Skip to content

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:

.venv_mcp_servers/bin/python -m src.mcp_sqlcl.server_token

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:

MCP Client (SSO token) → IAM exchange → DB token → Oracle ADB (wallet mTLS) → audit trail

Tools:

Tool Description
query_adw(sql) Execute SQL against ADW and return row results
get_schema(table_name) Return column definitions for a table
test_connection() Verify ADW connectivity and wallet config
whoami() Return the resolved IAM identity for the current token

Key env vars: IAM_DB_DNS_NAME, IAM_WALLET_DIRECTORY, IDCS_DOMAIN, IDCS_CLIENT_ID

Start:

nohup python src/backend/mcp_adw_server.py > logs/mcp_server.log 2>&1 &

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:

python -m src.mcp_sqlcl.server_token 2>> logs/mcp_sqlcl.log

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