MCP server: let Claude and other agents participate in your retros

Looptro ships a Model Context Protocol server so Claude Code, Cursor, and custom agents can read, prep, and act on retrospectives as first-class participants.

Updated

Looptro ships a Model Context Protocol (MCP) server so AI agents (Claude Code, Cursor, or anything that speaks MCP) can read past retros, prepare new ones, and act on outcomes as first-class participants. Agents prepare the ground, surface patterns, and follow up on action items so humans spend their retro time on the conversation.

If you build a non-agent integration, use the REST API instead. MCP is the right surface for AI agents that need capability-scoped tool calls and an audit trail.

Can you connect an agent today?

Not yet, unless you are in the private beta. The MCP server is live and every tool on this page is real, but an MCP token belongs to one team, and Looptro creates teams only for private-beta accounts. The OAuth handshake starts and then stops at the consent page.

Check the state yourself:

  • POST https://app.looptro.dev/mcp answers 401 with a WWW-Authenticate header that points at the OAuth discovery document. The server runs.
  • GET https://app.looptro.dev/api/config answers {"waitlist_mode":true}.
  • POST /api/auth/signup and GET /api/teams answer 404. Looptro does not mount those routes while waitlist mode is on.
  • The consent routes that finish the handshake, and the endpoint that mints a personal access token by hand, sit behind the same gate.

So a developer cannot get a token today. Only a pre-seeded beta token reaches the tools. Add your email address to the waitlist and we tell you when team accounts open. The rest of this page documents the server as it runs now, so you know what you get.

Connect an agent in four steps

The steps below are the whole procedure. Step 3 needs a team account, so today it completes only for a private-beta team.

  1. Add the server. Point your client at https://app.looptro.dev/mcp. Install in your client gives the exact configuration for each one. The server speaks JSON-RPC 2.0 over HTTP POST on one endpoint.
  2. Let the client discover the authorization server. The first call to /mcp returns 401 with a WWW-Authenticate header that names /.well-known/oauth-protected-resource (RFC 9728). The client follows that document to the authorization server metadata (RFC 8414), registers itself (RFC 7591), and then runs browser PKCE (RFC 7636) or, with no browser, the device-code flow (RFC 8628).
  3. Approve the team and the scopes. The consent page asks which team the token belongs to and which scopes the agent may use. A headless agent prints a short code instead, and you approve it on another device. This step needs a team account.
  4. Check the connection. Run /mcp in Claude Code. looptro appears with the scopes you approved. Ask for a read first, such as “List our five most recent retros.”

A script that cannot run OAuth uses a personal access token instead. Mint one with POST /api/teams/{team_id}/agent-tokens, from a browser session on a team account, with the scopes the script needs. That endpoint sits behind the same private-beta gate, so this path is closed today too. The plaintext token comes back once in the wire form rtl_pat_<id>_<secret>. Send it as Authorization: Bearer <token> to /mcp. Both paths hash the secret with Argon2, write rows to the same table, and produce the same audit attribution.

Install in your client

Every client below reaches the same URL, https://app.looptro.dev/mcp. The server speaks streamable HTTP, so no client needs a proxy, an npm package, or a local binary. Each client reads the 401, registers itself, and opens a browser for the OAuth flow on the first call. Step 3 still needs a team account, so read Can you connect an agent today? before you start.

Claude Code

Add the server from the terminal:

claude mcp add --transport http looptro https://app.looptro.dev/mcp

To share the server with a repository, write .mcp.json instead:

{
  "mcpServers": {
    "looptro": {
      "type": "http",
      "url": "https://app.looptro.dev/mcp"
    }
  }
}

Run /mcp in Claude Code to start the login and to read the connection state.

Claude Desktop

Claude Desktop reaches a remote server through a connector, not through claude_desktop_config.json. That file starts local stdio servers, and Looptro has no local binary.

Open Customize, then Connectors, then Add custom connector, and paste https://app.looptro.dev/mcp. Leave the advanced OAuth fields empty, because the server registers the client for you. On a Team or Enterprise plan an owner adds the connector under Organization settings first, and each member then selects Connect. Claude reaches the server from Anthropic’s servers rather than from your machine.

Cursor

Write ~/.cursor/mcp.json for every project, or .cursor/mcp.json for one project:

{
  "mcpServers": {
    "looptro": {
      "url": "https://app.looptro.dev/mcp"
    }
  }
}

A remote entry carries a url and no command. Leave out the auth block, which Cursor uses only for a server that cannot register a client on its own. Once the server connects, its tools appear under Available Tools.

OpenAI Codex CLI

Add the server, then start the login:

codex mcp add looptro --url https://app.looptro.dev/mcp
codex mcp login looptro

Codex writes the server into ~/.codex/config.toml:

[mcp_servers.looptro]
url = "https://app.looptro.dev/mcp"

Run codex mcp list to read the auth state, or type /mcp in the Codex TUI.

OpenCode

Add the server to opencode.json with the remote type:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "looptro": {
      "type": "remote",
      "url": "https://app.looptro.dev/mcp",
      "enabled": true
    }
  }
}

OpenCode asks you to authenticate on the first tool call. Run opencode mcp auth looptro to start the login by hand, and opencode mcp list to read the state.

VS Code and GitHub Copilot

Write .vscode/mcp.json for one workspace, or run the MCP: Open User Configuration command to add the server to every workspace:

{
  "servers": {
    "looptro": {
      "type": "http",
      "url": "https://app.looptro.dev/mcp"
    }
  }
}

VS Code opens a browser for the OAuth flow on the first connection. Add no oauth block, which carries a client id that this server issues on its own. Run the MCP: List Servers command to read the server state.

Windsurf

Cascade reads ~/.codeium/windsurf/mcp_config.json. A remote server takes serverUrl in place of command:

{
  "mcpServers": {
    "looptro": {
      "serverUrl": "https://app.looptro.dev/mcp"
    }
  }
}

Open the MCP settings from the Cascade panel to see the server’s tools. This file belongs to the Cascade agent. Windsurf now ships as Devin Desktop, and its newer default agent reads the Devin CLI configuration instead.

Zed

Open Settings, then AI, then MCP Servers, and select Add Server, then Add Remote Server. Zed writes the entry into your settings file:

{
  "context_servers": {
    "looptro": {
      "url": "https://app.looptro.dev/mcp"
    }
  }
}

An entry with no Authorization header makes Zed run the standard MCP OAuth flow. The indicator dot beside the server name turns green when the server is active.

A script, or a client that is not listed

Any client that takes a server URL works the same way. Give it https://app.looptro.dev/mcp and let it run the handshake.

A script that cannot run OAuth sends a personal access token instead. The endpoint takes one JSON-RPC 2.0 request per POST and returns one JSON response:

curl -sS https://app.looptro.dev/mcp \
  -H "Authorization: Bearer rtl_pat_<id>_<secret>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Change the method to tools/call to run a tool:

curl -sS https://app.looptro.dev/mcp \
  -H "Authorization: Bearer rtl_pat_<id>_<secret>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_retros","arguments":{"limit":5}}}'

Drop the Authorization header to see the discovery header the OAuth clients follow. The server answers 401 and names /.well-known/oauth-protected-resource.

Verify the connection

A 401 means the token is wrong. Approve the agent again, or issue a new token. A 403 on one tool means the token does not carry that tool’s scope. The error names the scope, and the failed call still writes an audit row, so the team audit timeline tells you what to grant.

Prompts your team can run

These are prompts a person types to an agent that has the Looptro server connected. Each one names the tools it reaches and the scopes those tools need.

Find the theme that keeps coming back.

Read our last five Looptro retros and list every theme that appears in more than one of them. Quote the cards you based each theme on. Change nothing.

Calls list_retros and get_retro. Needs retros:read.

Chase the open action items.

List every Looptro action item that is still open. For each one, tell me which retro it came from and how many days it has been open.

Calls get_action_items and get_retro. Needs action_items:read and retros:read.

Prepare Friday’s board.

Create Friday’s retro in Looptro from our team template. Then add one card to the first column for each action item that is still open, so the team sees what carried forward.

Calls list_team_templates, create_retro, get_action_items, and add_post. Needs templates:read, retros:write, action_items:read, and posts:write.

Tidy the board before the discussion.

Open our current Looptro retro, group the cards that say the same thing, and give each group a short title. Do not delete anything.

Calls get_retro, group_posts, and rename_group. Needs retros:read and posts:write.

Draft the summary narrative.

Read the summary of our last Looptro retro and draft a two-sentence narrative for the top of it. Show me the draft, and write it back only when I say yes.

Calls get_summary and set_summary_narrative. Needs retros:read and retros:write.

Record what the team agreed.

For each thing we agreed in today’s Looptro retro, create an action item with an owner and a due date. Then mark the two items we finished last sprint as done.

Calls create_action_item and update_action_item. Needs action_items:write.

Ask whether the retros change anything.

How many of our Looptro action items closed in the last quarter, how long did they take, and how many carried over more than once?

Calls get_team_analytics. Needs action_items:read.

What an agent can read

Read tools never change a retro. A token that carries only the read scopes below can look at everything in this table and nothing else.

What the agent reads Tool Scope
The team’s retros, newest first list_retros retros:read
One retro with its columns, posts, votes, and action items get_retro retros:read
The retro summary as Markdown get_summary retros:read
The team’s action items, filtered by state or by date get_action_items action_items:read
The team’s curated retro templates list_team_templates templates:read
Action-item follow-through and carry-forward rates get_team_analytics action_items:read
Participation spread across the team get_team_analytics posts:read
Which parts of the retro flow the team reaches get_team_analytics retros:read
Exports a retro’s summary to the team’s connected Slack channel export_to_slack retros:read

get_retro returns the whole board in one call, so an agent reads posts and action items with retros:read alone. get_team_analytics gates each of its four surfaces on its own scope and names what it withheld, so a token cannot read action-item data on the strength of retros:read. Every number it returns is an aggregate. It never names a person.

export_to_slack needs only retros:read, but it still has a side effect: it posts a real message to the team’s Slack channel. It also needs the team to have connected Slack and picked a channel first; an agent cannot do that step on its own.

What an agent can change

Write tools change the team’s data. Grant these only when you want the agent to act.

What the agent changes Tool Scope
Creates a retro from a preset or a team template create_retro retros:write
Changes a retro’s title, state, phase, or timer settings update_retro_settings retros:write
Closes a retro close_retro retros:write
Writes or clears the summary narrative set_summary_narrative retros:write
Sets its own ready flag in the current phase set_ready retros:write
Adds a card to a column add_post posts:write
Edits the body of a card it wrote update_post posts:write
Casts or removes one vote on a card vote_on_post posts:write
Groups cards, ungroups them, or renames a group group_posts, ungroup_posts, rename_group posts:write
Creates an action item create_action_item action_items:write
Updates an action item’s state, owner, or due date update_action_item action_items:write
Sets or disables the team’s sprint cycle set_team_sprint_cycle templates:write
Promotes an action item into a Linear issue in the team’s mapped Linear team create_linear_issue retros:write

Write tools refuse a closed retro, except for action items, which stay editable after the retro closes. update_post and update_action_item also check ownership: the agent’s issuing user must be the author, the assignee, or a team admin. create_linear_issue also needs the team to have connected Linear and mapped a target team first.

How scopes work

A token carries any of eight scopes: retros:read, retros:write, posts:read, posts:write, action_items:read, action_items:write, templates:read, and templates:write. A write scope satisfies the matching read requirement, so retros:write alone lets an agent call get_retro.

A tool call that lacks its scope returns a forbidden error that names the scope, such as missing scope: posts:write. The agent gets a clear reason and no data.

Every tool call writes an audit row tagged actor_type='agent' with the token id, the issuing user, the team, and, when the call fails, the error code. Agent actions sit beside human actions in one audit timeline.

Transport

The server speaks MCP revisions 2026-07-28 and 2025-06-18 on a single POST /mcp endpoint, so a client on either revision connects without configuration. It implements server/discover, tools/list and tools/call over JSON-RPC 2.0, and initialize for clients on the older revision. Every tool descriptor carries a full JSON Schema for its arguments, so an agent reads the shape at run time instead of hardcoding it.

Tokens

OAuth-issued tokens and hand-minted personal access tokens share one table and one enforcement model:

  • Capability-scoped. The token carries only the scopes the user approved. A tool call that misses its scope returns a 403 that names the scope.
  • Team-scoped. One token, one team. An agent that works with two teams installs once per team. This keeps the audit trail clean.
  • Revocable. Revoke a token with DELETE /api/teams/{team_id}/agent-tokens/{token_id}, or from the token management page in team settings. Revocation takes effect at once.
  • Bounded expiry. Up to 365 days from creation. The manual path lets you set the exact expiry, so access lapses on its own.
  • Rate-limited. Stricter than a user session, and counted per token. An agent over the budget gets a 429 rather than a silent failure.

What the MCP server does not do

  • Run a retro without a human. Technically possible, and not the product position. Agents prepare and assist. They do not replace the team.
  • Carry more than one team. One token, one team. This keeps the audit model clean.
  • Stream partial tool results. The transport is request and response over HTTP POST. There is no SSE stream for tool output and no server-initiated notification yet.
  • Expose MCP resources or prompts. Tools only in v1. Read-only resources and canned prompt workflows are on the list after that.
  • Export JSON. get_summary takes a retro id and returns Markdown. Markdown is the only export format today.

Questions about the Looptro MCP server

How do I connect Claude Code to Looptro?

Run claude mcp add --transport http looptro https://app.looptro.dev/mcp in your terminal. Claude Code reads the 401 the server returns, follows the OAuth discovery documents, registers itself, and opens the consent page. On that page you pick the team and approve the scopes the agent asks for. The consent page needs a team account, and team accounts are still in private beta.

Do I need the mcp-remote proxy to connect to Looptro?

No. The Looptro MCP server speaks streamable HTTP on one POST endpoint, and the current coding agents reach that endpoint directly. There is no npm package, no stdio binary, and no container to run. Point the client at https://app.looptro.dev/mcp and let it run the OAuth handshake. A client that speaks only stdio cannot connect, because the server offers no stdio transport.

Can a developer get an MCP token today?

No, not outside the private beta. Looptro runs in waitlist mode, so the server answers 404 on signup, on team creation, and on the endpoint that mints a token by hand. An MCP token belongs to one team, and the consent routes that finish the OAuth handshake sit behind the same gate. The server itself is live: a POST to https://app.looptro.dev/mcp answers 401 with the OAuth discovery header. The handshake starts and then stops at the consent page.

What scopes does the Looptro MCP server use?

Eight: retros:read, retros:write, posts:read, posts:write, action_items:read, action_items:write, templates:read, and templates:write. A write scope also satisfies the matching read requirement, so a token with retros:write can call get_retro. One token carries up to 12 scope entries, and only the ones you approve.

What happens when a tool call is missing a scope?

The server refuses the call and returns a forbidden error that names the scope, for example "missing scope: posts:write". The agent gets a reason and no data. The refused call still writes an audit row, so the team audit timeline shows what the agent tried and which scope it needed. Approve the agent again with that scope to grant it.

Can an agent read another team's retros?

No. Every token binds to one team. A tool call that names a retro on another team returns not found rather than forbidden, so the token cannot even confirm that the other retro exists. An agent that works with two teams installs once per team and holds two tokens.

Does the MCP server expose resources or prompts?

No, tools only in v1. The server speaks MCP revisions 2026-07-28 and 2025-06-18 on one POST endpoint, so a client on either revision connects without configuration. It implements server/discover, tools/list and tools/call over JSON-RPC 2.0, plus initialize for clients on the older revision. It does not stream partial tool results and it sends no server-initiated notifications. Each tool descriptor carries a full JSON Schema for its arguments, so an agent reads the shape at run time.

How does an agent export a retro?

The get_summary tool returns the retro as Markdown. It is the same text the Summary tab puts on your clipboard: the title, the narrative, a meta line, the grouped cards ordered by vote count, and the action items as a checklist. The tool takes a retro id and nothing else, so Markdown is the only format. There is no JSON export.