---
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. A client that follows the MCP specification for a remote server with OAuth needs nothing else.

## 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", scope="asset:read asset:write brand:read brand:write campaign_plan:read campaign_plan:write mutation:write observe:read skill:read skill:write"
    ```

2. **Read the protected resource metadata**

    `https://mcp.adcrunch.dev/.well-known/oauth-protected-resource` (RFC 9728) gives the resource, `https://mcp.adcrunch.dev/mcp`, and one authorization server, `https://auth.adcrunch.dev`.

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. **Register the client**

    The server accepts dynamic client registration (RFC 7591) with no initial token. A registered client is a public client: the token endpoint takes no client secret.

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 has no organization picker: [Auth & scopes](/mcp/auth#which-organization-your-client-acts-for) states which organization the token acts for.

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:

| Status | `WWW-Authenticate` `error` | Cause | Do this |
| --- | --- | --- | --- |
| `401` | `invalid_token`, or none | No token, or a token that does not verify, for example an expired token. | 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 70 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.
