v2.32.0

Oracle Discovery API

Point Claude — or any function-calling LLM — at a running Oracle and let it use C3's cross-project code & memory intelligence as tools. Discover projects, search code and memory across all of them, traverse the memory graph, and surface insights, without ever opening the chat UI.

v2.32.0 External LLM tools MCP + OpenAPI Read & safe-actions Bearer + loopback

Overview

The Oracle normally runs the LLM relationship inwards: its own model (Ollama) calls C3 tools to analyze your projects. The Discovery API flips that — it exposes those same capabilities outwards, so an external LLM can use the Oracle as a discovery tool over your whole C3 estate.

Two transports, one tool core. The exact same tool registry is served over both MCP (streamable HTTP/SSE — native for Claude Code / Claude Desktop) and an OpenAPI REST surface (for any function-calling LLM). They run on separate loopback ports because Flask is WSGI and the MCP transport is ASGI, but they dispatch through one definition of each tool — so the two surfaces can never drift apart.

What you get

SurfaceWhereUse it for
MCP server http://127.0.0.1:3332/mcp Native tool discovery for Claude Code / Desktop and any MCP client
REST + OpenAPI http://127.0.0.1:3331/api/discovery Function-calling for any LLM (GPT, Gemini, custom agents)
c3 oracle api CLI Terminal Get the token + a ready-to-paste .mcp.json snippet; rotate / clear the key

Safe by construction. Only read and safe-action tools are exposed — there are no code-editing tools on this surface. Both servers bind 127.0.0.1 (loopback) by default and require a Bearer token.


Quick start

Start the Oracle, grab your token, and connect a client.

1

Start the Oracle

python oracle/oracle_server.py \
  --no-browser

Prints the REST + MCP URLs and ensures an API key exists. The MCP server starts in a background thread.

2

Get the token

c3 oracle api info

Prints the Bearer token, both URLs, and a ready-to-paste Claude .mcp.json entry. Use c3 oracle api key for just the token. You can also generate, rotate, and copy the token visually in the Oracle dashboard under Settings → Discovery API.

3

Connect

# Claude → paste the snippet
# Any LLM → fetch openapi.json

See the two sections below for the MCP config and the OpenAPI flow.


Connect Claude (MCP)

Add the entry from c3 oracle api info to your .mcp.json (project root) or Claude Desktop config:

{
  "mcpServers": {
    "c3-oracle": {
      "type": "http",
      "url": "http://127.0.0.1:3332/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}

Claude lists the c3-oracle tools (list_projects, c3_search_cross, query_memory, read_graph, …). Ask it to "discover what C3 projects exist and search them for X".


Connect any LLM (OpenAPI REST)

Every tool is also a plain REST operation. Point a function-calling LLM at the spec, then call tools with the Bearer header.

# Discover the tools (OpenAPI 3.1)
curl -H "Authorization: Bearer <token>" \
     http://127.0.0.1:3331/api/discovery/openapi.json

# Invoke a tool by name
curl -X POST \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{"tool":"list_projects","args":{}}' \
     http://127.0.0.1:3331/api/discovery/call

# Or use the per-tool path (body = the tool's args)
curl -X POST \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{"query":"rate limiter","top_k":5}' \
     http://127.0.0.1:3331/api/discovery/tools/c3_search_cross

REST endpoints

All under /api/discovery; every request requires Authorization: Bearer <token>.

EndpointDescription
GET /tools Available tools, each with a JSON Schema and capability tier
POST /call Invoke any tool: body {"tool": name, "args": {…}}
POST /tools/<name> Invoke a named tool with the request body as its arguments object
POST /call/stream Same as /call but streams start → result|error → [DONE] as SSE
GET /openapi.json OpenAPI 3.1 document — one operation per tool
GET /mcp-info MCP URL + auth scheme for the streamable-HTTP transport

Tools & capability tiers

The exposed set is capped by api_max_tier in ~/.c3/oracle/config.json (read or action). Code-editing tools are never registered.

Read tier — discovery

ToolDoes
list_projects All registered C3 projects with paths + fact counts
search_facts Search memory facts across ALL projects
query_memory Search/list facts within one project
project_health Memory health check for a project
analyze_project LLM-powered analysis of a project's memory themes
cross_insights Cross-project insights
read_graph Memory-graph statistics for a project
c3_search / c3_search_crossCode-intelligence search (one project / all projects)
c3_read Read exact file content (symbols / line ranges)
c3_compress Token-efficient structural file map
c3_validate Syntax/type validation on a file
c3_status Project health / budget / sessions overview
c3_memory_query Read-only memory query (recall/list/score/graph/trends)
c3_edits / c3_edits_crossQuery the edit ledger (one / all projects)
activity_reportCross-project daily digest: sessions, tool calls, edits, git mutations, token/cost (optional LLM narration)

Action tier — safe writes (no code edits)

ToolDoes
suggest_actionCreate a pending memory suggestion a human approves (not a direct write)
delegate_task Run a configured Oracle agent and return its result

Authentication & security

A single Bearer token guards both transports. The REST surface checks it in a Flask before_request hook; the MCP transport checks it in a pure-ASGI middleware (so streaming responses pass through intact).

Where the token lives

OS keyring Token text, under service c3-oracle-api. Backed by Windows Credential Manager, macOS Keychain, or Linux Secret Service.
C3_ORACLE_API_KEY Environment override for headless / CI / containers where no keyring backend exists. When set, it wins and is never persisted to the keyring.

Exposing on a network. The default bind is 127.0.0.1. To let a remote LLM service reach the Oracle, set bind_host to 0.0.0.0 in ~/.c3/oracle/config.json — and put it behind TLS + a firewall yourself. The token alone is not a substitute for transport security.

Rotate or revoke at any time with c3 oracle api rotate / c3 oracle api clear.


CLI commands

CommandDescription
c3 oracle api info Print REST + MCP URLs, the token, and a ready-to-paste .mcp.json snippet
c3 oracle api key Print just the token (generating one if needed)
c3 oracle api rotate Replace the token with a fresh one
c3 oracle api clear Delete the stored token from the keyring

~/.c3/oracle/config.json keys

bind_host Interface to bind. Default 127.0.0.1. Use 0.0.0.0 to expose on a network (add TLS/firewall).
allowed_hosts Extra hostnames/IPs the Host + Origin guard accepts. Needed when bind_host is non-loopback so legitimate browsers/clients aren't blocked (v2.33.0).
api_enabled Serve the /api/discovery/* REST surface. Default true.
api_require_auth Require the Bearer token. Default true.
api_max_tier Cap exposed tools: read (discovery only) or action (adds suggest_action, delegate_task). Default action.
mcp_enabled Start the MCP HTTP/SSE server. Default true.
mcp_port MCP transport port. Default 3332.

Troubleshooting

SymptomCause & fix
401 unauthorized Missing or wrong token. Get the current one with c3 oracle api key and send it as Authorization: Bearer <token>.
Claude doesn't list the tools Confirm the Oracle is running and mcp_enabled is true; check the URL is http://127.0.0.1:3332/mcp and the Authorization header is present in .mcp.json.
Tool not found in the catalog It may be above your api_max_tier (e.g. suggest_action needs action), or it is a code-editing tool — those are never exposed.
Need a token without a keyring Set C3_ORACLE_API_KEY in the environment (CI / containers). It overrides the keyring and is not persisted.
The 'keyring' package is required pip install keyring — a C3 dependency that may be missing if you upgraded without re-installing.

Full endpoint and schema details live in oracle-guide/api-reference.md and oracle-guide/discovery-api.md.