The connector
Connect an assistant
Everything is self-service: nobody at Orkasa registers the broker's app.
Add the connector
In Claude: Settings → Connectors → Add custom connector, and paste
https://orkasa.app/api/mcp. In other clients, the same URL wherever they
ask for an MCP server address.
Authorize in Orkasa
Orkasa opens, you sign in and approve the permissions. Each one can be unchecked.
Done
The assistant now sees the tools that match the granted permissions, and no others.
What happens underneath
1. The client POSTs /api/mcp → 401 + WWW-Authenticate:
resource_metadata="…"
2. GET /.well-known/oauth-protected-resource (RFC 9728)
→ authorization_servers: [orkasa.app]
3. GET /.well-known/oauth-authorization-server (RFC 8414)
→ authorize / token / register
4. POST /api/oauth/register (RFC 7591) → client_id [+ secret]
5. GET /oauth/authorize → the broker signs in and approves
6. POST /api/oauth/token → access + refresh
7. POST /api/mcp (Bearer ork_at_…) → tools/list, tools/call
Steps 2 to 4 are what makes this self-service. Without them, an OAuth client would have to be created by hand for every broker — which is to say, there would be no connector.
Open registration is safe
POST /api/oauth/register is not authenticated. It cannot be: the client
announcing itself has no identity with us yet.
A registration grants nothing. It creates an app identity with no brokerage,
no token and no data behind it. Every byte it may one day read is decided
afterwards, by a signed-in human, on /oauth/authorize, inside their own
tenant. The abuse surface is rows in a table, not access — and the limits are
cut to that measure:
- 10 registrations per hour per IP;
redirect_urisoverhttps, except loopback (RFC 8252 §7.3: a desktop app receives its code onhttp://127.0.0.1:<port>);- permissions capped to the connector's ceiling, whatever the client asks for;
- dynamically registered implies mandatory PKCE, as for any public client.
The name is chosen by a stranger
The authorization screen says "X wants to connect", and that name was chosen by whoever registered. So the screen shows the real destination, not the URL the app declares:
Name chosen by the application itself, unverified. Your data is going to evil.example. Authorize only if you recognize that destination and you started this connection.
Showing the declared client_uri as proof of provenance turned the warning
against us: registering with client_uri: "https://orkasa.app" was enough to
make the screen display "· orkasa.app" under an invented name. The
redirect_uri, by contrast, is checked character by character against the
client's whitelist — it is the one thing on that screen a phisher cannot dress
up.
And it can be withdrawn
The Conexiones card in Orkasa's settings lists the assistants with live access, who authorized it and when, with a Disconnect button. Without it, an authorization given by mistake was good for sixty days — the life of the refresh token.
Desktop clients
A desktop assistant has nowhere to hide a secret. It registers with
token_endpoint_auth_method: "none", gets a client_id alone, and what
protects the exchange is PKCE — S256 and nothing else.
A code_challenge with no method is rejected: OAuth's historical default is
plain, which compares the verifier to the challenge in the clear, and that
challenge already travelled inside the authorization URL (so through browser
history and logs). The metadata only advertises S256, and the server no longer
does anything else.
The token endpoint decides the rule from the registration, never from what the request carries: a confidential client cannot pass itself off as public by omitting its secret.