Skip to content
Gujo Developers Sign in

Connect MCP

Let an agent call the tools of products you are entitled to. Give your client the server URL and sign in with your Gujo account.

View as Markdown

Endpoints and authentication

Server Endpoint Authentication
Customer MCP https://api.gujo.ai/api/mcp Sign in (OAuth). For CI and scripts, an account API key with the mcp.read ability
Design MCP https://design.gujo.ai/mcp Design agent token with the read role

Both servers take JSON-RPC 2.0 over HTTP POST. Always use api.gujo.ai and design.gujo.ai. Calls to gujo.ai/api/... lose the MCP headers, and tokens you get by signing in only work at the api.gujo.ai URL.

This page covers the customer MCP. The design MCP is described in Design Gallery.

Connect by signing in

Give your client just the server URL. You don't need to create a key or set an environment variable.

  1. Pick your client below and press the install button, or add the command or config.
  2. The first time the client calls the server, it opens your browser at the account.gujo.ai sign-in page. If you are already signed in, you go straight to the consent screen.
  3. On the consent screen, check the app's name, its address, the server it connects to and the permissions it gets, then approve.
  4. The client receives and keeps the token, and from then on refreshes it on its own when it expires.

The client finds where to sign in by itself, from the standard metadata the server publishes (/.well-known/oauth-protected-resource/api/mcp). It also registers itself as an app.

Permissions

Permissions on the consent screen have the same names as account API key abilities and are checked exactly the same way.

  • The default permissions are mcp.read (connect over MCP) and products.read (read your library and products). They are always included when you approve.
  • If the app asks for more, such as orders.read, subscriptions.read or device.install, those appear unchecked. Only the ones you check are granted.
  • The tool list shows only the tools the granted permissions allow. If the app calls a tool it lacks permission for, the server answers 403 and names the missing permission, and the app can ask for consent again with it.
  • Operator abilities cannot be requested.

Token lifetimes and disconnecting

  • An access token lasts one hour, and the client gets a new one with its refresh token. Both tokens change on every refresh.
  • A refresh token expires after 30 days without use. A connection ends 90 days after you approved it, and you sign in once more then.
  • Apps you connected by signing in are listed under Connected apps in your account security settings. You can see each app's name, permissions and last use, and Disconnect revokes all of that app's tokens.
  • An account can have up to 20 active connections. When it is full, disconnect the ones you no longer use.
  • Tokens you get by signing in work only for MCP. Calling other account API endpoints (such as /api/products) with them returns 401.

Connect with a key (CI, scripts)

Where nobody can sign in through a browser (CI, scripts on a server, headless agents), use an account API key. Expand Connect with a key under each client below for the config.

No config contains a key. They only point at an environment variable (GUJO_API_KEY, GUJO_DESIGN_TOKEN) or the client's password prompt. Create a key with the mcp.read ability as described in Account API keys, and put the value shown once at creation into a shell environment variable.

export GUJO_API_KEY="your key"

Connect a client

The endpoint is https://api.gujo.ai/api/mcp. Give your client just this URL: the first time it connects, it opens your browser so you can sign in to your Gujo account and approve its access.

Install in Cursor

The install button adds the server to Cursor. The first time it connects, Cursor opens your browser to sign in and approve access. Without the button, put the following in the config file.

File: ~/.cursor/mcp.json

{
    "mcpServers": {
        "gujo": {
            "url": "https://api.gujo.ai/api/mcp"
        }
    }
}
Connect with a key (CI, scripts)

Cursor reads the key from the environment variable GUJO_API_KEY, so start Cursor from a shell that has it. Put the following in the config file.

File: ~/.cursor/mcp.json

{
    "mcpServers": {
        "gujo": {
            "url": "https://api.gujo.ai/api/mcp",
            "headers": {
                "Authorization": "Bearer ${env:GUJO_API_KEY}"
            }
        }
    }
}
Install in VS Code

The install button adds the server to VS Code. The first time the server starts, VS Code opens your browser to sign in and approve access. To keep the setup in a repository, put the following in the config file.

File: .vscode/mcp.json

{
    "servers": {
        "gujo": {
            "type": "http",
            "url": "https://api.gujo.ai/api/mcp"
        }
    }
}
Connect with a key (CI, scripts)

VS Code asks for the key in a password prompt the first time it uses the server and stores it separately. Put the following in the config file.

File: .vscode/mcp.json

{
    "inputs": [
        {
            "type": "promptString",
            "id": "gujo-token",
            "password": true,
            "description": "Gujo account API key (mcp.read)"
        }
    ],
    "servers": {
        "gujo": {
            "type": "http",
            "url": "https://api.gujo.ai/api/mcp",
            "headers": {
                "Authorization": "Bearer ${input:gujo-token}"
            }
        }
    }
}

Add the server with the command below, then open /mcp in Claude Code, choose gujo and sign in. Once you approve in the browser, Claude Code keeps the token and refreshes it on its own. To share the setup with a project, put it in .mcp.json instead of running the command.

claude mcp add --transport http gujo https://api.gujo.ai/api/mcp

File: .mcp.json

{
    "mcpServers": {
        "gujo": {
            "type": "http",
            "url": "https://api.gujo.ai/api/mcp"
        }
    }
}
Connect with a key (CI, scripts)

Claude Code expands ${GUJO_API_KEY} in .mcp.json from the environment when it starts. claude mcp add --header does not expand environment variables and would leave the key itself in the config, so add the server with this file.

File: .mcp.json

{
    "mcpServers": {
        "gujo": {
            "type": "http",
            "url": "https://api.gujo.ai/api/mcp",
            "headers": {
                "Authorization": "Bearer ${GUJO_API_KEY}"
            }
        }
    }
}

Add the server with the command below and sign in through the browser with codex mcp login gujo. Once you approve, Codex keeps the token and refreshes it on its own.

codex mcp add gujo --url https://api.gujo.ai/api/mcp
codex mcp login gujo
Connect with a key (CI, scripts)

Codex reads the key from the environment variable GUJO_API_KEY named in bearer_token_env_var and sends it as an Authorization: Bearer header.

File: ~/.codex/config.toml

[mcp_servers.gujo]
url = "https://api.gujo.ai/api/mcp"
bearer_token_env_var = "GUJO_API_KEY"

In Claude.ai or Claude Desktop, go to Settings > Connectors > Add custom connector, enter only the URL below and connect. After you sign in to Gujo and approve in the browser, the connector receives a token. Do not enter a key.

https://api.gujo.ai/api/mcp
Connect with a key (CI, scripts)

In Settings > Connectors > Add custom connector, enter the URL below and add an Authorization request header with Bearer and your key. The key is then stored by Anthropic. Create a separate key for this connector only and revoke it as soon as you stop using it.

URL: https://api.gujo.ai/api/mcp
Authorization: Bearer <GUJO_API_KEY>

Windsurf (Devin Desktop) adds the server from a config that has only the URL, and opens your browser to sign in and approve access the first time it connects. Put the following in the config file.

File: ~/.codeium/windsurf/mcp_config.json

{
    "mcpServers": {
        "gujo": {
            "serverUrl": "https://api.gujo.ai/api/mcp"
        }
    }
}
Connect with a key (CI, scripts)

Windsurf (Devin Desktop) reads the key from the environment variable GUJO_API_KEY. Put the following in the config file.

File: ~/.codeium/windsurf/mcp_config.json

{
    "mcpServers": {
        "gujo": {
            "serverUrl": "https://api.gujo.ai/api/mcp",
            "headers": {
                "Authorization": "Bearer ${env:GUJO_API_KEY}"
            }
        }
    }
}
Your MCP keys

Keys are for CI and scripts that cannot sign in. Create one with the mcp.read ability in your account developer settings. The key is shown only once, when you create it.

Create a key with the MCP read ability

The endpoint is https://design.gujo.ai/mcp. Keep the key in the environment variable GUJO_DESIGN_TOKEN.

Install in Cursor

Cursor reads the key from the environment variable GUJO_DESIGN_TOKEN, so start Cursor from a shell that has it. Put the following in the config file.

File: ~/.cursor/mcp.json

{
    "mcpServers": {
        "gujo-design": {
            "url": "https://design.gujo.ai/mcp",
            "headers": {
                "Authorization": "Bearer ${env:GUJO_DESIGN_TOKEN}"
            }
        }
    }
}
Install in VS Code

VS Code asks for the key in a password prompt the first time it uses the server and stores it separately. Put the following in the config file.

File: .vscode/mcp.json

{
    "inputs": [
        {
            "type": "promptString",
            "id": "gujo-design-token",
            "password": true,
            "description": "Gujo design agent token"
        }
    ],
    "servers": {
        "gujo-design": {
            "type": "http",
            "url": "https://design.gujo.ai/mcp",
            "headers": {
                "Authorization": "Bearer ${input:gujo-design-token}"
            }
        }
    }
}

Claude Code expands ${GUJO_DESIGN_TOKEN} in .mcp.json from the environment when it starts. claude mcp add --header does not expand environment variables and would leave the key itself in the config, so add the server with this file.

File: .mcp.json

{
    "mcpServers": {
        "gujo-design": {
            "type": "http",
            "url": "https://design.gujo.ai/mcp",
            "headers": {
                "Authorization": "Bearer ${GUJO_DESIGN_TOKEN}"
            }
        }
    }
}

Codex reads the key from the environment variable GUJO_DESIGN_TOKEN named in bearer_token_env_var and sends it as an Authorization: Bearer header.

File: ~/.codex/config.toml

[mcp_servers.gujo-design]
url = "https://design.gujo.ai/mcp"
bearer_token_env_var = "GUJO_DESIGN_TOKEN"

Windsurf (Devin Desktop) reads the key from the environment variable GUJO_DESIGN_TOKEN. Put the following in the config file.

File: ~/.codeium/windsurf/mcp_config.json

{
    "mcpServers": {
        "gujo-design": {
            "serverUrl": "https://design.gujo.ai/mcp",
            "headers": {
                "Authorization": "Bearer ${env:GUJO_DESIGN_TOKEN}"
            }
        }
    }
}

Check the connection

  1. Ask the agent for its tool list. The tools the granted permissions (or the key's abilities) allow appear.
  2. If no sign-in window opens, check that the URL is https://api.gujo.ai/api/mcp. Start signing in again with /mcp in Claude Code or codex mcp login gujo in Codex.
  3. With a key, on 401 check the key, and on 403 missing_api_key_ability check that the key has mcp.read.
  4. With a key, if no tools appear, the client may not see the environment variable. Start the client again from a shell that has it.

Toolsets

Agents pick tools less accurately when they see all of them at once, so tools are grouped into toolsets. The first tools/list shows three meta tools and the tools of the library toolset.

Meta tool Input What it does
search_tools query?, toolset? Finds tools this key can call. Each result is {name, toolset, method, path, read_only, description}
enable_toolset toolset Turns a toolset on and adds its tools to the session's tool list. The result includes the input schemas of those tools
disable_toolset toolset Turns a toolset off

Turning a toolset on or off makes the server send notifications/tools/list_changed. If the client sent Accept: text/event-stream, the same response comes as SSE with that notification before the result. An unknown toolset name is an unknown_toolset tool error.

Toolset Tools
library (on from the start) library, products_content_assets_list
products products_list, products_show, products_detail, products_releases, products_updates
install products_install
license license_check, products_license, entitlements_pass_check
setup products_setup_progress_show, products_setup_progress_update
device bundles_list, device_entitlements, device_installs_create, device_usage_create
orders invoices_list, orders_list, orders_show, payment_methods_list
subscriptions subscriptions_list
client_config client_config

One tool is one account API endpoint. Tool names, required abilities and input fields match the tool column of the API reference. Read the detail and manual of a product you bought with products_detail.

  • The tool list only shows tools whose ability the key has. A key without orders.read, for example, sees no orders tools.
  • Entitlement and product-scoped key checks need the arguments, so they come back at call time as tool errors such as 403 product_entitlement_required.
  • The three write tools (products_setup_progress_update, device_installs_create, device_usage_create) run right away without approval.
  • Endpoints that revoke the calling key or return a new key in plain text, endpoints that take file uploads, and non-JSON responses (such as bundle files) are not tools.

Sessions

  1. Take the Mcp-Session-Id response header from initialize. The protocol version is 2025-11-25.
  2. Send the same Mcp-Session-Id on every later request. Each session remembers its enabled toolsets.
  3. Each use extends a session by 12 hours. An unknown session, or one created with another key, gets HTTP 404 with JSON-RPC -32600. Start again from initialize.

A request without the session header is treated as having only the library toolset on. Batch requests are rejected (400). Supported methods are initialize, ping, tools/list, tools/call and notifications (202 with an empty body).

Results and errors

  • Success: structuredContent = {status, body}, the HTTP status and JSON body you would get calling the endpoint over REST.
  • Failure: isError: true, structuredContent = {error, message, status?, body?, field?}. error is the endpoint's error code (such as product_entitlement_required), or invalid_input when an argument does not match the input fields (field names it).
  • Calling a tool name you cannot see is the JSON-RPC error -32602 Unknown tool. The old mcp_tool_{id} names now get this error too.
  • An unknown method is -32601.

Troubleshooting

Symptom Cause and fix
Every request starts a new session, or enabled toolsets disappear You are calling gujo.ai/api/mcp, which does not forward the Mcp-Session-Id header. Use https://api.gujo.ai/api/mcp
401 missing_api_key The client sends no Authorization header. If you connected by signing in, you have not signed in yet, so start signing in from the client (/mcp in Claude Code, codex mcp login gujo in Codex). With a key, check that the environment variable exists in the shell that started the client
401 invalid_api_key The token or key expired or was revoked. If you connected by signing in, sign in again from the client. With a key, create a new key
403 missing_api_key_ability The permission that work needs is missing. If you connected by signing in, check that permission when the app asks for consent again. With a key, check that it has mcp.read. Device sign-in keys (gujoctl) never have it, so create a separate key in Developer settings
404 with -32600 The session expired or belongs to another key. Run initialize again
-32602 Unknown tool This key cannot see that tool. Check the name with search_tools and add the ability the tool needs to the key
Tool result is 403 product_entitlement_required You have no entitlement to that product. Check the product ids you can use with library first