The Operator MCP puts your Leed workspace behind a Model Context Protocol endpoint, so any spec-compliant client can read your content, create and edit drafts, query analytics and pull form submissions on your behalf. Setting it up is one URL and a browser sign-in. Everything else — registering the client, exchanging codes, storing and refreshing the token — the client does for you, because the protocol requires it to.
The endpoint
https://app.leed.ai/mcpThat is the only value you configure anywhere.
| Setting | Value | Notes |
|---|---|---|
| Server URL | https://app.leed.ai/mcp | The whole configuration |
| Transport | Streamable HTTP (http) | POST only. Other methods answer 405 once authenticated — there is no SSE stream to open and no session to delete |
| Client ID | leave empty | The client registers itself dynamically at connect time |
| Client secret | leave empty | There is no pre-shared secret. Clients are public and use PKCE |
resource indicator | automatic | Sent by any compliant client. If yours does not send it, every call fails |
One request per POST: Leed does not accept batched JSON-RPC arrays. Every client that matters already sends one message per request, so this only surfaces if you are hand-rolling a caller.
The connection acts as you
What happens when you connect
You paste a URL and click Allow. Underneath, five things happen in a fixed order, and knowing them is the difference between fixing a stuck connection in a minute and guessing at it for an hour.
- Your client POSTs to
/mcpwith no token and gets a401carrying aWWW-Authenticateheader that points at Leed’s protected-resource metadata. That challenge is the discovery trigger; nothing else about the endpoint is disclosed first. - The client walks discovery —
/.well-known/oauth-protected-resourceto learn which authorization server issues tokens for this resource, then/.well-known/oauth-authorization-serveron that issuer to learn where to register, authorize and exchange. - The client registers itself through Dynamic Client Registration. This is why there is no secret to paste: the client mints its own identity on the spot.
- Your browser opens for an OAuth 2.1 authorization-code flow with PKCE. You sign in to Leed if you are not already signed in.
- You land on the consent screen, approve, and the browser hands a code back to your client, which exchanges it for a token bound specifically to
https://app.leed.ai/mcp. The nextPOST /mcpsucceeds.
sequenceDiagram
autonumber
participant C as Your MCP client
participant M as app.leed.ai/mcp
participant D as Discovery documents
participant A as Leed authorization server
participant U as You, in a browser
C->>M: POST /mcp (no token)
M-->>C: 401 + WWW-Authenticate: resource_metadata=…
C->>D: GET /.well-known/oauth-protected-resource
D-->>C: this resource, issued by app.leed.ai
C->>D: GET /.well-known/oauth-authorization-server
D-->>C: authorize / token / register endpoints
C->>A: POST /oauth2/register (Dynamic Client Registration)
A-->>C: client_id (no secret)
C->>U: open /oauth2/authorize with PKCE challenge (S256)
U->>A: sign in to Leed
A->>U: consent screen — pick a workspace, review, Allow
U-->>C: redirect back with the authorization code
C->>A: POST /oauth2/token (code + verifier + resource=…/mcp)
A-->>C: audience-bound access token
C->>M: POST /mcp with the token
M-->>C: tools/list, and every call thereafter
The consent screen
This is the only screen you interact with, and it is worth reading rather than clicking through.
It shows you:
- The client’s friendly name, fetched from its registration — Claude, Cursor — with its logo. Leed never displays the raw
client_idas a name, so if this reads An application the client registered without one. - Who you are signing in as, by email, and which role the connection will act with: “Acts with your Administrator permissions — it can only do what your role allows.”
- The workspace the connection will be bound to — as a picker if you belong to more than one, as a single line if you do not.
- An “It can” list and an “It cannot” list.
- “This connection will stay authorized for up to 180 days, or until you revoke it.”
Picking a workspace
If you belong to more than one workspace, a Workspace to authorize picker appears. It is fed by Leed’s own workspace listing, and each entry is tagged for eligibility with the same predicate the endpoint itself enforces — so the picker can never hand you a workspace that would then be refused at /mcp. An entry that is not eligible is rendered disabled and labeled — upgrade required.
When a workspace is refused
If no workspace you belong to is eligible, the screen says “None of your workspaces are on a plan that supports connecting AI tools. Ask a workspace admin to upgrade.” and the Allow button never appears.
That copy is now misleading, and it is worth knowing why: every plan is eligible, Free included. Reaching this state means a workspace’s entitlement record is unset or unrecognizable, not that it is on the wrong plan. Upgrading will not fix it — contact support instead.
The list on the consent screen is a summary
The “It can” list is four bullets: pages and content, forms and responses, analytics, and menus. The “It cannot” list is three: publish or delete content, access billing, manage users or permissions.
The second list is exactly right and is the important one. The first is an understatement written before the surface grew — a connected client also reaches contacts and accounts, personas, campaigns and deliverables, distributions, labels, journey stages, paths, user profile fields, autolinks, shortcodes and pending settings changes. Treat what the Operator MCP can and cannot do as the contract, not those four bullets.
Client setup
Every flow below ends the same way: your browser opens on the Leed sign-in and the consent screen above. None of them needs a client id, a client secret, an API key or an environment variable — if a field asks for one, leave it empty.
- Claude
- Claude Code
- ChatGPT
- Cursor
claude.ai and Claude Desktop are the same setup. Leed’s MCP is a remote HTTP server with OAuth, so both use the identical Connectors flow — there is no desktop-specific config file to edit.
- Open Settings → Connectors.
- Choose Add custom connector.
- Give it a name —
Leed— and enter the URLhttps://app.leed.ai/mcp. - Add, then Connect. Your browser opens Leed’s sign-in and consent screen.
Leave the OAuth client ID and secret fields empty. Claude registers itself with Leed automatically and sends the resource indicator without being asked.
Add the server from your terminal:
claude mcp add --transport http leed https://app.leed.ai/mcpThen, inside Claude Code, run /mcp, select leed, and authenticate — your browser opens Leed’s sign-in and consent screen. Nothing is stored in your project and no environment variable is needed.
To connect a second workspace, add it under a different name:
claude mcp add --transport http leed-acme https://app.leed.ai/mcpAdd Leed as a custom connector:
- Open Settings → Connectors.
- Choose to add a custom connector.
- Name it
Leedand enter the URLhttps://app.leed.ai/mcp. - Connect, and complete the Leed sign-in and consent screen in the browser window that opens.
Leave any client id and client secret fields empty.
Add the server to your MCP configuration — ~/.cursor/mcp.json for every project, or .cursor/mcp.json inside one:
{
"mcpServers": {
"leed": {
"url": "https://app.leed.ai/mcp"
}
}
}A url key is the entire entry. Do not add headers, an Authorization value or an API key — a hand-added header will not be an audience-bound token and every call will fail.
Then open Cursor Settings → MCP and click the login prompt beside the leed server to run the sign-in and consent flow.
Verifying the connection
Ask for something that can only come from your workspace:
“List my page types, then show me the five most recently edited pages.”
If the tools appear in your client and come back with your own content, you are connected. Asking your client to describe what it can do is also a fair test — the surface includes a capability-description tool, so a well-behaved client can enumerate itself.
Once you are working, the Operator MCP tool index is the fastest route from a tool name to its parameters, and authoring pages over MCP is worth reading before your first attempt at writing a page body, because that one has a workflow of its own.
One requirement your client must meet
This is a requirement the MCP authorization spec already places on clients, and the Claude-family clients satisfy it automatically — so in practice you meet it by using a current, spec-compliant client. If you hit the symptom above, re-authorize with a client that sends the indicator; the token will not repair itself. MCP troubleshooting starts here, and covers the rest of the failure modes.
The check exists to close the confused-deputy case the spec’s audience rule is written for: a token legitimately issued for some other Leed resource is still not a token for /mcp, and Leed will not accept it as one.
Local development
Running the backend locally? The endpoint follows the origin you reach it on:
http://localhost:8787/mcpEverything above works unchanged against it — discovery, registration, PKCE and consent all resolve against localhost:8787, and the token is bound to that origin rather than to app.leed.ai.
The Vite dev server on :5173 will not work as an MCP endpoint. It is a different origin, so it carries no authorization-server session cookie and the discovery documents are not served there. Use the backend’s own port.
This is a different mechanism from the Leed CLI’s sign-in, which uses a device-code flow rather than a browser redirect — CLI authentication covers that separately, and the two do not share credentials.