MCP Servers¶
Location: inception_mcp_servers/
Every MCP server follows the same 3-file pattern — keeping bootstrap, tool logic, and exposure control strictly separated.
server.py ← loads env, creates FastMCP, configures auth, starts transport
registry.py ← TOOL_REGISTRY: the only tools exposed to callers
tools.py ← implements all callable tool functions
Request flow: Client POST → server routes → tools.py executes → OCI API called → response returned.
Authentication modes¶
| Mode | File | Mechanism |
|---|---|---|
| Interactive OIDC | server_oidc.py |
Browser-based OCI IAM OIDC flow |
| Token / JWT bearer | server_token.py |
Authorization: Bearer <token> header |
1. SQLcl MCP (src/mcp_sqlcl)¶
Endpoint: http://127.0.0.1:3001/mcp/
Exposes Oracle Database via SQLcl. Each call spawns a per-request SQLcl stdio session — no shared global state.
Tools:
| Tool | Description |
|---|---|
execute_sql(query) |
Run SQL and return JSON results |
schema_information() |
Return table/column schema |
test_connection() |
Verify connectivity |
whoami() |
Return calling user identity |
Start:
Key env vars: SQLCL_PATH, SQLCL_CONNECTION, MCP_PORT=3001, IDCS_DOMAIN, IDCS_CLIENT_ID, IDCS_CLIENT_SECRET
Add/remove tools — edit registry.py:
TOOL_REGISTRY = {
"execute_sql": sqlcl_tools.execute_sql,
"schema_information": sqlcl_tools.schema_information,
}
2. Object Storage MCP (src/mcp_server_os)¶
Endpoint: http://127.0.0.1:3002/mcp/
Exposes OCI Object Storage. Uses TokenExchangeSigner — IDCS token → OCI IAM token per request.
Tools:
| Tool | Description |
|---|---|
get_os_namespace() |
Return tenancy namespace |
upload_object_file(bucket, name, path) |
Upload a local file |
list_objects(bucket) |
List bucket contents |
delete_object(bucket, name) |
Delete an object |
whoami() |
Return IAM identity |
Key env vars: MCP_HOST_MCP_OS, MCP_PORT_MCP_OS=3002, IDCS_DOMAIN, IDCS_CLIENT_ID, IDCS_CLIENT_SECRET
3. ADW MCP (src/mcp_adw)¶
Endpoint: http://127.0.0.1:8003/mcp/
Exposes Autonomous Data Warehouse with full end-to-end IAM token propagation. Unlike the SQLcl server (which uses a per-request subprocess), the ADW MCP connects directly through the Oracle Python driver with wallet-based mTLS.
Token flow:
Tools:
| Tool | Description |
|---|---|
query_adw(select_statement, bind_params=None) |
Execute a read-only SELECT against ADW and return row results |
execute_dml(statement, bind_params=None) |
Execute an INSERT/UPDATE against ADW under the same identity-propagated session as query_adw, return affected row count (added for united_health_pror_auth's prior-auth recipe — the first consumer needing per-user VPD-enforced writes, not just reads) |
whoami() |
Return the resolved IAM identity and enabled Oracle session roles for the current token |
Key env vars: IAM_DB_DNS_NAME, IAM_WALLET_DIRECTORY, IDCS_DOMAIN, IDCS_CLIENT_ID
Start:
4. OCI Database MCP (src/mcp_oci_control_plane_database)¶
Endpoint: http://127.0.0.1:8004/mcp/
Exposes OCI Database Cloud Service control-plane operations (list/administer database
resources, not query rows in a schema). Uses TokenExchangeSigner — same auth model as
Object Storage MCP, just handed to oci.database.DatabaseClient instead of
ObjectStorageClient. Sibling to Object Storage MCP's control-plane pattern, not to ADW
MCP's wallet-mTLS SQL pattern.
Tools:
| Tool | Description |
|---|---|
list_autonomous_db_versions(compartment_id, db_workload=None, limit=None) |
Lists Autonomous Database versions supported in a compartment. Read-only. |
whoami() |
Return the caller's identity claims from the verified bearer token |
get_token() |
Return the caller's own access token (debugging/bootstrap use) |
Start:
Key env vars: IAM_OCI_REGION, IAM_IDCS_CLIENT_ID, IAM_IDCS_CLIENT_SECRET,
TOKEN_FACTORY_* (see the module's sample.env)
Add/remove tools — edit registry.py:
TOOL_REGISTRY = {
"list_autonomous_db_versions": db_tools.list_autonomous_db_versions,
"whoami": db_tools.whoami,
"get_token": db_tools.get_token,
}
Full details, including the two-server (server.py / server_oidc.py) bootstrap flow and
a dependency-pin gotcha (mcp==1.22.0), are in
docs/mcp-servers/mcp-oci-control-plane-database.md.
Shared patterns¶
Per-request token validation¶
Every call validates the bearer token before executing any tool. There are no persistent authenticated sessions — if a token expires mid-session, the next call returns a 401 and the client must re-authenticate. This prevents stale sessions from retaining elevated access.
Explicit registry¶
Only tools listed in TOOL_REGISTRY are reachable. If a developer adds a new function to tools.py without registering it, it is never exposed — no accidental tool surface. This makes security audits straightforward: one registry file = complete capability inventory.
Stderr logging¶
MCP protocol uses stdout for JSON-framed tool responses. All server-side logs go to stderr to prevent protocol corruption. Route stderr to a log file:
Testing and diagnostics¶
# Kill a stuck server on port 3001
lsof -ti tcp:3001 | xargs kill -9
# Interactive MCP Inspector (requires OIDC auth flow in browser)
fastmcp dev --server-spec src/mcp_sqlcl/server_oidc.py:mcp
# Direct API test (token mode)
export MCP_ACCESS_TOKEN="<your-token>"
python src/mcp_sqlcl/test_mcp_sqlcl.py --url http://127.0.0.1:3001/mcp/ --limit 5