# Your own client

> Connect any MCP client to Nodaro over Streamable HTTP, discover the OAuth server, register the client or a developer app, and sign in with PKCE.

Source: https://nodaro.ai/docs/mcp/connect/custom-client

**Your own client** can connect to Nodaro if it speaks standard MCP over Streamable HTTP and signs in with OAuth. Point it at `https://mcp.nodaro.ai/mcp`, let it discover the OAuth server, register it, and send the user through the consent screen. This page lists the endpoints, the registration rules and the token lifetime.

## What your client needs

- **MCP over Streamable HTTP** at `https://mcp.nodaro.ai/mcp`.
- **OAuth 2.0 authorization code flow with PKCE.** Only the `S256` code challenge method is accepted.
- **OAuth discovery** through the protected resource metadata (RFC 9728) and the authorization server metadata (RFC 8414).
- **A client registration**, either through Dynamic Client Registration (RFC 7591) or as a developer app you register once.

## Endpoints

| What | Where |
| --- | --- |
| MCP endpoint | `https://mcp.nodaro.ai/mcp` |
| Protected resource metadata | `https://mcp.nodaro.ai/.well-known/oauth-protected-resource` |
| Authorization server metadata | `https://app.nodaro.ai/.well-known/oauth-authorization-server` |
| Dynamic Client Registration | `POST https://app.nodaro.ai/v1/oauth/register` |
| Token exchange | `POST https://app.nodaro.ai/v1/oauth/token` |
| Token revocation | `POST https://app.nodaro.ai/v1/oauth/revoke` |

Both metadata documents are served on both hosts, `app.nodaro.ai` and `mcp.nodaro.ai`. Each one is also served with a `/mcp` suffix, for example `/.well-known/oauth-protected-resource/mcp`, because some clients probe that form first. The authorization server metadata advertises the authorization, token, registration and revocation endpoints, the `code` response type, the `authorization_code` grant, `S256` PKCE, `client_secret_post` authentication and the supported scopes.

## The connection flow

### Discover the authorization server

Read the protected resource metadata from the MCP host. It binds the resource `https://mcp.nodaro.ai/mcp` to its authorization server, `https://app.nodaro.ai`. Then read the authorization server metadata for the endpoints.

### Register the client

Send your `client_name` and redirect URIs to the registration endpoint. Nodaro answers with a `client_id` that starts with `ndr_dcr_` and a `client_secret`. The endpoint accepts 10 requests per minute from one IP address.

### Send the user to the consent screen

Open the authorization endpoint in the browser with your `client_id`, `redirect_uri`, `response_type=code`, the `scope` list, a random `state`, and the PKCE `code_challenge` with `code_challenge_method=S256`. The user signs in, reviews the permissions and clicks **Allow**.

### Exchange the code

Nodaro redirects to your `redirect_uri` with a `code` and your `state`. Check the `state`, then exchange the code at the token endpoint with your `code_verifier`. A code works once and expires 10 minutes after it is issued.

### Call the MCP endpoint

Send the access token, which starts with `ndr_app_`, as `Authorization: Bearer <token>` on every request to `https://mcp.nodaro.ai/mcp`. List the tools with `tools/list`.

## Which client names can register

By default, Dynamic Client Registration accepts only known client names: Claude, Claude Code, Cursor, Cline, Continue, Goose, ChatGPT, OpenAI, Lovable, Gemini, Gemini CLI, Codex, MCP Inspector and mcp-inspector. A client with another name receives `403 client_not_allowed`.

If your client has another name, register it once as a developer app instead:

1. Open [app.nodaro.ai/settings/developer-apps](https://app.nodaro.ai/settings/developer-apps) and click **New developer app**.
2. Enter the name, the redirect URIs and the scopes the client may request.
3. Copy the `client_id` and the `client_secret`. The secret is shown only once. It does not expire, and you can rotate it on the app's page.

Each account can register up to 5 developer apps by hand. Clients that registered themselves appear in the same list but do not count toward that limit.

On your own Nodaro instance, the operator controls registration with `MCP_DYNAMIC_REGISTRATION` (`allowlist`, the default, `open` or `off`) and `MCP_DCR_ALLOWLIST`. In `open` mode, one client name and redirect URI pair can hold at most 5 unused registrations in 24 hours; more return `429 too_many_open_registrations`. In `off` mode, registration returns `403 dcr_disabled`. See [MCP on a self-hosted install](https://nodaro.ai/docs/self-hosting/mcp).

## Tokens

- **Lifetime.** An access token lasts 90 days. There are no refresh tokens: when a call returns `401`, send the user through the consent screen again.
- **Revocation.** Your client can revoke a token at the revocation endpoint, which always answers `200`. The user can also revoke the app at [app.nodaro.ai/settings/developer-apps](https://app.nodaro.ai/settings/developer-apps).
- **The consent screen.** Because a dynamically registered client chose its own name, the consent screen warns the user that Nodaro did not verify it.

The same OAuth server serves the REST API. [OAuth for developers](https://nodaro.ai/docs/developers/oauth) covers it in full.

## Handle tool results

- **Jobs.** Generation tools start a job and return its id at once. Poll `get_job` every 5 to 10 seconds, or call `wait_for_job`, until the job is `completed` or `failed`. See [Job tools](https://nodaro.ai/docs/mcp/tools/jobs).
- **Structured content.** Many tools return their data as `structuredContent` next to the text reply, for example the job envelope of `get_job`. Read the structured data in code.
- **Cards are optional.** Hosts that display MCP Apps get interactive cards, such as job progress and upload pickers. A client without them reads the same results as text and structured data.
- **Tasks.** A client that supports the MCP `tasks` API receives job progress through it.
- **Missing tools.** A tool whose scope the user did not grant is left out of `tools/list`. Check the granted scopes before you look for a missing tool.

## Common mistakes

- **Using `https://app.nodaro.ai/mcp`.** That address is a web page. A `POST` to it returns `405` with the error code `wrong_mcp_host`, which names the correct URL.
- **Using `https://api.nodaro.ai/mcp`.** That domain does not exist.
- **Adding a trailing slash.** Use `https://mcp.nodaro.ai/mcp` exactly.

## Reference

- [Model Context Protocol specification](https://modelcontextprotocol.io/specification)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)

## Frequently asked questions

### Which transport does the Nodaro MCP server use?

Streamable HTTP, at https://mcp.nodaro.ai/mcp. Sign-in is OAuth 2.0 with PKCE, and a client can register itself with Dynamic Client Registration.

### Why does registration fail with client_not_allowed?

Dynamic registration accepts only known client names, and your client's name is not on the list. Register a developer app in your Nodaro settings instead, and use its client id and secret.

### How long does an access token from the Nodaro MCP server last?

90 days. There are no refresh tokens, so after 90 days the user signs in again. Tokens can be revoked earlier from the Nodaro settings.

### Can I test the Nodaro MCP server with MCP Inspector?

Yes. MCP Inspector is one of the client names that can register dynamically, so it can connect, sign in and list the tools.
