Skip to content

Connect an agent

At the end of this guide, an MCP client can search and file the catalog through /mcp. You need a running xixo that is connected to masks, and an account in the masks tenant it signs in with.

An MCP client registers itself with masks the first time it connects. The masks tenant has to allow that.

  1. Open the masks tenant’s settings.
  2. Under Dynamic registration, choose On, or On, limited to these scopes.
  3. If you limit it, list openid, profile, email, offline_access, and every scope in the table below. A client asks for every scope xixo offers, and masks refuses the whole request with invalid_scope when one of them is beyond the limit.

MASKS_DYNAMIC_REGISTRATION on the masks deployment overrides the tenant’s choice. See registering a client in the masks docs.

  1. Add the server. Use your xixo address followed by /mcp:

    Terminal window
    claude mcp add --transport http xixo http://xixo.localhost:8180/mcp
  2. Start claude and run /mcp. Choose xixo, then authenticate.

  3. The browser opens masks. Sign in, and approve the scopes the client asks for.

  4. Back in Claude Code, /mcp lists xixo as connected, with its tools.

Any MCP client that speaks OAuth and registers itself dynamically can connect. Give it the /mcp URL, such as https://xixo.example.com/mcp. The address without /mcp answers 404, and the resource the metadata names is the /mcp URL, which a client checks against the address it was given.

In Claude, open Settings → Connectors, choose Add custom connector, and enter a name and the /mcp URL. Claude sends you to masks to sign in and approve, and then lists the xixo tools under the connector, where you choose which ones it may call without asking.

You do not configure any of this. It is listed so you can follow it in a log.

  1. The client calls /mcp without a token. xixo answers 401 with a WWW-Authenticate header that names /.well-known/oauth-protected-resource.
  2. The client reads that document. It lists the /mcp URL as the resource, the masks issuer as the authorization server, and every xixo: scope an MCP tool checks, with its description.
  3. The client registers with masks and sends you there to sign in and approve.
  4. The client calls /mcp again with the token masks issued.

See agents and MCP for how the endpoint is built.

The tools a client sees depend on the scopes its token holds. A tool the token does not reach is left out of tools/list.

Scope What it unlocks
xixo:catalog:read search, and feed to read a feed
xixo:catalog:write connect, and feed to note, rename, analyze, create, place, or change a lifetime
xixo:resources:read resource, to list resources and ask them read-only commands
xixo:resources:command resource commands that act: check, sync, keep, export, cancel, put, and snapshot
xixo:web:read resource searches on a web search resource
xixo:web:keep resource snapshot on a web resource, without xixo:resources:command
xixo:mcp:call the tools of every MCP server attached as a resource

xixo offers each of these scopes, and a client asks for all of them. A masks limit narrower than this table refuses every such client, so limit a client in the client instead, such as Claude’s per-tool permissions. The full list is in the scopes reference, and each tool’s arguments are in the MCP reference.

Ask the agent to search the catalog for a word you know is in it. It calls search and returns feeds with their ids. Then ask it to list resources, which calls resource with no key.

The masks log shows each step the client took.

What you see Why
The client never opens masks The masks metadata at /.well-known/oauth-authorization-server has no registration_endpoint, so dynamic registration is off.
masks redirects back with invalid_scope and this client may not request The tenant’s limit leaves out a scope xixo offers. Add the scopes it names.
The client gets 404 The address is missing /mcp.
  • The client never opens masks. Dynamic registration is off in the masks tenant.
  • 401 after signing in. xixo refused the token, for example because masks issued it for a different tenant. xixo records each refusal with its reason on the Activity page in Settings.
  • 503 from /mcp or /.well-known/oauth-protected-resource. masks is not answering, or MASKS_ISSUER_TEMPLATE is not set. The response body says which.
  • A tool is missing. The token does not hold the scope for it. Authenticate again and approve the scope.
  • 429 too many requests. The token made more than XIXO_MCP_LIMIT calls in a minute, 120 by default. See the environment reference.