Connecting an agent

Kampa runs an MCP server. An MCP client you already use, such as Claude Code, Claude.ai or Cursor, connects to it with one URL and can then read your project's tokens, grade colour pairs, read the check's verdict and, if you allow it, propose changes. The model runs on your own account. Kampa stores no AI key and runs no model for this.

Everything here describes what Kampa does today.

Connect

The URL is https://<your Kampa address>/api/mcp. Settings, Agents shows it with a Copy button.

  1. Paste the URL into your client as a remote MCP server.
  2. Your client opens Kampa in the browser. Sign in if you aren't.
  3. Kampa names the client asking and lets you choose:
    • Read-only or Read & write.
    • This project (pick one) or All my projects.
  4. Select Allow. The browser goes back to your client, which is now connected.

Claude Code

claude mcp add --transport http kampa https://<your Kampa address>/api/mcp

Claude.ai: Settings, Connectors, Add custom connector, and paste the URL.

Cursor, in .cursor/mcp.json or ~/.cursor/mcp.json:

{
  "mcpServers": {
    "kampa": { "url": "https://<your Kampa address>/api/mcp" }
  }
}

A connected client appears under Connected clients in Settings, Agents: its name, its access, its projects, when it connected and when it was last used. Revoke ends it at once. To change a client's access, revoke it and connect again.

Behind the scenes this is OAuth 2.1: the client registers itself, you approve it on Kampa's own page, and Kampa gives the client a token that lasts an hour and a refresh token it uses to get the next one. Kampa stores only hashes of both.

Manual tokens

For scripts, and clients that can't sign in with OAuth, open Manual tokens (advanced) in Settings, Agents. Give the token a name, pick Read or Write, and select Create token. Kampa shows the token once and stores only a hash. A manual token reaches one project and does not expire until you revoke it. Send it on every request:

claude mcp add --transport http kampa https://<your Kampa address>/api/mcp --header "Authorization: Bearer <token>"

What the tools do

Tool What it does
list_projects The project the token reaches: name, modes, rail, WCAG level, push target, revision.
list_tokens Every token with its path, type and value per mode. Filter by path prefix or type; paged.
get_token One token: its value per mode, the alias chain it follows and what it resolves to.
get_verdict The check's current report: pairs tested, failures by pair and mode, exemptions, lint errors, component results. The same report the editor shows.
grade_pair Contrast between two colours, each a hex value or a token path, at AA or AAA.
read_artifact tokens.css, tokens.ts or one mode's DTCG file, exactly as Kampa would push it.
read_page Without a name: the project's pages with their verdicts, and the components a page can use, with their variants, states and text slots. With a name: that page's document and its check, and on request the index.html and page.css Kampa writes for it.

Every result carries the project's revision, which changes whenever the project is saved.

Every tool takes an optional project, an id from list_projects. A connection that reaches all your projects needs it whenever you have more than one; a connection to one project never does.

Write tools (Read & write only)

On a Read-only connection the write tools are listed but refuse, by name: the answer says the tool needs Read & write, so your agent can tell you to reconnect.

Tool What it does
propose_changes A batch of edits, checked as one: set a value, point a token at another (an alias is a value like {color.blue.500}), add a token, remove a token, set a role, add a mode copied from another. Checks only, unless apply is true.
propose_page A whole page document (format 0.5): layout nodes and component instances, every value a token. Checks only, unless apply is true.
push Opens a pull request on the connected repository with the project's current tokens. Rail 2 projects only.

propose_changes runs the same checks the editor's prompt bar runs: the batch is tried on a copy of the project, the project's rules must still hold, and the accessibility check runs before and after. The answer lists every change and every contrast pair that would newly fail.

A batch is applied whole or not at all. It is refused when:

  • the revision it names is not the project's current one, because someone saved since the agent read it. The refusal names the current revision;
  • any change in it is malformed, names a token or mode that does not exist, or gives a value of the wrong type;
  • it adds a contrast failure and the project's Block push on check failure is on. The refusal names each pair, mode and ratio;
  • it would leave a value Kampa can't write into tokens.css, such as a reference to a token that does not exist.

propose_page runs the page check the editor runs: the document's shape, that every component, variant, state, slot and breakpoint exists, that every dimension and colour is a token, and every contrast pair of every component on the background it sits on, in every mode. A page with any error is refused, and a page with a failing pair is refused when Block push on check failure is on. A page with the same name is replaced.

Each applied batch or page is listed under Change sets in Settings, Agents, with its summary, how many changes it held, and which client or token made it. Undoing a change set from that list is not built yet.

push on a Rail 2 project opens a pull request the way Push in the editor does, with the same check. Its Change note says "Proposed through the Kampa connector" and lists the latest change sets. A Rail 1 push merges, so on a Rail 1 project push is refused: the change is ready for you to push in Kampa.

The editor does not yet pick up a change an agent saved while the project is open. Reload the editor after an agent applies a batch, or your next save will overwrite it.

What it refuses

  • A request without a valid token gets 401, with a header that tells the client where to sign in. A revoked token, an expired one, a token for a project you no longer own, and a made-up token all get the same answer.
  • A browser request from another site gets 403.
  • More than 120 requests a minute on one token get 429, with a Retry-After.
  • A token path, a mode name or a file name is only ever looked up in the project's own data. A path that is not a token path, a mode the project does not have, or a file Kampa does not write is refused with a message the model can read.
  • An agent can never connect GitHub, change the rail or delete a project.