67 docs indexed
Front MCP (Model Context Protocol) servers behind obleth's identity layer, verify them end-to-end, and let the gateway run their tools for a model.
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.
Deleting a server also strips it from the tool_servers grant of every model
that had it, so no model is left pointing at a server that no longer exists. The
affected model names are recorded on the audit entry.
The gateway is transport-transparent, so a bad upstream URL or a rejected
credential only shows up when something actually calls the server. Two paths
verify a registration end-to-end, both driving the real MCP handshake
(initialize → notifications/initialized → tools/list) through the gateway
at /mcp/{name}:
test_mcp tool sweeps every registered server (or
a named subset) and returns one pass/fail row per server with its tool list.
See Charo.A name that is not registered comes back as a failure; a server that is registered but disabled is skipped rather than probed. Probes authenticate as the reserved internal identity, which is flagged synthetic, so verification traffic stays out of usage and cost statistics.
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 |