discovery, and the one rule that is stricter than the baseline
Building a client
A compliant MCP client needs no special-casing for init.Tasks. The server publishes the standard discovery documents, so you can find everything from the endpoint alone.
- RFC 9728 protected-resource metadata, on the MCP host at
https://mcp.inittasks.com/.well-known/oauth-protected-resource(also at…/oauth-protected-resource/mcp). An unauthenticated call to the endpoint answers401with aWWW-Authenticateheader that points there. - RFC 8414 authorization-server metadata, on the authorization server it names,
https://api.inittasks.com/.well-known/oauth-authorization-server. The MCP host serves no authorization endpoints of its own.
The first document names the authorization server:
curl -s https://mcp.inittasks.com/.well-known/oauth-protected-resource{
"resource": "https://mcp.inittasks.com/mcp",
"authorization_servers": ["https://api.inittasks.com/"],
"scopes_supported": ["tasks:read", "tasks:write"],
"bearer_methods_supported": ["header"],
"resource_name": "init.Tasks",
"resource_documentation": "https://inittasks.com"
}The second lists the endpoints: https://api.inittasks.com/oauth/authorize, /oauth/token, /oauth/register and /oauth/revoke.
Registration is open. Use RFC 7591 dynamic client registration and start immediately. There is no review and no waiting list. See authentication for the flow, which is the same one the REST API uses.
resource is mandatory
The server is stricter than the MCP baseline here, and only here. resource (RFC 8707) is required on both /oauth/authorize and /oauth/token.
Send the MCP endpoint as the resource:
resource=https://mcp.inittasks.com/mcpA token is minted for one audience and refused at the other. A token for the MCP server does not work against the REST API, and a token for the REST API does not work here. Omit resource and the request is refused rather than defaulted, because a token that works everywhere is the thing this rule exists to prevent.
Approval happens on the user's device
There is no password form in your window. The user sees a nine-digit code, opens init.Tasks on a device they already trust, and approves there.
They can grant less than you asked for. Read the granted scope from the token response, on every refresh too, rather than assuming. See scopes.
What to expect at runtime
- The tool list is the same one on the tools page, and it is generated from the running server.
- A connection only lists the tools its grant allows. On a read-only grant the write tools are not registered at all, so calling one answers a tool result with
isError: trueand the textMCP error -32602: Tool create_todo not found. Treat it as a permission prompt to the user, not as a bug: ask them to reconnect and switch on write. - A revoked grant (in the app, by API, replaced by a new connection of the same app, or after an encryption key change) answers HTTP
401with the JSON-RPC error-32001(Unauthorized: the session behind this token is no longer valid; reconnect) and aWWW-Authenticatechallenge, within a couple of seconds on a session that was already open. A refresh then answers400 invalid_grant. Send the user through approval again. - The
401challenge asks forscope="tasks:read tasks:write". The user still decides: the approval screen starts with read only. - Tools that read a date phrase or need "today" take an optional
tz(an IANA zone such asEurope/Amsterdam). Pass the user's zone; the default is UTC, and an unknown zone is refused. - Content is decrypted for each call.
searchworks, by decrypting and matching in memory; there is no index to query, so do not build a tool that assumes one. See encryption. - A session nobody uses for 30 minutes is closed, and one connection holds at most 16 open sessions (the least recently used one is closed first). A request on a closed session answers
404(unknown session); start a new session withinitialize, as the Streamable HTTP transport specifies. - Tool calls are rate limited per connection: 600 per 5 minutes, 120 of them for tools that change something. A refusal is HTTP
429withRetry-Afterand the JSON-RPC error-32029. See rate limits.
Next
- Authentication for the full OAuth flow.
- The tools for the surface your client will see.