Sayr

MCP Server

Connect an AI agent (Claude, ChatGPT, or any MCP-compatible client) to Sayr using the Model Context Protocol

Sayr runs a remote Model Context Protocol (MCP) server, so an AI agent can read and write tasks, comments, and more in your organization on your behalf, the same way the CLI or a personal access token does.

Early preview

MCP support is newly available. It's a Sayr Cloud feature — self-hosted instances don't expose an MCP server yet.

Setting it up

The server URL is:

https://api.sayr.io/mcp

Sayr's MCP server authenticates over OAuth, the same standard most modern MCP clients speak natively. Adding the URL is normally the whole setup: your client discovers the authorization server on its own, opens a browser for you to sign in, and shows a consent screen listing exactly which scopes the agent is requesting before anything connects. No API key to generate or paste in.

Protocol version

Sayr's server currently speaks only the newest MCP protocol revision (2026-07-28). Most actively maintained clients already support it or will very soon; if a client reports a connection or protocol-version error rather than prompting you to sign in, it likely hasn't caught up yet. The CLI and Public API cover the same ground in the meantime.

Where you paste the URL and what the menu is called varies by client. A few common ones:

Claude Code

claude mcp add --transport http sayr https://api.sayr.io/mcp

Then start a session and run /mcp to finish signing in.

Claude.ai / Claude Desktop

Configured in the app, not a file: Settings → Connectors → Add custom connector, then enter a name and the URL above. (Requires a paid Claude plan.)

ChatGPT

Also UI-only: Settings → Connectors → Advanced settings → Developer mode (turn it on) → Create connector, then enter a name, the URL, and set Authentication to OAuth. (Requires a ChatGPT Plus, Pro, Team, or Enterprise account.)

Cursor

.cursor/mcp.json in your project, or ~/.cursor/mcp.json globally:

.cursor/mcp.json
{
	"mcpServers": {
		"sayr": { "url": "https://api.sayr.io/mcp" }
	}
}

VS Code (GitHub Copilot)

.vscode/mcp.json — note the top-level key is servers, not mcpServers, and type is required here:

.vscode/mcp.json
{
	"servers": {
		"sayr": { "type": "http", "url": "https://api.sayr.io/mcp" }
	}
}

Other JSON-config clients

Most other clients follow Cursor's shape, a mcpServers object keyed by a name you choose:

{
	"mcpServers": {
		"sayr": { "url": "https://api.sayr.io/mcp" }
	}
}

A few (Windsurf, for one) use serverUrl instead of url — check your client's own docs if the connection doesn't show up after a restart.

YAML-based configs

If your tool or agent framework takes its MCP server list as YAML rather than JSON, the equivalent is usually:

mcpServers:
  sayr:
    url: https://api.sayr.io/mcp

Local-only (stdio) clients

If your client only supports local command-based servers, bridge it with mcp-remote:

{
	"mcpServers": {
		"sayr": { "command": "npx", "args": ["-y", "mcp-remote", "https://api.sayr.io/mcp"] }
	}
}

Whichever client you use, the first connection opens a browser for you to sign in and approve the requested scopes — nothing to generate or copy in beforehand.

What it can do today

Account

ToolWhat it doesScope needed
whoamiThe authenticated user this connection is acting asnone (just a valid connection)
list_organizationsOrganizations the user is a member ofnone (just a valid connection)

Tasks

ToolWhat it doesScope needed
list_tasksSearch and list tasks in an organizationtasks.read
get_taskFull detail for one task, by its number (e.g. 123) or idtasks.read
create_taskCreate a new task with a title, markdown description, status, prioritytasks.create
update_taskChange status, priority, title, description, category, release or visibilitytasks.changeStatus / tasks.changePriority / tasks.editAny, depending on the field
set_task_labelsReplace the labels on a taskcontent.manageLabels
set_task_assigneesReplace the assignees on a task (organization members only)tasks.assign

Comments

ToolWhat it doesScope needed
list_commentsList a task's comments, with reply countstasks.read
create_commentPost a public or internal comment on a tasktasks.comment
update_commentEdit a comment's content or visibilitytasks.comment for your own; moderation.manageComments for others'
delete_commentDelete a commenttasks.comment for your own; moderation.manageComments for others'

Releases

ToolWhat it doesScope needed
list_releasesList releases, optionally filtered by statustasks.read
get_releaseOne release by slug or id: description, lead, labels, linked pull requests, tasks and countstasks.read
create_releaseCreate a release with a name, slug, Markdown description, status and target datecontent.manageReleases
update_releaseChange a release's name, slug, description, status, dates, color, icon or leadcontent.manageReleases
publish_releaseMark a release as released and close every open task in itcontent.manageReleases
delete_releaseDelete a release (its tasks are unlinked, not deleted)content.manageReleases

To add a task to a release, use update_task with the release's slug or id as releaseId.

Release activity

ToolWhat it doesScope needed
list_release_status_updatesA release's status updates, newest first, with health and comment countstasks.read
create_release_status_updatePost a status update with a health rating (on track, at risk, off track)content.manageReleases
update_release_status_updateEdit a status update's content, health or visibilitycontent.manageReleases
delete_release_status_updateDelete a status update and its commentscontent.manageReleases
list_release_commentsA release's top-level comments, optionally just those on one status updatetasks.read
list_release_comment_repliesThe replies in one comment threadtasks.read
create_release_commentComment on a release or status update, or reply to a commenttasks.comment
update_release_commentEdit a release comment's content or visibilitytasks.comment for your own; moderation.manageComments for others'
delete_release_commentDelete a release comment and its repliestasks.comment for your own; moderation.manageComments for others'
add_release_labelAdd a label to a releasecontent.manageReleases
remove_release_labelRemove a label from a releasecontent.manageReleases
link_release_pull_requestLink a GitHub pull request by URL (the repository must be connected)content.manageReleases
unlink_release_pull_requestUnlink a pull request from a releasecontent.manageReleases

Organization reference

ToolWhat it doesScope needed
list_labelsLabels in an organization (for set_task_labels)tasks.read
create_labelCreate a label, or return the existing one with that namecontent.manageLabels
list_categoriesCategories in an organization (for update_task)tasks.read
list_membersMembers of an organization (for set_task_assignees)tasks.read

Every tool except whoami and list_organizations takes an org argument (an organization's slug or id), so one connection can act across every organization you belong to — the agent names which org each call targets. Descriptions and comments are written and returned as Markdown.

Permissions

MCP access reuses the exact same scope vocabulary and permission model as personal access tokens: during consent, you approve a specific set of scopes (tasks.read, tasks.create, tasks.comment, and so on), and from then on every call is checked twice — does the connection hold the scope, and do your teams in that organization currently allow it. A connection can never do more than you can yourself: if your team can't edit other people's tasks or manage labels, neither can your agent, even with every scope approved. Member, team, and billing management are never reachable this way, whatever scopes were granted.

Like the CLI, the MCP server applies these checks to every task — including ones you created or are assigned to. If your team doesn't grant tasks.editAny, an agent can still change status and priority (where allowed) but not a task's title or description.

If your role or teams change, that takes effect on the very next call — nothing is cached against the old permissions.

Disconnecting an app

Every app you've approved is listed under Settings → Connections → Connected apps, with when you connected it and how many permissions it holds. Revoke cuts it off immediately: its current access stops working on the next call, and it can't renew it. To use the app again, connect it and approve it from scratch.

Rate limits

Usage is rate-limited per organization, not capped by a monthly quota — there's no "ran out of AI actions" wall. The limit is higher on Pro:

PlanLimit
Free20 requests/minute per person, per organization
Pro120 requests/minute per person, per organization

The limit follows the plan of the organization each call targets, and every person and organization is metered independently: hitting the limit against one organization doesn't affect calls against another, and a teammate's agent doesn't use up yours.

On this page