Skip to content

MCP Servers

Location: inception_mcp_servers/

The MCP (Model Context Protocol) servers are the tool execution layer of Project Inception. They expose enterprise backend operations — database queries, file storage, data warehousing — as structured, authenticated tools that AI agents can call via the MCP protocol over HTTP.


Available Servers

Server Module Endpoint Backend
SQLcl mcp_sqlcl/ http://127.0.0.1:3001/mcp/ Oracle Database via SQLcl
Object Storage mcp_os/ http://127.0.0.1:3002/mcp/ OCI Object Storage
ADW mcp_adw/ http://127.0.0.1:8003/mcp/ Oracle Autonomous Data Warehouse

Platform Architecture

MCP servers sit in the Tool Layer between the agent orchestration tier and OCI backend services.

┌─────────────────────────────────────────────────┐
│              AI Agent / LLM Client              │
│         (Claude, OCI GenAI, LangChain)          │
└─────────────────────┬───────────────────────────┘
                      │  MCP over HTTP
┌─────────────────────────────────────────────────┐
│               MCP Tool Layer                    │
│  ┌──────────────┐ ┌──────────────┐ ┌─────────┐ │
│  │  mcp_sqlcl   │ │   mcp_os     │ │ mcp_adw │ │
│  │  port 3001   │ │  port 3002   │ │  port   │ │
│  │              │ │              │ │  8003   │ │
│  └──────┬───────┘ └──────┬───────┘ └────┬────┘ │
└─────────┼────────────────┼──────────────┼──────┘
          │                │              │
          ▼                ▼              ▼
   Oracle DB         OCI Object      Oracle ADW
   via SQLcl          Storage       (wallet mTLS)

Consistent 3-File Structure

Every MCP server follows the same module layout:

<server_module>/
├── src/
│   ├── server_oidc.py   ← bootstrap: interactive OIDC auth
│   ├── server_token.py  ← bootstrap: non-interactive bearer token auth
│   ├── registry.py      ← TOOL_REGISTRY: the only tools exposed to callers
│   ├── tools.py         ← all tool function implementations
│   └── common/
│       └── settings.py  ← .env loading and config exports
├── tests/               ← test clients for both auth modes
└── .env                 ← environment configuration
File Role
server_oidc.py / server_token.py Bootstrap only — load env, configure auth, create FastMCP, run transport
registry.py Single source of truth for exposed tools; adding to tools.py alone does nothing
tools.py All tool logic — never imports FastMCP, never creates a server
common/settings.py Loads .env via python-dotenv; exports all settings as module-level variables

Authentication Architecture

All three servers use OCI IAM (IDCS) for authentication. Two deployment modes are available for each server:

Mode 1 — Interactive OIDC (server_oidc.py)

Uses fastmcp.server.auth.providers.oci.OCIProvider. FastMCP handles the full OAuth 2.0 Authorization Code flow — the client opens a browser, the user logs in to OCI IAM, and a token is issued.

Client (auth="oauth")
  → FastMCP OAuth discovery endpoints
  → Browser redirect to OCI IAM login
  → Authorization code returned
  → FastMCP exchanges code for access token
  → Token validated; tool calls authorized

Use when: Bootstrapping a new token, interactive testing, MCP Inspector.

Mode 2 — Bearer Token (server_token.py)

Uses a custom OCITokenAuthMiddleware + JWTVerifier. The caller must supply a valid IDCS JWT in the Authorization: Bearer <token> header on every request, including the MCP initialize handshake.

Client (Authorization: Bearer <token>)
  → OCITokenAuthMiddleware intercepts request
  → JWTVerifier validates signature via IDCS JWKS endpoint
  → Claims (sub, aud, iss) verified
  → Tool call dispatched

Use when: Non-interactive clients, agents, CI/CD pipelines, production.

Important

Do not connect an OAuth-only client (auth="oauth") to server_token.py. The middleware validates a bearer token on the MCP initialize handshake itself — before OAuth can complete. Always connect OAuth clients to server_oidc.py.


Token Bootstrap Flow

First-time setup to obtain an MCP_ACCESS_TOKEN:

Step 1 → Start server_oidc.py
Step 2 → Run tests/get_token.py
Step 3 → Browser opens: OCI IAM login
Step 4 → Login completes → get_token tool returns access token
Step 5 → Token written to .env as MCP_ACCESS_TOKEN
Step 6 → Stop server_oidc.py
Step 7 → Start server_token.py (uses MCP_ACCESS_TOKEN for validation)

Shared Design Patterns

Explicit tool registry

Only tools listed in TOOL_REGISTRY are reachable by callers. A function in tools.py that is not registered is never exposed — no accidental surface area. Security audits are simple: one registry file = the complete capability inventory.

# registry.py
TOOL_REGISTRY = {
    "execute_sql": sqlcl_tools.execute_sql,
    "schema_information": sqlcl_tools.schema_information,
}
# anything not listed here cannot be called

Per-request token validation

There are no persistent authenticated sessions. Every MCP request is independently validated. If a token expires mid-session, the next call receives a 401 and the client must re-authenticate. This prevents stale sessions from retaining elevated access.

Stderr-only logging

The MCP protocol uses stdout for JSON-framed tool responses. All server-side diagnostic output goes to stderr to prevent protocol corruption. Redirect stderr to a log file for persistent logging:

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

Health check endpoint

Every server registers a /health route returning 200 OK. Use it for load balancer health checks and uptime monitoring.


IDCS Domain Configuration

IDCS_DOMAIN format

IDCS_DOMAIN must be set to the bare hostname only — no https:// prefix, no :443 port suffix.

# Correct
IDCS_DOMAIN=idcs-10ca4bf910534e0290c18c358e3226b2.identity.oraclecloud.com

# Wrong — will produce a malformed URL
IDCS_DOMAIN="https://idcs-10ca4bf910534e0290c18c358e3226b2.identity.oraclecloud.com:443"

Both auth_middleware.py and token_verifier.py prepend https:// and append :443 where needed — the env var should only contain the domain.


Diagnostics

# Kill a server on a stuck port
lsof -ti tcp:3001 | xargs kill -9
lsof -ti tcp:3002 | xargs kill -9
lsof -ti tcp:8003 | xargs kill -9

# Check health endpoints
curl http://127.0.0.1:3001/health
curl http://127.0.0.1:3002/health
curl http://127.0.0.1:8003/health

# MCP Inspector (requires server_oidc.py running)
fastmcp dev --server-spec src/server_oidc.py:mcp