An MCP client loads every tool definition from every server it connects to, into every turn. Ten servers with twenty tools each is a few hundred tool definitions in the context window before the conversation starts.
The gateway inverts that. You register your remote MCP endpoints on mcpi.app; your client connects to one server — this one — and sees two tools:
find_tools(request, k?)— describe what you want in words. A ranking model scores every tool in your catalog and returns the few that fit, with their input schemas.call_tool(name, arguments)— run one of them. The upstream's result comes back verbatim.
Set it up
- Add your endpoints. Dashboard → Gateway → name, URL, and optionally a
header. Each endpoint must be a public
https://URL. - Point a client at the gateway. It is this site's own MCP server, so any client that can already reach it works:
claude mcp add --transport http mcpi https://mcpi.app/mcpAuthenticate with an API key from Settings (Authorization: Bearer oat_…
or X-API-Key), or let the client run OAuth against this site.
3. Test each endpoint. The Test button on an endpoint dials it, reports
how many tools it advertises, and says whether its contract moved since the
last time the gateway saw it.
Authenticating to an upstream
Three cases, and an endpoint uses exactly one of them:
- No auth — leave the header fields empty.
- A static header — paste the name (
Authorization,X-API-Key, …) and the value. The value is encrypted with AES-256-GCM before it is stored, never returned to the browser, and never written to a log. - OAuth — for the servers that want a real sign-in. See below.
An endpoint that already carries a pasted header refuses OAuth sign-in; remove the header first.
Signing in with OAuth
When an endpoint answers 401, its row shows needs sign-in. Select
Sign in and the browser goes to the upstream's own authorization page. After
you approve, it returns to the Gateway page and the row shows signed in.
What happens behind that button:
- Discovery starts from the
WWW-Authenticatechallenge the upstream sent, which names its protected-resource metadata (RFC 9728). A server that publishes no metadata is refused rather than probed at guessed paths. - The gateway registers itself as an OAuth client (RFC 7591), or uses its
client metadata document at
/gateway/oauth/client.jsonwhen the server supports that instead. If you supplied credentials of your own (below), those are used and nothing is registered. - Authorization uses PKCE
S256; a server that does not advertise S256 is refused. The issuer that answers is checked against the one discovery found. - The callback lands on
/gateway/oauth/callback—/callbackalso works, for servers that only accept short redirect paths — and exchanges the code.
The sign-in in progress is bound to your account and to the browser that started it, is good for ten minutes, and can be used once. A callback that arrives in a different browser, twice, or late does nothing.
What is stored
Encrypted with AES-256-GCM under the server's ENCRYPTION_KEY: the access
token, the refresh token, and the registered client's id and secret. None of it
is ever sent to the browser or written to a log — the endpoint list only reports
that you are signed in, and which issuer granted it.
Tokens refresh on their own. If the upstream rejects a token that has not expired yet — a revoked grant looks exactly like this — the gateway refreshes once and retries; a second rejection flips the endpoint back to needs sign-in.
Bring your own OAuth client
Some servers do not offer dynamic registration; they hand you a client id (and
sometimes a secret) from a console. Put them in Advanced on the add form and
sign-in presents them instead of registering anything. Register
https://mcpi.app/gateway/oauth/callback as the redirect URI — /callback is
accepted too.
The secret is encrypted like every other credential here and never comes back to
the browser; the endpoint list only reports that a client id is set. How the
secret is presented at the token endpoint follows what the server advertises in
token_endpoint_auth_methods_supported: HTTP Basic (client_secret_basic) by
default, client_secret_post when the server advertises post and not basic.
Signing out
Sign out deletes the stored grant and keeps the endpoint, so you can sign in
again later. The delete happens first and always. If the server published a
revocation_endpoint, the gateway then tells it the grant is finished
(RFC 7009) — your refresh token if there is one, otherwise the access token.
That call is a courtesy: a server that is down, slow, or refuses cannot stop you
signing out here, and the failure is only logged.
Contract changes come with the answer
Every connect snapshots each endpoint's contract and classifies what moved
against the last one — the same engine the inspector and the directory use.
When find_tools returns a tool from an endpoint whose contract changed, the
result carries a contract_changes note with the breaking / compatible /
cosmetic counts. Your client finds out that a tool's arguments changed before
it calls it, rather than from a failed call.
What it costs
| Free | With a subscription | |
|---|---|---|
find_tools |
100 per day | Unlimited |
call_tool |
Unlimited | Unlimited |
| Endpoints | 20 | 20 |
Only find_tools is metered: it is the call that runs the ranking model.
Proxying a call you already found costs nothing extra. Over the free limit,
find_tools returns a tool error saying so — your client sees a readable
message, not a failure.
The Gateway page shows what routing has actually done: find_tools and
call_tool counts, the model input tokens they used, your most-called tools,
and an estimate of the context kept out of your client — the tool definitions
in your catalog that find_tools did not return, summed over every call.
Limits
- Endpoints must be public HTTPS. Private, loopback, link-local and cloud-metadata addresses are refused when you save an endpoint, and every connection resolves the name through a connector that refuses any answer outside public address space — so a name that changes where it points later does not get a second chance.
- Remote (Streamable HTTP) servers only. A local stdio server has no URL this
site can reach; run
mcpi serveon your own machine for those. - OAuth covers the authorization-code flow with dynamic registration, a client metadata document, or credentials you supply. Incremental scope upgrades are not implemented, and a grant is only revoked upstream if the server publishes a revocation endpoint.
- Two endpoints of yours may not share a name. When two endpoints expose a tool with the same name, the gateway prefixes both with the endpoint name.