Connect AI tools (MCP)
odnoga ships a built-in MCP server so Claude Desktop, Cursor, VS Code, Lovable, and any other MCP-aware client can read your prompts, routing rules, and usage — and make changes with your approval.
No API keys to copy. The user signs in through OAuth, picks a workspace, and approves a scope.
Where to find it
Workspace → Connect → Connect AI tools (MCP).
You'll see:
- The MCP server URL for this workspace.
- One-tab-per-client snippets (Claude, Cursor, VS Code, Other).
- A Connected apps list with last-used timestamps and per-app revoke.
How a user connects
- Open the AI tool (e.g. Claude Desktop).
- Settings → Connectors → Add custom connector.
- Paste the odnoga MCP URL.
- Browser opens → sign in to odnoga → pick workspace → approve scopes.
- Tool now has scoped access until you revoke it.
Scopes (what tools can do)
| Scope | Lets the tool… |
|---|---|
prompts:read | Read your prompt registry. |
prompts:write | Save new versions, change labels. |
routing:read | Read routing policy and cache settings. |
routing:write | Change routing policy, toggle cache. |
usage:read | Read spend, requests, recent logs. |
usage:read + budgets:read | Export one end user's data for a DSR (end_users.export). |
usage:write | Rename, tag and archive your functions. |
models:read | Read the catalogue and model lifecycle state. |
budgets:read | Read spend caps and workspace policy. |
budgets:write | Change spend caps, web-search policy, and model lifecycle behaviour. |
Every scope is opt-in on the consent screen. Write scopes are always opt-in.
Scoping usage to one caller
usage.summary, usage.timeseries, usage.by_model, usage.errors and
usage.recent_requests accept optional function_slug and app_slug filters.
They use the same caller attribution as the request log, so a filtered number
always matches the rows you can see there; unattributed covers traffic that
sent no caller metadata. Omit both to get the whole workspace. Every response
echoes the applied scope, and an unknown filter name is rejected with an
error rather than silently answered with whole-workspace numbers.
Surviving a model retirement without a deploy
Vendors retire models. The tools below are enough to detect it, decide, and act — without a code change and without opening the app:
| Ask | Tool |
|---|---|
| "What of mine is dying?" | models.audit — hand it the slugs your codebase names, get a verdict for each, plus which of your functions call them |
| "What has odnoga already told us?" | models.notices — the history, including every request it rejected or substituted |
| "What happens on the day?" | settings.model_lifecycle.get — the switch, and the retired/sunsetting models you are still calling |
| "Keep it alive while I fix the code" | settings.model_lifecycle.set with {"retired_model_fallback": true} |
| "Is my fallback chain sound?" | routing.check_chain — flags dead entries, vendors with no key, and co-sunset: a fallback that retires on the same day as its primary |
Two things worth knowing before you rely on the switch. It is organisation-wide — a retirement is a vendor event,
not a workspace one — and it requires organisation-admin rights. And it cannot rescue a model whose replacement is
itself retired or unnamed: settings.model_lifecycle.get reports replacement_live for exactly this reason, and a
false there means a code change is the only path.
Answering a data-subject request
end_users.export returns everything odnoga holds about one end user — the profile, whether contact details are on
file, and their request history — for an Article 15 or Article 20 request. Identify them by the id you send in
x-odnoga-end-user, or by email.
Erasure is deliberately not an MCP tool. It is irreversible and requires a fresh step-up authentication, so it
lives in the app under Workspace → Privacy. end_users.export says so when you reach for it. See
Data protection.
Knowing which spend is yours
functions.list returns your integrations and an attribution block saying how much of the window's spend has no
caller at all. This matters because unlabelled traffic produces no row in the list — the gap is invisible in exact
proportion to its size. Read the cost share rather than the request share; top_unattributed names the models and
endpoints the missing labels are arriving on. Fix it by sending X-Odnoga-App and X-Odnoga-Function
(see the headers reference); every endpoint reads them.
Revoking
- Per-app: Connect AI tools → Connected apps → Disconnect. Effective immediately.
- All apps at once: rotate the workspace virtual key the MCP server is bound to.
Security
- OAuth 2.1 with Dynamic Client Registration — no shared secret to leak.
- Verified clients (Claude, Cursor) get a verified badge in the Connected apps list.
- Every action a tool takes is recorded in Requests and Key audit with the client name + IP.
Use cases
- "Claude, save this prompt as
welcome-emailversion 2 and label it staging." - "Cursor, show me the last 10 failed requests for
gpt-4o-mini." - "Lovable, add
gpt-4-turboto the allowed-models list for staging." - "Claude,
gemini-2.5-flashjust started failing — check what odnoga says and keep it serving while I migrate."
The tool calls odnoga's MCP server, which goes through exactly the same authorised paths the dashboard does — same auth, same audit, same rules.