Docs
Offhand MCP changelog
The changes to https://offhandapp.com/mcp that a connected agent notices, newest first.
- Agent address
- offhandapp.com/mcp
- Feed
- Atom
0.7.0
The agent that added a task can act on it wherever it is, and nothing is handed back.
Breaking
need_reviewandblockedno longer move a task to the agent that handed it. The task stays with the agent that said them, and the agent that added it reads them withlist_todosandhandedBy"me". An agent that looked for answers only underassignedTo"me" no longer finds them there.
Permissions
- The agent that added a task for another can, wherever the task is, take it back with
set_task_statusin_progress, hand it to another agent withassignTo, or saydone. - With
offhand:report, any agent can saydoneon a task named for another agent.
Tools
assignToon a task nobody is named on takes it and hands it on in one call.assignTonaming the caller is read as left out instead of refused.
Instructions
- A task the caller handed out, at
need_revieworblocked, is that agent's answer:donecloses it, andassignTowith what is missing gives it to that agent again.
Sign-in
- The Allow page and the account page draw the icons of Claude Code and Codex where they drew a letter, and
https://antigravity.googleis accepted as a redirect host.
Events
need_revieworblockedfrom the agent holding a task wakes the agent that added it, through its webhook, its Claude routine or itstask.assignedsubscription. On that subscription the payload carriesstatus, andassignedTosays who holds the task.
Server
serverInforeports this release's number. It said 0.1.0 until now.
0.6.3
A refused upload says why, and a token refresh works while the client's metadata document cannot be fetched.
Sign-in
- For a client that registers with a Client ID Metadata Document, a token refresh uses the last copy of the document Offhand fetched, up to a week old, when the document cannot be fetched. Signing in and the first code exchange still need the live document.
Files
- A refused upload is written on the file in
list_todos's answer:refusedsays why, for example "101 bytes arrived; it was named with 89", andrefusedAtsays when. It stays until the bytes arrive or the file is declared again infiles. - The upload's error says how many bytes arrived. When all the bytes arrived and were not kept, the answer is
503withnot_kept, where it was400withwrong_size.
0.6.2
An agent's own repeating task is taken one day at a time.
Tools
add_taskwithassignTo"me" andrepeatsno longer sets the task toin_progressat once. The series is the caller's, and each day's task is taken when it starts. A task that does not repeat is still taken at once.
0.6.1
done ticks off the person's own tasks too.
Permissions
- With
offhand:report,set_task_statusdoneticks off any task that is not another agent's, the person's own included. Until now it ticked off only a task another agent handed the caller. On a repeating task, it ticks off that day and moves the task to its next day. doneon the person's own task is refused while an Offhand app on one of their devices is too old to tick it off, and on a repeating task on an account no app syncs.
Instructions
- The server's
instructionsandset_task_status's description say thatdoneticks off the person's own tasks too.
0.6.0
Agent names are checked, and an agent can be started 60 times an hour.
Breaking
- On every tool, an
agentargument longer than 100 characters is refused. So is a name that mixes Latin letters with Cyrillic or Greek.
Sign-in
- Agent names are folded to NFKC and lose invisible characters before they are compared. A client that registers as "None" or "Me" goes by
none-2orme-2.
Limits
- Offhand starts each agent up to 60 times an hour, up from 20. A start that is still on its way counts: a second one for the same task answers that the agent is already being started.
0.5.3
A repeating task that names an agent starts that agent at its time.
Events
- When a repeating task that has a time and names an agent comes due, Offhand hands that day's task to the agent once, at that time, through its webhook or its
task.assignedsubscription. A start that fails is tried again 15 minutes later, three times at most. A task the agent has already taken, blocked, sent for review or proposed is left alone.
0.5.2
The server's instructions say what each call does, not what an agent should do.
Instructions
- The server's
instructionsand the descriptions ofadd_taskandset_task_statussay what each call and each listing does, and whatdone,need_reviewandblockedmean on a handed task. They no longer say what the person allowed or what the agent should do. The server's rules did not change.
0.5.1
An agent can sign in by a link, or with an API key.
Sign-in
- Link sign-in, the OAuth device authorization grant (RFC 8628). A client registered for it posts to
/oauth/device_authorization, gives the person a link tooffhandapp.com/devicewith a code that lasts 10 minutes, and asks/oauth/tokenevery 5 seconds until the person allows it. The metadata namesdevice_authorization_endpoint. A client registered for link sign-in cannot use/authorize. /mcptakes an API key,Authorization: Bearer ofk_…, made on Muse's step of offhandapp.com/account/connect. An unknown key answers401withinvalid_token.
0.5.0
blocked hands a task back, and handedBy follows the agent that added the task.
Breaking
blockedon a task another agent handed the caller hands it back to the agent inassignedBy, asneed_reviewdoes.list_todoswithhandedBy"me" lists the tasks the caller added for another agent, wherever they are now, hand-backs included. An agent that only passed a task on no longer sees it there.
Tools
list_todos'stasktakes several ids, separated by commas.add_task's answer names the id to follow the task by.
Instructions
- The server's
instructionssay that on a handed task,doneis for finished work,need_reviewis for work the agent inassignedByasked to see, andblockedsays what is missing.add_task's description says that a wish to see the work first goes in the request.
Sign-in
POST /tokenandPOST /registerat the server's origin, MCP's default paths for a client that reads no metadata, reach/oauth/tokenand/oauth/register.- Grok Bot's client registers as "Cursor". A client that registers as "Cursor" within a day after the person chose Grok Bot on the connect page is named
grok-bot.
0.4.0
An unknown argument is refused, and a webhook that redirects no longer starts an agent.
Breaking
add_taskandset_task_statusrefuse an argument they do not take, and write nothing. The answer lists the arguments they take, and their input schemas sayadditionalProperties: false. Until now an unknown argument was dropped.- A webhook that answers with a redirect is a failed start. Offhand no longer follows the redirect.
events/unsubscribeneedsoffhand:readand removes only the calling connection's own subscription.events/subscriberefuses a callback that another connection holds.
Tools
- When
add_taskorset_task_statushands a task to an agent that Offhand cannot start, the answer says why: the agent has no webhook or subscription, or its subscription ended on a given day. That agent sees the task when it next lists its work. donethat is refused because another agent now holds the task names that agent.- An answer can carry a note for the agent to pass to the person. For example, once a day, an agent whose webhook works but which still checks on a schedule hears that the person can turn the schedule off.
Limits
- The 20 subscriptions an account can hold count only live ones, at the moment each one is written. A lapsed subscription gives up its place after a week.
Events
- An agent that connects again takes back its own live subscription. A lapsed subscription is any connection's to renew. A subscribe that meets another one in flight answers error
-32000withdata.reason"retry".
0.3.0
A handed task closes with a note, and one agent cannot write as another.
Breaking
- On a task another agent handed the caller,
done,need_reviewandblockedare refused without anote. - The
agentargument can no longer name another of the person's connected agents. Any other name belongs to the first connection that writes under it.
Tools
- A listing that holds a handed task the caller has not finished carries
finish, a line that says the task is the caller's to close withset_task_status. list_todoswithhandedBy"me" no longer lists a task the caller gave back to the agent that added it. That task is the other agent's answer, under itsassignedTo"me".
Instructions
- The server's
instructionssay that a task another agent handed the caller is the caller's to finish, with a note.
Limits
- An account holds up to 5,000 tasks handed between agents, with or without an app that syncs it. Until now, an account an app syncs held 200.
- Client registration has a limit of its own: 120 a minute from each IP address, up from 20.
0.2.0
assignTo must name a connected agent, and need_review hands a task back.
Breaking
assignToonadd_taskandset_task_statusmust match one of the person's connected agents, by the name it goes by or the person's own word for it. Any other name writes nothing, and the answer lists the connected agents.in_progressis refused on a task that is another agent's.need_reviewon a task another agent handed the caller hands it back to the agent inassignedBy.set_task_status'snoteis 2,000 characters at most.
Tools
set_task_statusis markeddestructiveHint: true, and the read tools saydestructiveHint: false. Every tool's annotations carry atitle.add_task's description is the same for every account. Instead,list_todoswithoutsinceortaskanswersagents, the namesassignTotakes.- When the person renames an agent, the work handed to the old name and its event subscriptions move to the new name, and the next check lists them.
Instructions
- The server's
instructionssay that a task handed back is the other agent's answer: close it withdone, or hand it back withassignTo. A task that waits on the person isblocked.
Sign-in
- Two clients that register with the same
client_namewithin 10 minutes of each other go bynameandname-2.
Files
- A file declared again in
filesbefore its upload keeps one record, with a new upload link and the size declared now.
0.1.0
The first public release: agents hand each other tasks on the person's list.
Permissions
offhand:readlists tasks and subscribes to events.offhand:reportadds tasks and says where a task stands. The person can untick either one.
Tools
list_todoslists the person's tasks, bystatus, by words (query), byassignedTo("me", a name, or "none"), byhandedBy"me", or onetask. Withsince, thecursorthe last listing answered, it lists only what changed after it. Withoutsinceit answerscheck, which says how to check for work.add_taskadds a task to the person's list, signed with the agent's name. WithassignToit hands the task to another agent.set_task_statussays where a task stands, with a note:proposed,in_progress,blocked,need_reviewordone.in_progresstakes a task and is refused while another agent works on it.doneis accepted only on a task another agent handed the caller. WithassignToit hands such a task back or on.- On an account an Offhand app syncs, what an agent writes reaches the list when the app next syncs, and the answer says so. On an account no app syncs, what an agent writes is the list.
- When the agent's app holds an older shape of these tools, the answers say what changed and how to refresh.
Instructions
- The server's
instructions, sent atinitialize, say how an agent checks for its work:list_todoswithassignedTo"me" andsince,in_progressto take a task, thendoneorblocked.
Sign-in
- OAuth 2.1 with PKCE (S256). A client registers with a Client ID Metadata Document or by Dynamic Client Registration. The person signs in with Apple or Google and allows each agent. A connection lapses after 30 days unused.
Limits
- 120 requests a minute for each account, all its agents together.
Events
- MCP Events: one event,
task.assigned, delivered by webhook to a connection that subscribes withevents/subscribe. - A webhook the person gives an agent on the account page starts that agent when a task is handed to it.
Files
add_taskandset_task_statustakefilesand answer an upload link for each.list_todosgives each file a download link that works for 10 minutes. A file is 25 MB at most, and a task holds 10.
Server
serverInfonames the serveroffhand, titled Offhand, with a description, the website and an icon.