Punchlist

Connect an agent to Punchlist

Punchlist runs an MCP server. An agent you connect reads each board's rules and moves cards through the same gate you do: when a card is missing something, the move is refused and the refusal names what is missing. A connection works in one workspace and acts for the person who allowed it.

The server

Every agent connects to the same address:

Server URL

https://punchlistio.com/mcp
  • MCP over streamable HTTP, answering POST requests with JSON.
  • Sign-in is OAuth 2.1. A client finds Punchlist's sign-in from the server's own metadata, registers itself (dynamic client registration) and uses PKCE, so there is nothing to paste. Only an owner of a workspace can allow a connection to it.
  • Each connection is rate-limited. Past the limit the server answers 429 with a Retry-After header, and nothing is written.
  • An agent connected before 10 October 2026 may use the server's older address on supabase.co. It keeps working, and nothing needs changing.

Claude (claude.ai and the desktop app)

  1. In Claude, open Settings, then Connectors.
  2. Choose Add custom connector, name it Punchlist and paste the server URL.
  3. Press Connect. Punchlist asks you to sign in and Allow; choose the workspace the connection is for.
  4. In a chat, turn the connector on and ask Claude to brief you on a board.

On a Claude Team or Enterprise plan, an owner of the Claude organization adds the connector first; then each person connects their own account.

Claude Code

Add the server

claude mcp add --transport http punchlist https://punchlistio.com/mcp
  1. Run the command above in your terminal.
  2. In Claude Code, type /mcp, pick punchlist and choose Authenticate.
  3. Your browser opens Punchlist: sign in, Allow, then go back to Claude Code.

Cursor

Add to Cursor

Or by hand, in ~/.cursor/mcp.json

{
  "mcpServers": {
    "punchlist": {
      "url": "https://punchlistio.com/mcp"
    }
  }
}
  1. Add the server with the button, or paste the snippet into mcp.json.
  2. In Cursor Settings, MCP, press Connect beside punchlist.
  3. Your browser opens Punchlist: sign in, Allow, then go back to Cursor.

Any other MCP client

A client that speaks MCP over streamable HTTP and supports OAuth only needs the server URL. It discovers the rest from two documents:

Protected resource metadata

https://punchlistio.com/.well-known/oauth-protected-resource/mcp

Authorization server metadata

https://pkytkidrvgydqsdnoabw.supabase.co/.well-known/oauth-authorization-server/auth/v1

A client that cannot sign in by OAuth uses a workspace token instead. An owner creates one in Punchlist under Rules, Connect an agent, Other agents. It is shown once; the client sends it on every request as Authorization: Bearer <token>. Codex, for example, reads it from an environment variable:

~/.codex/config.toml

[mcp_servers.punchlist]
url = "https://punchlistio.com/mcp"
bearer_token_env_var = "PUNCHLIST_MCP_TOKEN"

Shell

export PUNCHLIST_MCP_TOKEN="<your token>"

Every tool

This list is read from the same catalogue the server hands an agent, so it is always the current one. Each tool says whether it only reads or also writes; clients use those marks to decide which calls to confirm with you.

Reading the tool list…

What a refusal looks like

A card cannot move until it has what its board's gate asks for. When an agent asks for a move the card is not ready for, nothing changes, and the tool call comes back as a result marked as an error whose text names every missing requirement. Asking to move a card that has nothing filled in from new to done looks like this:

Reading the gate's wording…

It is an answer, not a crash. The agent reads it, fills in what it names (an effort, a criterion, a batch, a commit) and tries again, or tells you what only you can supply. The board's owner sees every refusal on the board, so an agent cannot quietly route around the gate.

CI from GitHub Actions

A board can wait for a green CI run before a batch ships, and show CI on every card. An owner declares the check in the board's Edit project, under CI check: the repository and the workflow file. Then one step goes at the end of that workflow's job.

No secret is stored anywhere. GitHub signs a short-lived token naming the repository, the commit, the workflow and the run, and Punchlist checks GitHub's signature. The token's audience, punchlist-ci:<workspace id>, names your workspace, so a run is recorded only on your boards; Edit project shows the step with yours filled in. The job needs permission to ask for the token:

Permissions

permissions:
  contents: read
  id-token: write

The step

      # Punchlist: report how this run ended. GitHub signs a short-lived token naming this repo, commit,
      # workflow and run; Punchlist checks GitHub's signature, so no secret is stored anywhere. The audience
      # names the workspace the run is recorded in.
      - name: Report to Punchlist
        if: always()
        continue-on-error: true
        env:
          CONCLUSION: ${{ job.status }}
          AUDIENCE: punchlist-ci:<workspace id>
        run: |
          token=$(curl -sSfG -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            --data-urlencode "audience=$AUDIENCE" "$ACTIONS_ID_TOKEN_REQUEST_URL" | jq -r .value)
          curl -sS -X POST https://pkytkidrvgydqsdnoabw.supabase.co/functions/v1/punchlist-ci-report \
            -H 'content-type: application/json' \
            --data "{\"id_token\":\"$token\",\"conclusion\":\"$CONCLUSION\"}" \
            -w '\nHTTP %{http_code}\n' || true

The check waits for the workflow's first report, so declaring it never holds up a ship before the workflow has run once. A failed or cancelled run is recorded too, and a report that cannot reach Punchlist never turns the run red.

Revoking an agent

  1. In Punchlist, open Rules and find Connect an agent. Under Connected, every OAuth connection and workspace token is listed with what it did in the last hour.
  2. Press Revoke beside it. Its next call is refused. Revoking your own OAuth connection also withdraws your consent, so the agent has to ask again to reconnect.

Revoke is how you disconnect an agent. Signing out of Punchlist does not disconnect one.

You can also remove the connector in the agent itself; in Claude that is Settings, Connectors.

Try it on a sample board

In Settings, an owner can load a sample board into a workspace: Harborline, an invented ferry-booking app with cards in every column, a batch in progress, and one card that is missing everything the gate asks for. Settings then shows what to ask your agent, such as a briefing on the board, and moving that card to done to watch it be refused.

On the Free plan the sample is the workspace's one project; archive it to make room for your own.

Your data and support

  • A connection reads and writes only the boards in the workspace it was allowed for, with the access of the person who allowed it.
  • Each request is recorded (the time, the tool, and whether it was allowed or refused) and the records are kept 30 days. An agent's changes appear in the board's history under its name.
  • Punchlist does not use your boards to train AI models.

The privacy policy and the terms say the rest. Questions and help: punchlistio.com/support. Punchlist is made by DENT Studios.

Start free