64 docs indexed
obleth can front MCP (Model Context Protocol) servers with the same identity
obleth can front MCP (Model Context Protocol) servers with the same identity
layer it applies to LLM traffic. Clients authenticate once with an obleth API key
and reach any registered MCP server through a single endpoint —
/mcp/{server} — while obleth injects the upstream credential and records access.
This keeps obleth lean: as a reverse proxy it is transport-transparent — it does not parse JSON-RPC, so any MCP-over-HTTP server (streamable-HTTP or SSE) works unchanged.
obleth uses registered MCP servers in two ways:
/mcp/{server} and run tool calls themselves (this guide, below).From the dashboard (MCP Servers → Register) or the Management API:
curl -X POST "${OBLETH_ADMIN_BASE_URL}/api/v1/mcp-servers" \
-H "Authorization: Bearer $OBLETH_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "github",
"upstream_url": "https://mcp.githubcopilot.com/mcp",
"auth_header": "Bearer ghp_…"
}'
name — the path segment clients use: /mcp/github.upstream_url — the MCP server's base URL.auth_header — optional full Authorization header value obleth injects toward
the upstream (stored encrypted-at-rest in production). Clients never see it.Other endpoints: GET /api/v1/mcp-servers, GET/PUT/DELETE /api/v1/mcp-servers/{id}. All writes are audited and synced to every gateway
pod via Redis.
Clients point their MCP client at obleth using their obleth API key:
POST https://{obleth-host}/mcp/github
Authorization: Bearer sk_...
Content-Type: application/json
{ "jsonrpc": "2.0", "method": "tools/list", "id": 1 }
obleth:
auth_header,Sub-paths are supported: /mcp/{server}/{rest} forwards {rest} (and the query
string) to the upstream.
Beyond proxying, obleth can run an MCP server's tools on a model's behalf. A client sends a plain OpenAI chat request and gets back a grounded final answer — it never sees tool definitions or tool calls. obleth discovers the granted servers' tools, injects them into the request, executes the model's tool calls against the MCP upstream, appends the results, and re-asks the model, looping (bounded) until the model answers.
client ──▶ obleth (plain chat request, no tools)
│ model is granted MCP servers + native function calling
│ inject discovered tools, add the nudge
├──▶ model "I should search…" → tool_calls
│ execute tool calls against the MCP server(s)
├──▶ MCP server tools/call → result
│ append results, re-ask
├──▶ model (loops up to max_turns)
│◀── final answer
client ◀─────┘ grounded answer (no tool_calls)
To turn it on:
tool_servers on the model.
The model must have native supports_function_calling — the loop is skipped
(with a logged warning) for models without it.tool_loop_enabled: true on
PUT /api/v1/settings/boons.curl -X PUT http://localhost:9180/api/v1/models/$MODEL_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "tool_servers": ["searxng"] }'
Key behaviors:
tools keep control of them: the granted MCP
tools are merged into the client's set, the gateway executes only its own
tools, and any client-owned tool call is handed straight back to the client.max_turns forces
a final answer so a plain chat client never receives unexpected tool_calls.tool_loop usage record.The full configuration reference (turn limits, timeout, the tool nudge) lives in
Model Boons → The gateway tool loop.
For an end-to-end live web-search example, see examples/searxng/.
Per-call counts are exported as Prometheus metrics (server names are low-cardinality):
obleth_mcp_requests_total{server, status="2xx|4xx|5xx"}Registry changes (create/update/delete) appear in the audit log. With OTLP
tracing enabled, each call produces an mcp_request span tagged with the server
name.
| Status | Meaning |
|---|---|
401 | missing/invalid obleth API key |
403 | key disabled, or the MCP server is disabled |
404 | no MCP server registered under that name |
502 | the upstream MCP server failed |