MCP
The Pealboard MCP server lets an assistant search, read and change issues and
portal requests with your own permissions. It is a stateless Worker at
https://mcp.pealboard.com/mcp: POST only, no session, no SSE transport.
Every call forwards your API key to /v1 and the server holds nothing —
authorization is the API’s, applied the same way it is to any other caller.
What you need
Section titled “What you need”The endpoint, https://mcp.pealboard.com/mcp, and a Pealboard API key —
create one at Settings → API keys (see
API keys). A key acts with the role of the member who
issued it, narrowed by whatever scopes it was given. If the key’s owner
belongs to more than one workspace, send X-Workspace-Id; with one
membership it is filled in for you.
Claude Code
Section titled “Claude Code”claude mcp add --transport http pealboard https://mcp.pealboard.com/mcp \ --header "Authorization: Bearer pb_your_key"Claude Desktop and claude.ai
Section titled “Claude Desktop and claude.ai”Settings → Connectors → Add custom connector, with the URL
https://mcp.pealboard.com/mcp. Sending a bearer header this way needs
Anthropic’s static_headers option, which is a limited beta today; until
your organization has it, use Claude Code or Cursor instead. OAuth 2.1 is
planned for this server (below) and is what will make the custom connector
work for every claude.ai organization, not only ones in the beta.
Cursor
Section titled “Cursor”In ~/.cursor/mcp.json, or the project’s .cursor/mcp.json:
{ "mcpServers": { "pealboard": { "url": "https://mcp.pealboard.com/mcp", "headers": { "Authorization": "Bearer ${env:PEALBOARD_API_KEY}" } } }}VS Code
Section titled “VS Code”{ "servers": { "pealboard": { "type": "http", "url": "https://mcp.pealboard.com/mcp", "headers": { "Authorization": "Bearer ${input:pealboard-key}" } } }}ChatGPT
Section titled “ChatGPT”Not yet. ChatGPT’s connectors authenticate with OAuth or not at all — it cannot send a bearer API key as a header. Pealboard’s MCP server accepts only an API key today, so there is no way to connect ChatGPT to it until the OAuth plan below ships.
A client with no remote support
Section titled “A client with no remote support”Bridge it with mcp-remote. Every client above speaks remote HTTP itself, so
this is a fallback for one that does not:
{ "mcpServers": { "pealboard": { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.pealboard.com/mcp", "--header", "Authorization: Bearer pb_your_key" ] } }}Rate limit
Section titled “Rate limit”120 requests a minute, per API key. Exceeding it answers 429 with
Retry-After: 60.
The tools
Section titled “The tools”Every tool’s input schema is the API’s own field names — a filter, a field or
a value that works in a curl call to /v1 works unchanged from a tool
call. Grouped as the server groups them:
Issues
| Tool | Does |
|---|---|
search_issues |
Search and filter issues across every connected repository, from the cache. Paged. |
get_issue |
One issue in full, with its comments and the portal requests that point at it. |
create_issue |
Create an issue in GitHub and cache it. |
update_issue |
Change an issue’s title, body, labels, assignees, milestone or state. labels and assignees replace the whole set. |
comment_on_issue |
Post a comment. visibility: "internal" (the default) is never seen by a customer; visibility: "public" with a portalId is. |
Projects
| Tool | Does |
|---|---|
list_projects |
Every synced GitHub Project, its fields, and their options. |
set_project_field |
Set one field on one issue’s card, by field name and value name. Adds the issue to the project first if needed. |
move_issue_to_column |
set_project_field with the field fixed to the board’s status field — what dragging a card does. |
Views
| Tool | Does |
|---|---|
list_views |
The workspace’s shared views and the calling credential’s own personal ones. |
run_view |
The issues a saved view selects, paged. @me in its filter resolves to the caller. |
Portals
| Tool | Does |
|---|---|
list_portals |
Every portal in the workspace, with its address, access mode and counts. |
list_portal_requests |
Requests on one portal, filterable by status, company, request type and visibility; held: true returns the hold queue. |
reply_to_portal_request |
Post a reply the requester can see. Refuses a held request — release it first. |
release_request |
Accept a held request: create its GitHub issue, apply the request type’s labels and project, email the requester. |
reject_request |
Refuse a held request. Nothing is written to GitHub and the requester is not emailed. |
Workspace
| Tool | Does |
|---|---|
whoami |
The workspace this connection acts in, the member it acts as, and the key’s scopes. |
list_repositories |
Every repository the GitHub installation can see, and whether Pealboard mirrors it. |
sync_status |
The most recent sync jobs and the installation’s GitHub request budget. |
Two resources — pealboard://views and pealboard://portals — expose the
same lists as attachable context rather than a call the model makes on its
own. Two prompts, triage_new_requests and weekly_summary, walk a portal’s
hold queue and summarize a window of activity, each naming which tools to
call and in what order.
Auth today, and the OAuth plan
Section titled “Auth today, and the OAuth plan”v1 accepts one credential: Authorization: Bearer pb_.... There is no
session and no OAuth flow. Two checks happen before a tool ever runs, and
they answer different questions:
- Every request: the key looks like a Pealboard key — begins
pb_, long enough. A missing or malformed one is401withWWW-Authenticatenaming where to make one, and the connection never reaches the handler. - Once, on connect: the server calls
GET /v1/meto confirm the key is still live. A revoked or expired key is also401here, rather than connecting cleanly and failing on the first tool call — which would look like a broken server rather than a bad key.
What the key may do, and which workspace it belongs to, are answered only by the API, on each tool call. There is no second copy of scopes or roles here.
The server already publishes RFC 9728 Protected Resource Metadata at
/.well-known/oauth-protected-resource, because a client that speaks OAuth
discovery probes for it before trying a request, and a 404 there would make
a working API key look like a broken server. It says plainly that only a
bearer key is supported today; it does not yet list an authorization server.
OAuth 2.1 with PKCE is planned on the same /mcp endpoint — when it ships,
API keys keep working exactly as they do now, verified before a request is
handed to the OAuth provider, so nothing already configured breaks.