Appearance
Connecting an agent
Your CoCoCo instance exposes an MCP server. Point an AI agent at it and the agent can query your GraphQL API, read the platform's authoring guides, and build custom apps, workflows and integrations against your own data.
This page covers Claude Code, Claude Desktop, Claude.ai and Cursor.
What you need
Two things:
- Your instance URL, with
/mcpon the end. - An API token from your instance.
Your instance URL
The MCP endpoint is the domain you log into, plus /mcp. If you sign in at https://acme.cococo.app, your endpoint is https://acme.cococo.app/mcp.
There is no single shared address and no formula to derive one. Every deployment has its own domain, whether CoCoCo hosts it or you run it yourself. If you are not sure which domain is yours, it is the one in your browser's address bar when you are signed in.
The examples below all use https://example.cococo.app/mcp. Replace it with your own.
Creating a token
Go to /#/api-tokens in your instance and create a token.
A token carries your permissions. An agent using it can see and change exactly what you can, and nothing more. Treat it like a password: don't paste it into a shared document, and don't commit it to a repository.
Every example below reads the token from a COCOCO_MCP_TOKEN environment variable rather than hard-coding it, so that a config file stays safe to commit. Set it first:
bash
export COCOCO_MCP_TOKEN="your-token-here"Claude Code
One command:
bash
claude mcp add --transport http cococo https://example.cococo.app/mcp \
--header "Authorization: Bearer $COCOCO_MCP_TOKEN"Or, to share the server with everyone working in a repository, write it into .mcp.json at the project root:
json
{
"mcpServers": {
"cococo": {
"type": "http",
"url": "https://example.cococo.app/mcp",
"headers": {
"Authorization": "Bearer ${COCOCO_MCP_TOKEN}"
}
}
}
}Claude Code expands ${COCOCO_MCP_TOKEN} from the environment when it reads the file, so this file is safe to commit — each person supplies their own token. A project-scoped server is not used until each person approves it once: after adding the file, claude mcp list shows the server as Pending approval, and the next interactive claude session in that directory asks whether to enable it.
Three scopes are available, chosen with --scope:
| Scope | Who gets it | Stored in |
|---|---|---|
local (default) | Just you, in this project | ~/.claude.json |
project | Everyone working in this repository | .mcp.json |
user | Just you, in every project | ~/.claude.json |
Claude Desktop and Claude.ai
These share one connector system, so the steps are the same in both; the labels below are from Claude Desktop.
- Open Settings → Connectors, click Add, then Add custom connector. On a Team or Enterprise plan an owner does this from Organization settings → Connectors.
- Enter a name and your server URL.
- Under Authentication, choose No sign-in. The dialog pre-selects Sign in now, because your instance advertises an OAuth login; leave that selected and the next step is refused with "Authorization is reserved when sign-in is enabled". Leave the OAuth client section empty.
- Under Request headers, pick
authorizationfrom the header-name list (it is offered only once sign-in is off) and enterBearer YOUR_TOKENas the value. Leave Required ticked. - Under Advanced, leave the transport on Streamable HTTP.
- Click Add, then Connect.
Three things catch people out here:
- Include
Bearerand the space. The header value is sent exactly as you type it — nothing is added for you. The connector saves either way, but withabc123alone it never connects; the server answers 401. - Request header authentication is in beta, and is not enabled for every organization. If your dialog has no Request headers section, your organization doesn't have access yet.
- Authentication settings are frozen once a connector is added. An existing connector offers only Disconnect and Remove; to change or rotate a token you must remove it and add it again.
Cursor
Write .cursor/mcp.json in a project, or ~/.cursor/mcp.json to make the server available everywhere:
json
{
"mcpServers": {
"cococo": {
"url": "https://example.cococo.app/mcp",
"headers": {
"Authorization": "Bearer ${env:COCOCO_MCP_TOKEN}"
}
}
}
}${env:COCOCO_MCP_TOKEN} is read from the environment, so this file is also safe to commit.
Clients that only support OAuth
Some clients register a remote MCP server only through OAuth discovery and cannot send a fixed header — sandboxed agent runtimes are the usual example. Your instance does publish OAuth discovery metadata, but its authorization server does not yet accept client registrations from MCP clients, so these clients cannot sign in directly. Until it does, use the token route through a small local proxy that speaks stdio to the client and HTTP to your instance.
mcp-remote is one such proxy (a third-party package, not part of CoCoCo). It forwards any header you give it:
json
{
"mcpServers": {
"cococo": {
"command": "npx",
"args": [
"mcp-remote",
"https://example.cococo.app/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer YOUR_TOKEN"
}
}
}
}Write Authorization:${AUTH_HEADER} without spaces and keep the space inside the environment variable: some clients split args at spaces. mcp-remote can also read headers from a file (--header-file), which keeps the token out of the process list.
The proxy runs where the client runs. If the client itself sits in a sandbox, the proxy either runs inside it — then the token must be available there — or on the host, outside the sandbox's control.
Checking it works
In Claude Code:
bash
claude mcp listA working server reports cococo: https://example.cococo.app/mcp (HTTP) - ✔ Connected.
In any client, ask the agent to run this query. It needs no permissions and answers pong, which confirms the connection is live:
graphql
query { ping }Troubleshooting
| Symptom | Cause |
|---|---|
| Connection refused, or the server is not found | Check the domain, and that the path ends in /mcp. |
| 401, or the client connects then drops immediately | The token is missing the Bearer prefix, or it has been revoked. |
| Your client offers only OAuth sign-in and no header field | See Clients that only support OAuth. |
| Authorization is reserved when sign-in is enabled | Authentication is still on Sign in now. Switch to No sign-in before adding the header. |
| No Request headers section in the connector dialog | Header authentication is in beta and not enabled for your organization. |
| You changed the token but it still fails | Authentication settings are frozen after a connector is created. Remove the connector and add it again. |
| The agent connects but sees no data | Tokens carry their owner's permissions. Check what that account can see in the UI. |
What the agent can do
Once connected, an agent can read the API domains to find its way around the schema, follow the authoring guides for custom apps, workflows, Lua scripting and integrations, and use Magic Query for a simpler URI-style way to read your data.