# 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](https://www.rfc-editor.org/rfc/rfc9728) protected-resource metadata, at `/.well-known/oauth-protected-resource`.
- [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414) authorization-server metadata, at `/.well-known/oauth-authorization-server`.

```bash
curl -s https://mcp.inittasks.com/.well-known/oauth-protected-resource
```

Registration is open. Use [RFC 7591](https://www.rfc-editor.org/rfc/rfc7591) dynamic client registration and start immediately. There is no review and no waiting list. See [authentication](/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](https://www.rfc-editor.org/rfc/rfc8707)) is required on both `/authorize` and `/token`.

Send the MCP endpoint as the resource:

```text
resource=https://mcp.inittasks.com/mcp
```

A 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 rather than assuming. See [scopes](/scopes).

## What to expect at runtime

- The tool list is the same one on [the tools page](/mcp), and it is generated from the running server.
- A write tool on a read-only grant returns [forbidden_scope](/errors/forbidden_scope). Handle it as a permission prompt to the user, not as a bug.
- A revoked grant returns [grant_revoked](/errors/grant_revoked). Refreshing will not help. Send the user through approval again.
- Content is decrypted per request. There is no server-side search, so do not build a tool that assumes one. See [encryption](/encryption).

## Next

- [Authentication](/authentication) for the full OAuth flow.
- [Running it locally](/mcp/local) to develop against stdio first.
