Connect in one step.
Omniio speaks Streamable HTTP MCP at a single URL. Add it to your client, authorize once, and every server you turn on is reachable through it.
Quickstart
Claude Code takes the endpoint from the CLI. Everything else — the Claude desktop app, Cursor, Windsurf, custom clients — takes the same URL in an mcpServers block.
claude mcp add --transport http omniio https://mcp.omniio.dev{ "mcpServers": { "omniio": { "type": "http", "url": "https://mcp.omniio.dev" } }}The first call triggers an OAuth authorization in your browser. After that, your client holds a token for https://mcp.omniio.dev and no further setup is needed. To check the endpoint from a terminal:
curl -i -X POST https://mcp.omniio.dev \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'An unauthorized probe answers 401 with a WWW-Authenticate header pointing at the discovery document — that response means the endpoint is healthy, not misconfigured.
The three tools
Your agent does not see every tool from every server. It sees three, and uses them to reach the rest. That keeps the context window for your work instead of spending it on schemas.
search_tools
BM25-ranked search across the cached catalog of your enabled servers. Takes a natural-language query and an optional limit (8 by default, 25 at most). Returns qualified names with one-line summaries.
{ "name": "search_tools", "arguments": { "query": "create a pull request", "limit": 5 }}describe_tool
Takes the qualified name and returns that tool's description and full JSON input schema — so the agent reads argument shapes only for the tool it actually picked.
{ "name": "describe_tool", "arguments": { "name": "github__create_pull_request" }}run_tool
Invokes the upstream tool with your credentials attached and returns its result unchanged. The qualified name goes in name; the upstream's own arguments go in arguments.
{ "name": "run_tool", "arguments": { "name": "github__create_pull_request", "arguments": { "owner": "acme", "repo": "web", "title": "Fix login" } }}Tool names
Tools are namespaced by server slug so two servers can both expose a search without colliding. The separator is __:
<server-slug>__<tool-name>github__create_pull_requestexa__web_searchThe registry in your dashboard lists every qualified name your endpoint currently answers, with its schema and its recent runs.
Authorization
There are two layers, and they are separate on purpose.
Your client to Omniio
OAuth 2.1 with dynamic client registration. Omniio is the authorization server at https://omniio.dev and the protected resource at https://mcp.omniio.dev; tokens are audience-bound to that resource.
Omniio to each upstream
Servers that need an API token take one from you in the library; it is sealed with AES-256-GCM before it is stored and only opened to make a call. Servers that speak OAuth send you through their own consent screen, and the resulting grant is held per user and refreshed on demand. Revoking a server in the library deletes its credential.
Limits & billing
Each call to search_tools, describe_tool or run_tool counts once against your monthly allowance. Free includes 10,000 and refuses calls beyond that until the counter resets on the 1st, UTC; paid plans keep serving and bill the overage.
When the limit is reached, the endpoint answers the call with an error that names the plan, the count and the reset date, so the agent can report it rather than failing silently.
Audit trail
Every run_tool invocation is recorded with its arguments, its result, whether it succeeded, and how long the upstream took. Entries are kept for 7 days and then pruned; the activity log can export what it shows as JSON before then.
Discovery calls are counted for billing but not stored as audit entries — the log is a record of what your agent did, not what it looked at.