---
title: Another client
description: Connect a client that you build, or a client with no page here — the endpoint, the transport, the protocol versions, OAuth discovery, and the discovery documents.
---

This page is for a developer. It gives what a client needs to connect to the AdCrunch MCP server with no guide. The client must identify itself with a Client ID metadata document, which the MCP specification adds in version `2025-11-25`. A client that knows only dynamic client registration, as in the older versions, cannot connect.

## The endpoint

|  |  |
| --- | --- |
| Endpoint | `https://mcp.adcrunch.dev/mcp` |
| Transport | Streamable HTTP |
| Protocol versions | `2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`, `2024-10-07` |
| Capabilities | `tools`, `prompts` |
| Authorization | OAuth 2.1, with PKCE (`S256`) |

The server sets no `instructions` on `initialize`. The text of each tool is in `tools/list`.

## Authorization

The endpoint accepts one credential: a bearer token that AdCrunch issued for this endpoint. An API key of the REST API does not work here.

1. **Call the endpoint with no token**

    The server answers `401`. Its `WWW-Authenticate` header names the protected resource metadata and each scope of the server:

    ```http
    WWW-Authenticate: Bearer resource_metadata="https://mcp.adcrunch.dev/.well-known/oauth-protected-resource/mcp", scope="asset:read asset:write brand:read brand:write campaign_plan:read campaign_plan:write mutation:write observe:read skill:read skill:write web:read"
    ```

2. **Read the protected resource metadata**

    `https://mcp.adcrunch.dev/.well-known/oauth-protected-resource/mcp` (RFC 9728) gives the resource, `https://mcp.adcrunch.dev/mcp`, and one authorization server, `https://auth.adcrunch.dev`. The path follows RFC 9728: the well-known suffix goes between the host and the path of the resource. `https://mcp.adcrunch.dev/.well-known/oauth-protected-resource` gives the same document.

3. **Read the authorization server metadata**

    `https://auth.adcrunch.dev/.well-known/oauth-authorization-server` (RFC 8414) gives each endpoint. Read the endpoints from this document. Do not write them into your client, because their host is not the host of the issuer.

4. **Identify the client**

    The server identifies a client by its Client ID metadata document, and the authorization server metadata says `client_id_metadata_document_supported: true`. Publish a JSON document at an HTTPS URL, and use that URL as your `client_id`. The document holds `client_id` (the same URL), `client_name`, `redirect_uris`, and `token_endpoint_auth_method`: `none`, or `private_key_jwt` with a `jwks_uri`. The URL must answer `200` with a JSON content type, with no redirect, in 5 KB or less. The server refuses a URL on `adcrunch.dev`. Claude and ChatGPT publish such a document. MCP Inspector uses one when you start it with `--client-metadata-url`.

    The server does not accept dynamic client registration: `/oauth2/register` answers `403`. The title of the consent screen names the host of your `client_id`, and the screen shows the host of the redirect URI that receives the access. The screen shows your `logo_uri` only when it is on the origin of your `client_id`.

    **Changed on 2026-10-07.** Before this date, the server accepted dynamic client registration (RFC 7591), and it gave each registered client a public client id.

5. **Authorize**

    Send the person to the authorization endpoint with a PKCE challenge (`S256`). Ask for the service scopes that your client needs, and for `offline_access` to get a refresh token. The person signs in to AdCrunch and approves the access. The consent screen shows the organization that the token acts for, and a person in two or more organizations chooses one there: [Auth & scopes](/mcp/auth#which-organization-your-client-acts-for) gives the rules.

6. **Call the endpoint with the token**

    Send `Authorization: Bearer <token>` on each request. The token lives about one hour. Use the refresh token to get a new one.

The authorization response carries the `iss` parameter (RFC 9207), and its value is `https://auth.adcrunch.dev`.

### When the endpoint refuses the token

These failures happen before any tool runs, so they are HTTP answers and not tool results.

Each answer carries a JSON body, `{ "error": "<code>", "error_description": "<sentence>" }`, and a `WWW-Authenticate` header that names the protected resource metadata. A `401` header also names each scope of the server. A `403` header carries `error="insufficient_scope"` and the scopes that the token lacks.

| Status | `error` in the body | Cause | Do this |
| --- | --- | --- | --- |
| `401` | `invalid_request` | No token. | Authorize. |
| `401` | `invalid_token` | A token that does not verify: for example an expired token, or a token for another resource. | Refresh the token, or authorize again. |
| `401` | `invalid_token` | The token carries no organization or no user. | Create an organization in AdCrunch, then authorize again. |
| `403` | `insufficient_scope` | The token holds no AdCrunch service scope: a token from before AdCrunch had scopes, or a token for OpenID Connect scopes only. | Authorize again. |

The endpoint accepts a token that holds a service scope, but not the scope of one tool. The call of that tool then fails with the code `forbidden`. [Errors](/mcp/errors) gives the shape.

## Tools and prompts

`tools/list` gives the same tools to each token of one organization. The scopes of the token do not change the list. They decide which tools can run. The providers of the organization change one part of it: the live lists (`meta_list_*`, `tiktok_list_*` and `gads_list_*`, but not `meta_list_pages` and `meta_list_pixels`) show only for a provider that the organization has connected. With Meta, TikTok and Google Ads connected, the list has 72 tools. A provider connected during a session shows at the next `tools/list`. AdCrunch sends no `notifications/tools/list_changed`, so a client that keeps the list shows the new tools when it lists again.

Each tool carries these keys in its `_meta`:

| Key | Value |
| --- | --- |
| `dev.adcrunch/errors` | Each failure code that the tool can send. |
| `dev.adcrunch/scope` | The one service scope that the tool needs. |
| `dev.adcrunch/providers` | The providers that the tool works with, when a provider decides whether it works. A tool that works the same way for each provider has no such key. |

The page of each tool shows the same facts, from the same list. A failed tool call carries a code in `structuredContent`, as [Errors](/mcp/errors) states.

A successful tool call carries its result in `structuredContent`, in the shape of the output schema of the tool. The first text block holds the same result as JSON. So a client that reads only text gets the same result. Other blocks can follow it, such as a note for the agent or an image.

**Changed on 2026-09-26.** Before this date, the text of a success had no one rule. Some tools sent the JSON of `structuredContent`. Some sent the record with no wrapper, for example the generic entity get of that date sent the entity and not `{"entity":…}`. Some sent a sentence, for example `brand_delete`. `structuredContent` did not change.

`prompts/list` gives one prompt for each Skill and for each brand of the organization. It depends on the scopes: a Skill needs `skill:read`, and a brand needs `brand:read`. [Prompts](/mcp/prompts) describes them.

## Discovery

An agent that looks for the server before it connects can find it.

### The MCP Server Card

AdCrunch publishes an [MCP Server Card](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127) at three addresses, with the same content:

- `https://adcrunch.dev/.well-known/mcp/server-card.json`
- `https://mcp.adcrunch.dev/.well-known/mcp/server-card.json`
- `https://mcp.adcrunch.dev/mcp/server-card`, the path that the proposal reserves under the endpoint.

The card names the endpoint and the protocol versions above. It lists no tools and no prompts. A connection lists them. No token is necessary to read the card.

### The ARD manifest

An agent that starts from the domain alone reads `https://adcrunch.dev/.well-known/ard.json` first. This [ARD manifest](https://agenticresourcediscovery.org/) lists what AdCrunch offers an agent: this MCP server and the REST API. For each one, it gives the document that describes it and some example questions that it can answer.

The same document is at `https://adcrunch.dev/.well-known/ai-catalog.json`, the path that older crawlers read. The `robots.txt` of `adcrunch.dev` names that path.

### The API Catalog

The REST API has an index of its own: an [RFC 9727](https://www.rfc-editor.org/rfc/rfc9727) linkset at `https://adcrunch.dev/.well-known/api-catalog`, and at the same path on the API origin. It names each published API and its OpenAPI document. The [API reference](/api/introduction) describes the REST API.
