From dddc6b4d15bd960147c3b2e9684cb7d748954fea Mon Sep 17 00:00:00 2001 From: Niek Candaele <22315101+niekcandaele@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:29:48 +0200 Subject: [PATCH 1/3] docs(advanced): add connect your AI assistant page (GH #3623) Documents the Takaro MCP endpoint for operators: the endpoint URL and its discovery document, the URL-only setup for Claude Code, Claude.ai and ChatGPT, the pre-registered fallback clients for Cursor and VS Code, what the assistant can and cannot do, domain selection, the destructive-call brake, the response budget, and troubleshooting. Ships alongside gettakaro/takaro#3623 (epic gettakaro/takaro#3616), which extends the maintainer-side manual OAuth checklist in that repo. Claude-Session: https://claude.ai/code/session_01LRsE6g3Copo9nYfxCuP5Z6 --- docs/advanced/connect-your-ai-assistant.md | 146 +++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 docs/advanced/connect-your-ai-assistant.md diff --git a/docs/advanced/connect-your-ai-assistant.md b/docs/advanced/connect-your-ai-assistant.md new file mode 100644 index 0000000..496be56 --- /dev/null +++ b/docs/advanced/connect-your-ai-assistant.md @@ -0,0 +1,146 @@ +--- +sidebar_position: 8 +--- + +# Connect your AI assistant + +Takaro exposes an **MCP endpoint**: a single URL that an AI assistant — Claude Code, Claude.ai, ChatGPT, Cursor — can connect to and then use to work with your game servers, players, modules and roles on your behalf. + +The assistant acts **as you**. It signs in with your own Takaro account through the normal login page, and every call it makes carries exactly the roles and permissions you already have. It cannot see or do anything you could not do yourself in the dashboard, and every change it makes shows up in your event log attributed to your user. + +## What you need + +- A Takaro account. +- An assistant ("harness") from the supported list below. Most harnesses need nothing but the endpoint URL; a few need a client id as well. + +## The endpoint + +| Deployment | URL | +| ------------- | --------------------------- | +| Takaro-hosted | `https://api.takaro.io/mcp` | +| Self-hosted | `/mcp` | + +You never have to look up a login server. The endpoint publishes a discovery document that tells the assistant where to authenticate, and every compliant harness reads it automatically. Check that it is reachable: + +```bash +curl https://api.takaro.io/.well-known/oauth-protected-resource/mcp +``` + +The response names the endpoint and the authorization server your assistant will be sent to: + +```json +{ + "resource": "https://api.takaro.io/mcp", + "authorization_servers": ["https:///realms/takaro"], + "resource_name": "Takaro API" +} +``` + +## Claude Code + +Add the server by URL. There is no client id, no secret, and no registration step: + +```bash +claude mcp add --transport http takaro https://api.takaro.io/mcp +``` + +The first time Claude Code uses it, a browser opens on the Takaro login page. Sign in, and **a consent screen appears** asking whether to let the assistant act on your Takaro account. Approve it. + +Back in Claude Code, check the connection by asking it to list your Takaro domains. It should name every domain you belong to. + +## Claude.ai and ChatGPT + +Both take the same URL-only path. + +- **Claude.ai** — add `https://api.takaro.io/mcp` as a custom connector, then complete the same login and consent. +- **ChatGPT / Codex** — add it as an MCP server by URL. + +Neither needs a client id. + +## Harnesses without automatic registration + +Some harnesses cannot register themselves the way the ones above do. For those, Takaro pre-registers a client in every environment, and you point the harness at its fixed client id: + +| Harness | `client_id` | Redirect URIs | +| ----------------- | ------------------- | ------------------------------------------------------------------------------------ | +| Cursor | `takaro-mcp-cursor` | `https://www.cursor.com/agents/mcp/oauth/callback`, `http://localhost:8787/callback` | +| VS Code / Copilot | `takaro-mcp-vscode` | `https://vscode.dev/redirect`, `http://127.0.0.1:33418` | + +Both are public clients using PKCE, both require consent, and both are configured so that no extra scope has to be requested. Their definitions live in the Takaro repository, in [`containers/keycloak/config/takaro-realm.yaml`](https://github.com/gettakaro/takaro/blob/development/containers/keycloak/config/takaro-realm.yaml). + +:::caution +These two clients are **not yet verified end to end**. Neither vendor documents whether it can be pointed at a fixed client id rather than registering its own. If you get one of them working — or find that you cannot — please tell us in an issue on the Takaro repository. +::: + +Claude Code can also use a fixed client id if you ever need it to, with `claude mcp add --client-id --callback-port …`. + +## Not supported yet + +**Windsurf** and **Zed** have no client. Neither publishes a fixed callback URL anywhere authoritative, and Takaro will not guess one: a redirect URI that is not exactly right is a security hole rather than a convenience. + +More generally, a harness that registers itself by URL can only do so if its own host is on Takaro's allowlist. `claude.ai`, `chatgpt.com` and loopback addresses are allowed today. A new harness on a new host needs that host added to the Takaro deployment's configuration first — there is deliberately no "any host" setting. + +## What your assistant can and cannot do + +- **It acts as you.** Same roles, same permissions. See [roles and permissions](../roles-and-permissions.md). +- **It works in one domain at a time.** A domain is one tenant: its game servers, players, modules and roles are separate from every other domain's. +- **Staff-only operations are invisible to it.** Anything guarded by Takaro's admin authentication — creating domains, for example — is excluded from what the assistant can see or call, mechanically, not by convention. +- **Everything is audited.** Changes land in your event log with your user as the acting user, exactly as if you had made them in the dashboard. Your normal rate limits apply. + +It has four tools: + +| Tool | What it does | +| -------------------- | ----------------------------------------------------------------------------------------- | +| `search_api` | Finds API operations from a plain-language description, and returns their ids | +| `describe_operation` | Returns the exact request and response shape of one operation, including validation rules | +| `call_api` | Runs one operation as you, and returns the response | +| `list_domains` | Lists the domains you belong to, with their names and ids | + +A well-behaved assistant searches, describes, then calls. If it guesses an operation id instead, it gets a clear error telling it to search first. + +## Choosing a domain + +- **You belong to one domain.** Nothing to do. The assistant never mentions domains and never asks. +- **You belong to several.** A call that does not name a domain is **refused before it runs**, with a message listing each domain by name and id and telling the assistant to ask you which one to use. Tell it, and it repeats the call against that domain. This is deliberate: a helpful guess against the wrong tenant is worse than a question. +- **You belong to none.** Calls are refused, because there is nothing to act on. + +Ask your assistant to list your domains if you are not sure what it can see. + +## The destructive-call brake + +Takaro limits how fast an assistant can delete things. + +- **Destructive means a delete.** Creating or updating something is never braked — only operations that remove data. +- By default, **5 destructive calls in 60 seconds**. The sixth is refused with a message telling the assistant to stop and ask you what should be deleted, and that it may try again after the window. +- The window starts at the first destructive call and is not extended by later ones. +- The limit is counted **per user, across all your domains**, and it counts attempts — a delete that Takaro then rejects for another reason still spends one. +- Reading keeps working while the brake is engaged. It stops runaway deletion; it does not lock your assistant out. +- The brake applies **only to the MCP endpoint**. The REST API is unchanged. + +Self-hosting? The two settings are `MCP_DESTRUCTIVE_CALL_THRESHOLD` (default `5`) and `MCP_DESTRUCTIVE_CALL_WINDOW_SECONDS` (default `60`). + +## Large responses + +Two rules keep an answer inside a model's context window: + +- A paginated operation called without a page size is given a small one automatically, so "list the players" does not return thousands of rows. +- A response larger than the byte cap (`MCP_MAX_RESPONSE_BYTES`, default 65536) is cut off, and a `--- TRUNCATED ---` note is appended saying how large the response really was and how to fetch the rest — a smaller page size, the next page, or a narrower filter. + +If your assistant reports that data was truncated, it is not an error. Ask it to narrow the query. + +## Troubleshooting + +**The assistant gets a 401.** The token is missing, expired, or was issued for something other than the Takaro API. Disconnect and reconnect the server so the login runs again. + +**No consent screen appeared, and the connection failed.** The harness's host is probably not on the allowlist, so Takaro would not let it register itself by URL. Use a pre-registered client id if one exists for your harness, or ask for the host to be added. + +**"Unknown operation id".** The assistant invented an id, or the operation is staff-only. Ask it to use `search_api` first. + +**The call was refused because you belong to more than one domain.** Tell it which domain to work in; the refusal message lists them. + +**A delete was refused with a mention of a limit.** That is the destructive-call brake. Confirm what should be deleted, and it can continue after the window passes. + +## Next steps + +- [The Takaro API](./api.md) — the same operations, called directly. +- [Roles and permissions](../roles-and-permissions.md) — what your assistant inherits from your account. From 7e9f3377cca4be6e3b23d6b978f678f6084e9921 Mon Sep 17 00:00:00 2001 From: Niek Candaele <22315101+niekcandaele@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:37:53 +0200 Subject: [PATCH 2/3] docs(advanced): rework the AI assistant page after review (GH #3623) A UX review of the first draft found the page had exactly one assistant a reader could follow to completion. Fixes: - An "which assistant do you have?" table up front, with an honest verification status per assistant, so a reader finds their own path without reading the whole page. - Claude.ai and ChatGPT get real setup sections and a verification step instead of one sentence each. - Cursor and VS Code get told what to actually do with the client id, and are told plainly that if their assistant has no client-id setting it is not supported yet. - New: how to disconnect and reconnect, how to revoke the grant, and a self-hosted section carrying the allowlist rule (no wildcard) and the two environment variables that were previously scattered through user prose. - Troubleshooting gains the dominant self-hosted failure (browser cannot reach the login server), quotes the real "Unknown operation id" message, and is split into linkable headings. - Drops the "harness" jargon, the curl diagnostic from the main flow, and the bolded-bullet lists in favour of prose. Also links the page from advanced/api.md, which was the only other place a reader looking for programmatic access would land. Claude-Session: https://claude.ai/code/session_01LRsE6g3Copo9nYfxCuP5Z6 --- docs/advanced/api.md | 2 + docs/advanced/connect-your-ai-assistant.md | 152 +++++++++++++-------- 2 files changed, 97 insertions(+), 57 deletions(-) diff --git a/docs/advanced/api.md b/docs/advanced/api.md index 3894f26..3a9eb32 100644 --- a/docs/advanced/api.md +++ b/docs/advanced/api.md @@ -6,6 +6,8 @@ sidebar_position: 4 For a hands-on experience and quick start with the Takaro API, visit the [interactive API documentation](https://api.takaro.io/api.html). You can explore endpoints, make test requests, and view responses in real-time. +If you would rather have an AI assistant call these operations for you, see [Connect your AI assistant](./connect-your-ai-assistant.md). + ## Authentication To use the API programmatically, authenticate by calling the login endpoint with your credentials. This returns a session token you can use for subsequent requests. diff --git a/docs/advanced/connect-your-ai-assistant.md b/docs/advanced/connect-your-ai-assistant.md index 496be56..bc5fad2 100644 --- a/docs/advanced/connect-your-ai-assistant.md +++ b/docs/advanced/connect-your-ai-assistant.md @@ -4,14 +4,28 @@ sidebar_position: 8 # Connect your AI assistant -Takaro exposes an **MCP endpoint**: a single URL that an AI assistant — Claude Code, Claude.ai, ChatGPT, Cursor — can connect to and then use to work with your game servers, players, modules and roles on your behalf. +Takaro exposes an **MCP endpoint**: a single URL your AI assistant connects to. Once connected, it can work with your game servers, players, modules, and roles on your behalf. Claude Code, Claude.ai, and ChatGPT connect with nothing but that URL. -The assistant acts **as you**. It signs in with your own Takaro account through the normal login page, and every call it makes carries exactly the roles and permissions you already have. It cannot see or do anything you could not do yourself in the dashboard, and every change it makes shows up in your event log attributed to your user. +The assistant acts **as you**. It signs in with your own Takaro account through the normal login page, and every call it makes carries exactly the roles and permissions you already have. It cannot see or do anything you could not do yourself in the dashboard, and every change it makes appears in your event log attributed to your user. ## What you need - A Takaro account. -- An assistant ("harness") from the supported list below. Most harnesses need nothing but the endpoint URL; a few need a client id as well. +- Membership of at least one Takaro domain. An assistant connected to an account with no domain can sign in, but has nothing to act on. +- One of the assistants below. + +## Which assistant do you have? + +| Assistant | Status | What you supply | Where | +| --------------------- | ----------------------------------------- | ------------------- | ---------------- | +| Claude Code | Verified | The URL | [Claude Code](#claude-code) | +| Claude.ai | Expected to work, not confirmed by Takaro | The URL | [Claude.ai](#claudeai) | +| ChatGPT and Codex | Expected to work, not confirmed by Takaro | The URL | [ChatGPT and Codex](#chatgpt-and-codex) | +| Cursor | Unverified | The URL and a client id | [Assistants that need a client id](#assistants-that-need-a-client-id) | +| VS Code / Copilot | Unverified | The URL and a client id | [Assistants that need a client id](#assistants-that-need-a-client-id) | +| Windsurf, Zed | Not supported | — | [Not supported yet](#not-supported-yet) | + +"Verified" means somebody has driven the whole flow — sign-in, consent, and real calls — end to end. Everything below that line is honest about what has not been tried yet. ## The endpoint @@ -20,72 +34,66 @@ The assistant acts **as you**. It signs in with your own Takaro account through | Takaro-hosted | `https://api.takaro.io/mcp` | | Self-hosted | `/mcp` | -You never have to look up a login server. The endpoint publishes a discovery document that tells the assistant where to authenticate, and every compliant harness reads it automatically. Check that it is reachable: +You never have to look up a login server. The endpoint publishes a discovery document that tells the assistant where to authenticate, and every compliant assistant reads it automatically. + +## Claude Code + +Add the server by URL. There is no client id, no secret, and no registration step: ```bash -curl https://api.takaro.io/.well-known/oauth-protected-resource/mcp +claude mcp add --transport http takaro https://api.takaro.io/mcp ``` -The response names the endpoint and the authorization server your assistant will be sent to: +The first time Claude Code uses it, a browser opens on the Takaro login page. Sign in, and **a consent screen appears** asking whether to let the assistant act on your Takaro account. Approve it. -```json -{ - "resource": "https://api.takaro.io/mcp", - "authorization_servers": ["https:///realms/takaro"], - "resource_name": "Takaro API" -} -``` +Check the connection by asking Claude Code: -## Claude Code +> list my Takaro domains -Add the server by URL. There is no client id, no secret, and no registration step: +It should name every domain you belong to. To disconnect and start over: ```bash -claude mcp add --transport http takaro https://api.takaro.io/mcp +claude mcp remove takaro ``` -The first time Claude Code uses it, a browser opens on the Takaro login page. Sign in, and **a consent screen appears** asking whether to let the assistant act on your Takaro account. Approve it. +## Claude.ai -Back in Claude Code, check the connection by asking it to list your Takaro domains. It should name every domain you belong to. +Open **Settings → Connectors**, add a custom connector, and give it `https://api.takaro.io/mcp`. The same login and consent screens follow. Check it the same way — ask it to list your Takaro domains. -## Claude.ai and ChatGPT +Custom connectors are not available on every Claude.ai plan. If you cannot find the option, use Claude Code instead. -Both take the same URL-only path. +## ChatGPT and Codex -- **Claude.ai** — add `https://api.takaro.io/mcp` as a custom connector, then complete the same login and consent. -- **ChatGPT / Codex** — add it as an MCP server by URL. +Both add MCP servers by URL, from their own settings. Give them `https://api.takaro.io/mcp`, complete the login and consent, then ask the assistant to list your Takaro domains. -Neither needs a client id. +Where that setting lives moves between ChatGPT releases and plans, so follow your assistant's own documentation for adding a remote MCP server. Nothing Takaro-specific is needed beyond the URL. -## Harnesses without automatic registration +## Assistants that need a client id -Some harnesses cannot register themselves the way the ones above do. For those, Takaro pre-registers a client in every environment, and you point the harness at its fixed client id: +Claude Code, Claude.ai and ChatGPT register themselves with Takaro automatically, using their vendor's published identity. Cursor and VS Code do not. For those, Takaro pre-registers a client in every environment, and you point the assistant at its fixed client id: -| Harness | `client_id` | Redirect URIs | -| ----------------- | ------------------- | ------------------------------------------------------------------------------------ | -| Cursor | `takaro-mcp-cursor` | `https://www.cursor.com/agents/mcp/oauth/callback`, `http://localhost:8787/callback` | -| VS Code / Copilot | `takaro-mcp-vscode` | `https://vscode.dev/redirect`, `http://127.0.0.1:33418` | +| Assistant | `client_id` | +| ----------------- | ------------------- | +| Cursor | `takaro-mcp-cursor` | +| VS Code / Copilot | `takaro-mcp-vscode` | -Both are public clients using PKCE, both require consent, and both are configured so that no extra scope has to be requested. Their definitions live in the Takaro repository, in [`containers/keycloak/config/takaro-realm.yaml`](https://github.com/gettakaro/takaro/blob/development/containers/keycloak/config/takaro-realm.yaml). +Add `https://api.takaro.io/mcp` as an MCP server in the assistant, then look for a client-id setting on that server entry and put the id above in it. Everything else — consent, permissions, scopes — is already configured on Takaro's side. -:::caution -These two clients are **not yet verified end to end**. Neither vendor documents whether it can be pointed at a fixed client id rather than registering its own. If you get one of them working — or find that you cannot — please tell us in an issue on the Takaro repository. +:::caution Unverified +Neither vendor documents whether it lets you supply a client id at all, and neither has been driven through this flow end to end. **If you cannot find a client-id setting, that assistant is not supported yet** — it will try to register itself, which Takaro refuses. Either way, please [open an issue](https://github.com/gettakaro/takaro/issues/new) telling us what you found; it is exactly what we are missing. ::: -Claude Code can also use a fixed client id if you ever need it to, with `claude mcp add --client-id --callback-port …`. +Self-hosting, or curious about the details? Both clients are defined in [`containers/keycloak/config/takaro-realm.yaml`](https://github.com/gettakaro/takaro/blob/development/containers/keycloak/config/takaro-realm.yaml), including the exact redirect URIs they accept. ## Not supported yet **Windsurf** and **Zed** have no client. Neither publishes a fixed callback URL anywhere authoritative, and Takaro will not guess one: a redirect URI that is not exactly right is a security hole rather than a convenience. -More generally, a harness that registers itself by URL can only do so if its own host is on Takaro's allowlist. `claude.ai`, `chatgpt.com` and loopback addresses are allowed today. A new harness on a new host needs that host added to the Takaro deployment's configuration first — there is deliberately no "any host" setting. +More generally, an assistant that registers itself by URL can only do so if its own host is on Takaro's allowlist. `claude.ai`, `chatgpt.com` and loopback addresses are allowed today. On Takaro-hosted, [open an issue](https://github.com/gettakaro/takaro/issues/new) to ask for a host to be added. On a self-hosted deployment you add it yourself — see [Self-hosted deployments](#self-hosted-deployments). ## What your assistant can and cannot do -- **It acts as you.** Same roles, same permissions. See [roles and permissions](../roles-and-permissions.md). -- **It works in one domain at a time.** A domain is one tenant: its game servers, players, modules and roles are separate from every other domain's. -- **Staff-only operations are invisible to it.** Anything guarded by Takaro's admin authentication — creating domains, for example — is excluded from what the assistant can see or call, mechanically, not by convention. -- **Everything is audited.** Changes land in your event log with your user as the acting user, exactly as if you had made them in the dashboard. Your normal rate limits apply. +Your assistant acts as you: same roles, same permissions, as described in [roles and permissions](../roles-and-permissions.md). It works in one domain at a time — a domain is one tenant, and its game servers, players, modules, and roles are separate from every other domain's. Staff-only operations, such as creating domains, are excluded from what it can see or call at all. Every change lands in your event log with your user as the acting user, exactly as if you had made it in the dashboard, and your normal rate limits apply. It has four tools: @@ -100,45 +108,75 @@ A well-behaved assistant searches, describes, then calls. If it guesses an opera ## Choosing a domain -- **You belong to one domain.** Nothing to do. The assistant never mentions domains and never asks. -- **You belong to several.** A call that does not name a domain is **refused before it runs**, with a message listing each domain by name and id and telling the assistant to ask you which one to use. Tell it, and it repeats the call against that domain. This is deliberate: a helpful guess against the wrong tenant is worse than a question. -- **You belong to none.** Calls are refused, because there is nothing to act on. +If you belong to one domain, there is nothing to do — the assistant never mentions domains and never asks. + +If you belong to several, a call that does not name a domain is **refused before it runs**, with a message listing each domain by name and id and telling the assistant to ask you which one to use. Tell it, and it repeats the call against that domain. This is deliberate: guessing wrong and acting on the wrong domain is worse than asking. + +If you belong to none, every call is refused, because there is nothing to act on. Ask your assistant to list your domains if you are not sure what it can see. ## The destructive-call brake -Takaro limits how fast an assistant can delete things. - -- **Destructive means a delete.** Creating or updating something is never braked — only operations that remove data. -- By default, **5 destructive calls in 60 seconds**. The sixth is refused with a message telling the assistant to stop and ask you what should be deleted, and that it may try again after the window. -- The window starts at the first destructive call and is not extended by later ones. -- The limit is counted **per user, across all your domains**, and it counts attempts — a delete that Takaro then rejects for another reason still spends one. -- Reading keeps working while the brake is engaged. It stops runaway deletion; it does not lock your assistant out. -- The brake applies **only to the MCP endpoint**. The REST API is unchanged. +Takaro limits how fast an assistant can delete things. By default, the sixth delete within 60 seconds is refused, with a message telling the assistant to stop, ask you what should be deleted, and try again after the window. The window starts at the first delete and is not extended by later ones. -Self-hosting? The two settings are `MCP_DESTRUCTIVE_CALL_THRESHOLD` (default `5`) and `MCP_DESTRUCTIVE_CALL_WINDOW_SECONDS` (default `60`). +Deletes are counted per user across all your domains, and attempts count — a delete Takaro then rejects for another reason still spends one. Creating and updating are never braked, only deleting (and any operation Takaro explicitly marks as destructive). Reading keeps working while the brake is engaged: it stops runaway deletion, it does not lock your assistant out. The brake applies only to the MCP endpoint, never to the REST API. ## Large responses Two rules keep an answer inside a model's context window: - A paginated operation called without a page size is given a small one automatically, so "list the players" does not return thousands of rows. -- A response larger than the byte cap (`MCP_MAX_RESPONSE_BYTES`, default 65536) is cut off, and a `--- TRUNCATED ---` note is appended saying how large the response really was and how to fetch the rest — a smaller page size, the next page, or a narrower filter. +- A response larger than 64 KB is cut off, and a `--- TRUNCATED ---` note is appended saying how large the response really was and how to fetch the rest — a smaller page size, the next page, or a narrower filter. -If your assistant reports that data was truncated, it is not an error. Ask it to narrow the query. +If your assistant reports that data was truncated, that is not an error. Ask it to narrow the query. + +## Revoking access + +Removing the MCP server from your assistant stops that assistant using it, but it does not withdraw the permission you granted on the consent screen. To do that, open the account console of the login server your browser was sent to during setup — its address is the one you saw in the browser while signing in — and remove Takaro's entry under **Applications**. Signing out of every session there ends any access token already issued. + +Do both if you have lost the device the assistant was running on. ## Troubleshooting -**The assistant gets a 401.** The token is missing, expired, or was issued for something other than the Takaro API. Disconnect and reconnect the server so the login runs again. +### The assistant says it cannot reach Takaro, or reports a 401 + +The token is missing, expired, or was issued for something other than the Takaro API. Remove the MCP server from your assistant and add it again so the login runs afresh — in Claude Code, `claude mcp remove takaro` followed by the `claude mcp add` command above. + +### The browser opened but the login page never loaded + +Self-hosted deployments only. The login server has to be reachable **from the machine running the browser**, over HTTPS, on a public hostname. An internal-only address dead-ends here even though the API itself works. + +### No consent screen appeared, and the connection failed + +The assistant's host is probably not on Takaro's allowlist, so Takaro would not let it register itself by URL. Use a client id if one exists for your assistant, or ask for the host to be added. + +### The assistant says "Unknown operation id" -**No consent screen appeared, and the connection failed.** The harness's host is probably not on the allowlist, so Takaro would not let it register itself by URL. Use a pre-registered client id if one exists for your harness, or ask for the host to be added. +The full message is: _Unknown operation id "…". It does not exist or is not available through this endpoint. Use search_api to find a valid operation id._ Either the assistant invented an id, or the operation is staff-only. Ask it to search first. + +### The call was refused because you belong to more than one domain + +Tell the assistant which domain to work in; the refusal message lists them by name. + +### A delete was refused with a mention of a limit + +That is the destructive-call brake. Confirm what should be deleted, and the assistant can continue once the window has passed. + +### Checking the endpoint is reachable + +```bash +curl https://api.takaro.io/.well-known/oauth-protected-resource/mcp +``` -**"Unknown operation id".** The assistant invented an id, or the operation is staff-only. Ask it to use `search_api` first. +A healthy deployment answers with a small JSON document naming the endpoint and the login server your assistant will be sent to. Anything else — a connection error, an HTML error page — means the endpoint itself is the problem, not your assistant. -**The call was refused because you belong to more than one domain.** Tell it which domain to work in; the refusal message lists them. +## Self-hosted deployments -**A delete was refused with a mention of a limit.** That is the destructive-call brake. Confirm what should be deleted, and it can continue after the window passes. +- The endpoint is `/mcp`, and the login server must be reachable over HTTPS from your users' browsers. +- An assistant may only register itself by URL if its host is listed in `keycloak.realm.mcp.permittedClientIdDomains`. There is no wildcard: `*` matches nothing, and an empty list rejects everything. Every host in the assistant's redirect URIs has to be listed too. +- The brake is `MCP_DESTRUCTIVE_CALL_THRESHOLD` (default `5`) within `MCP_DESTRUCTIVE_CALL_WINDOW_SECONDS` (default `60`). +- The response cap is `MCP_MAX_RESPONSE_BYTES` (default `65536`). ## Next steps From 52f09a330354401f2f387b51a8355da9251ee634 Mon Sep 17 00:00:00 2001 From: Niek Candaele <22315101+niekcandaele@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:40:39 +0200 Subject: [PATCH 3/3] docs(advanced): correct four claims the code does not support (GH #3623) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An independent review against the implementation caught four overstatements: - The endpoint is modern-only (`legacy: 'reject'`, revision 2026-07-28). An older client can complete the OAuth flow and still have every tool call refused, so it belongs in "what you need". - `claude mcp add` does not itself start the login. Say to run `/mcp` in Claude Code. - Nothing forces search-before-call: a correctly guessed operation id runs. The error only fires on an id the endpoint does not expose. - "Every change appears in your event log" is stronger than the code: an MCP call is audited exactly as the same action is from the dashboard, no more. Also separates ChatGPT from Codex, and stops asserting what Cursor and VS Code do or do not document — both describe a client-id setting; what is unverified is whether the flow completes against Takaro. Claude-Session: https://claude.ai/code/session_01LRsE6g3Copo9nYfxCuP5Z6 --- docs/advanced/connect-your-ai-assistant.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/advanced/connect-your-ai-assistant.md b/docs/advanced/connect-your-ai-assistant.md index bc5fad2..2df6055 100644 --- a/docs/advanced/connect-your-ai-assistant.md +++ b/docs/advanced/connect-your-ai-assistant.md @@ -6,13 +6,13 @@ sidebar_position: 8 Takaro exposes an **MCP endpoint**: a single URL your AI assistant connects to. Once connected, it can work with your game servers, players, modules, and roles on your behalf. Claude Code, Claude.ai, and ChatGPT connect with nothing but that URL. -The assistant acts **as you**. It signs in with your own Takaro account through the normal login page, and every call it makes carries exactly the roles and permissions you already have. It cannot see or do anything you could not do yourself in the dashboard, and every change it makes appears in your event log attributed to your user. +The assistant acts **as you**. It signs in with your own Takaro account through the normal login page, and every call it makes carries exactly the roles and permissions you already have. It cannot see or do anything you could not do yourself in the dashboard, and its changes are audited exactly as the same action would be if you made it there — attributed to your user, with no separate treatment for having come from an assistant. ## What you need - A Takaro account. - Membership of at least one Takaro domain. An assistant connected to an account with no domain can sign in, but has nothing to act on. -- One of the assistants below. +- One of the assistants below. It has to speak a current version of the MCP protocol (revision `2026-07-28` or newer); an older client is turned away even after signing in successfully. ## Which assistant do you have? @@ -44,7 +44,7 @@ Add the server by URL. There is no client id, no secret, and no registration ste claude mcp add --transport http takaro https://api.takaro.io/mcp ``` -The first time Claude Code uses it, a browser opens on the Takaro login page. Sign in, and **a consent screen appears** asking whether to let the assistant act on your Takaro account. Approve it. +Adding the server does not sign you in — Claude Code marks it as needing authentication. Run `/mcp` inside Claude Code and start the login from there (some versions also accept `claude mcp login takaro`). A browser opens on the Takaro login page; sign in, and **a consent screen appears** asking whether to let the assistant act on your Takaro account. Approve it. Check the connection by asking Claude Code: @@ -64,9 +64,12 @@ Custom connectors are not available on every Claude.ai plan. If you cannot find ## ChatGPT and Codex -Both add MCP servers by URL, from their own settings. Give them `https://api.takaro.io/mcp`, complete the login and consent, then ask the assistant to list your Takaro domains. +These are two different products with two different setup surfaces, but the Takaro side is identical: `https://api.takaro.io/mcp`, then login and consent, then ask the assistant to list your Takaro domains. -Where that setting lives moves between ChatGPT releases and plans, so follow your assistant's own documentation for adding a remote MCP server. Nothing Takaro-specific is needed beyond the URL. +- **ChatGPT** connects remote MCP servers from its own settings. Whether the option is available depends on your plan and, in a workspace, on your admin's policy. +- **Codex** is configured from its CLI, and signing in to the server is a separate step from adding it. + +Where those settings live moves between releases, so follow your assistant's own documentation for adding a remote MCP server. Nothing Takaro-specific is needed beyond the URL. ## Assistants that need a client id @@ -80,7 +83,7 @@ Claude Code, Claude.ai and ChatGPT register themselves with Takaro automatically Add `https://api.takaro.io/mcp` as an MCP server in the assistant, then look for a client-id setting on that server entry and put the id above in it. Everything else — consent, permissions, scopes — is already configured on Takaro's side. :::caution Unverified -Neither vendor documents whether it lets you supply a client id at all, and neither has been driven through this flow end to end. **If you cannot find a client-id setting, that assistant is not supported yet** — it will try to register itself, which Takaro refuses. Either way, please [open an issue](https://github.com/gettakaro/takaro/issues/new) telling us what you found; it is exactly what we are missing. +Neither of these has been driven through the whole flow against Takaro, so we cannot promise it works. Both vendors describe a client-id setting on an MCP server entry — Cursor as `auth.CLIENT_ID`, VS Code as `oauth.clientId` — but check your own version's documentation for the current name. **If your assistant has no such setting, it is not supported yet**: it will try to register itself, which Takaro refuses. Either way, please [open an issue](https://github.com/gettakaro/takaro/issues/new) telling us what you found; it is exactly what we are missing. ::: Self-hosting, or curious about the details? Both clients are defined in [`containers/keycloak/config/takaro-realm.yaml`](https://github.com/gettakaro/takaro/blob/development/containers/keycloak/config/takaro-realm.yaml), including the exact redirect URIs they accept. @@ -93,7 +96,7 @@ More generally, an assistant that registers itself by URL can only do so if its ## What your assistant can and cannot do -Your assistant acts as you: same roles, same permissions, as described in [roles and permissions](../roles-and-permissions.md). It works in one domain at a time — a domain is one tenant, and its game servers, players, modules, and roles are separate from every other domain's. Staff-only operations, such as creating domains, are excluded from what it can see or call at all. Every change lands in your event log with your user as the acting user, exactly as if you had made it in the dashboard, and your normal rate limits apply. +Your assistant acts as you: same roles, same permissions, as described in [roles and permissions](../roles-and-permissions.md). It works in one domain at a time — a domain is one tenant, and its game servers, players, modules, and roles are separate from every other domain's. Staff-only operations, such as creating domains, are excluded from what it can see or call at all. Whatever an action records in your event log when you do it in the dashboard, it records the same way when your assistant does it — with your user as the acting user — and your normal rate limits apply. It has four tools: @@ -104,7 +107,7 @@ It has four tools: | `call_api` | Runs one operation as you, and returns the response | | `list_domains` | Lists the domains you belong to, with their names and ids | -A well-behaved assistant searches, describes, then calls. If it guesses an operation id instead, it gets a clear error telling it to search first. +A well-behaved assistant searches, describes, then calls, and the tool descriptions tell it to. Nothing forces the order: an assistant that guesses an id correctly can call it straight away. An id that does not exist — or that it is not allowed to see — comes back as an error pointing it at `search_api`. ## Choosing a domain