Tecto docs
tectoapp.io

MCP server

Tecto ships a first-party MCP server, so an agent — Claude, an agent CLI, anything that speaks the protocol — can read and move a workspace's boards without anyone writing glue code.

There is nothing to install. The server runs on your Tecto instance and answers at https://app.tectoapp.io/mcp; you point an agent at that address and give it a token.

It is a thin layer over the public API: the endpoint holds no permission logic of its own but makes ordinary API requests with your credential, so an agent sees and changes exactly what you can. Card bodies cross the wire as canonical Markdown.

Setting it up

Mint a token first: Settings → Tokens, in the workspace the agent should work in. Give it content:read if the agent should only read, content:write if it should also write. The secret is shown once.

A token minted here works here — it reads and writes what Tecto shows you, and nothing the other apps hold. That also means you do not have to tell the agent which workspace to use: the token names one, and the endpoint reads it from there.

In an MCP host's configuration file:

{
  "mcpServers": {
    "tecto": {
      "type": "http",
      "url": "https://app.tectoapp.io/mcp",
      "headers": {
        "Authorization": "Bearer tecto_pat_…"
      }
    }
  }
}

Hosts differ in how they spell this; what they all need is the address and the Authorization header. In Claude Code, for example:

claude mcp add --transport http tecto https://app.tectoapp.io/mcp \
  --header "Authorization: Bearer tecto_pat_…"

If your account is in several workspaces and you want to name one explicitly, address https://app.tectoapp.io/mcp/w/<workspace id> instead. A token may only ever name its own workspace, so the two have to agree.

Keeping an agent read-only is the token's job, not a setting: a content:read token is refused by the server on every write, which is a stronger guarantee than a switch on the client side.

Adding it as a connector

Hosts that offer no header field — claude.ai among them — add the endpoint as a connector and sign you in instead. Paste the same address, https://app.tectoapp.io/mcp, into the connector dialog; the rest is a sign-in and one screen asking whether you want to connect. Nothing to copy, no token to keep.

A connector is broader than a token, and the screen says so before you agree:

  • It covers every workspace you are a member of, not one.
  • It reads and writes what you can. There is no read-only connector; mint a content:read token for an agent that should only look.
  • It still sees Tecto only, and it stops working when your access does.

Because a connector covers several workspaces, the agent has to say which one it means: https://app.tectoapp.io/mcp/w/<workspace id>.

What the agent gets

Read-only unless marked.

  • get_workspace — name and shape of the workspace the token opens.
  • list_boards / get_board — the boards, and one board's columns and lanes.
  • get_board_cards — a board's cards, grouped by column × lane, with honest per-group totals and cursors for the long columns.
  • create_board (write) — a new board in a collection, with the default columns the app would seed.
  • add_card (write) — a new card at a column's end, or an existing page attached as a card.
  • move_card (write) — column, lane and position in one step, the same transactional move the app performs.
  • get_card / update_card (write) — a card's body as canonical Markdown, read and replaced whole.
  • comment_on_card (write) / list_card_comments — the card's discussion.
  • search — full-text over the workspace; every hit says what it is.

What the agent cannot do, the token could not do either: permissions, visibility and trash semantics are the server's, not the MCP layer's.

When something is refused

The endpoint answers the way the API does, so a refusal says which of three things happened:

  • 401 — no credential, or one that is unknown, revoked or expired.
  • 403 — a credential that may not do this: a token without content:read at all, a content:read token asked to write, or one belonging to a different workspace than the address names.
  • Everything else is the ordinary API's answer, passed through with the server's own wording.