Yarnt Start free

Yarnt MCP Server

Let an agent work your tasks over the MCP tool-call protocol.

The Yarnt MCP server offers the same operations and permission model as the REST API. It uses MCP tool calls instead of JSON over HTTP. An MCP client, such as Claude, can list, create, and move tasks.

This page lists the tools. The /yarnt skill describes how an agent works its assigned tasks until none are left, then stops.

Server URL: https://mcp.getyarnt.com. Paste this origin into your client. Do not add a path.

Connecting

The transport is stateless streamable HTTP. A client sends a POST to the base URL for every call. The server has no SSE stream. A GET or DELETE to the URL returns 405.

Most clients need only the URL. They find the OAuth endpoints themselves. For Claude Code, run:

claude mcp add --transport http yarnt https://mcp.getyarnt.com

Other MCP clients take the same URL in their "add server" screen.

Authorizing

The first call opens a browser for a standard OAuth flow.

Why a robot

The agent does not hold your password or a service key. It holds a scoped, revocable token bound to the robot. It can see and do only what that robot's membership permits. Every call follows the same row-level security and limit rules as the app. The agent cannot change billing.

Tokens & revoking

Access tokens last 1 hour. Refresh tokens last 30 days. Each refresh issues a new refresh token and revokes the old one. Clients refresh automatically. To revoke access, disable the robot or revoke its refresh token.

Auth is OAuth 2.1 with PKCE (S256, required). The server supports Dynamic Client Registration, so clients register themselves.

Limits that apply to agents

The robots of a workspace share a number of tasks in flight: the plan's in-flight number for each human. That is 1 for each human on No Excuses and I Have a Reason, 2 on There's a Story, 3 on It's a Whole Thing, and 4 on This is Fine. Any robot can use any of it, so one busy robot can keep another from starting. When every place is taken, start_task does not start the task. The answer gives the number and the robots that hold the places. This is a limit, not a fault: do not try again until a robot task is finished or unstarted.

A robot's tasks in flight do not count against a human's number, and a human's do not count against the robots'. Robots are not paid seats and do not add to the workspace queue pool.

A plan allows a number of robots for each human in the workspace: 1 on No Excuses and I Have a Reason, 2 on There's a Story, 3 on It's a Whole Thing, and 4 on This is Fine. The robots are pooled across the workspace. A robot has one connection. When you approve an agent as a robot, the robot's other connection ends. The consent screen lists only the robots you made, so each person on a team connects their own. For the same reason, only the person who made a robot can make an API key for it. After a downgrade, or when a person leaves, the workspace can have more robots than its plan allows. Yarnt then keeps the most recently used robots and archives the rest. It disconnects their agents. To archive or restore a robot, go to Settings, Robots.

The workspace queue cap still applies to robots. An agent that creates tasks can hit a full queue. To make room, finish a task or drop a task.

Tools

Tools return plain text, not JSON. The exception is get_attachment, which returns an image when the attachment is an image. Assignee values are user ids (from list_users or whoami), not emails.

ToolParametersDoes
whoaminoneYour own id name (kind) plus the person who granted you access. Use it to find which list_users row is you.
list_taskslist opt (now / next / queue default / wishlist / finished / all), assignee opt (me / unassigned / user id), project optTasks in priority order. Each row shows its list.
get_taskid reqFull detail including the body/description.
create_tasktitle req, project opt, wish opt boolAdds the task to the next list. wish: true adds it to the wishlist instead and uses no queue slot.
update_taskid req, title opt, body opt, assignee opt/nullable, project opt/nullableEdit fields. Omit a field to leave it unchanged. Pass null to clear it. To move a task between lists, use start, finish, drop, or unstart.
start_taskid reqStart it.
finish_taskid reqFinish it.
drop_taskid reqDrop it.
unstart_taskid reqPut a started task back: state todo, top of Next, blocked and its reason cleared. An agent uses it to hand back work it cannot finish. Add a comment with the reason first, because unstarting clears it.
list_usersnoneMembers you can assign to: id name (kind). The kind is human or integration.
list_projectsincludeArchived opt boolProject names. Archived projects are left out by default.
add_commenttaskId req, body reqComment on a task.
list_commentstaskId reqComments, oldest first.
list_historytaskId reqChange history, oldest first.
list_attachmentstaskId reqFiles on a task, newest first: id name (size, type).
get_attachmentid req, as opt (auto default / link)Get one attachment. An image comes back as an image block. A text file comes back as its text. Any other file, or any file over 4 MB, comes back as a description and a download URL that is valid for one hour. as: "link" always returns only the URL.
add_attachmenttaskId req, name req, data req (base64), contentType optAttach a small file by value, such as a short log or diff that the agent writes itself.
drop_attachmentid reqRemove a file from a task, with its data. Use it to remove a mistaken upload. You cannot undo it.
start_uploadtaskId req, name req, contentType optStart to attach a file from disk. It returns a URL to PUT the bytes to, a handle, and the upload command to run. The type comes from contentType, or from the filename if you leave out contentType.
finish_uploadupload req (the handle)Attach the uploaded file. The size is read from the file that arrived. The type is the one declared at start_upload.

Attachments

A file the agent made goes up in two steps. Base64 of a real screenshot is hundreds of thousands of characters long, and a language model cannot output it exactly. One wrong character corrupts the file. So start_upload returns a signed URL, the agent's shell sends the bytes, and finish_upload records the result. The file does not pass through the model.

start_upload  → curl -X PUT -H "Content-Type: image/png" --upload-file shot.png "<url>"  → finish_upload

start_upload prints that command with the URL filled in. The header is part of the command. curl --upload-file declares application/octet-stream unless you set another type, and a screenshot with that type downloads instead of showing inline. So the type is set when the upload starts, from contentType or from the filename. finish_upload records that type, not the type the transfer declared.

The caps come from your plan. The web uploader enforces the same caps: file size, files per task, and total workspace storage. If a call goes over a cap, the error is a plain sentence that names the cap. drop_attachment removes a file that was attached by mistake, such as the wrong file or a duplicate.

Sample output

list_tasks:

1234abcd...  [now] Fix the flaky deploy step @Yarntbot
5678cdef...  [next] Write onboarding empty states (unassigned)

whoami:

abcd1234-...  Yarntbot (integration)
granted by: dcba4321-...  Ada

Questions about the MCP server: hello@getyarnt.com.