Offhand

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_review and blocked no 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 with list_todos and handedBy "me". An agent that looked for answers only under assignedTo "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_status in_progress, hand it to another agent with assignTo, or say done.
  • With offhand:report, any agent can say done on a task named for another agent.

Tools

  • assignTo on a task nobody is named on takes it and hands it on in one call. assignTo naming the caller is read as left out instead of refused.

Instructions

  • A task the caller handed out, at need_review or blocked, is that agent's answer: done closes it, and assignTo with 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.google is accepted as a redirect host.

Events

  • need_review or blocked from the agent holding a task wakes the agent that added it, through its webhook, its Claude routine or its task.assigned subscription. On that subscription the payload carries status, and assignedTo says who holds the task.

Server

  • serverInfo reports 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: refused says why, for example "101 bytes arrived; it was named with 89", and refusedAt says when. It stays until the bytes arrive or the file is declared again in files.
  • The upload's error says how many bytes arrived. When all the bytes arrived and were not kept, the answer is 503 with not_kept, where it was 400 with wrong_size.

0.6.2

An agent's own repeating task is taken one day at a time.

Tools

  • add_task with assignTo "me" and repeats no longer sets the task to in_progress at 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_status done ticks 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.
  • done on 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 instructions and set_task_status's description say that done ticks 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 agent argument 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-2 or me-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.assigned subscription. 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 instructions and the descriptions of add_task and set_task_status say what each call and each listing does, and what done, need_review and blocked mean 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 to offhandapp.com/device with a code that lasts 10 minutes, and asks /oauth/token every 5 seconds until the person allows it. The metadata names device_authorization_endpoint. A client registered for link sign-in cannot use /authorize.
  • /mcp takes an API key, Authorization: Bearer ofk_…, made on Muse's step of offhandapp.com/account/connect. An unknown key answers 401 with invalid_token.

0.5.0

blocked hands a task back, and handedBy follows the agent that added the task.

Breaking

  • blocked on a task another agent handed the caller hands it back to the agent in assignedBy, as need_review does.
  • list_todos with handedBy "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's task takes several ids, separated by commas.
  • add_task's answer names the id to follow the task by.

Instructions

  • The server's instructions say that on a handed task, done is for finished work, need_review is for work the agent in assignedBy asked to see, and blocked says what is missing. add_task's description says that a wish to see the work first goes in the request.

Sign-in

  • POST /token and POST /register at the server's origin, MCP's default paths for a client that reads no metadata, reach /oauth/token and /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_task and set_task_status refuse an argument they do not take, and write nothing. The answer lists the arguments they take, and their input schemas say additionalProperties: 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/unsubscribe needs offhand:read and removes only the calling connection's own subscription. events/subscribe refuses a callback that another connection holds.

Tools

  • When add_task or set_task_status hands 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.
  • done that 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 -32000 with data.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_review and blocked are refused without a note.
  • The agent argument 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 with set_task_status.
  • list_todos with handedBy "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 its assignedTo "me".

Instructions

  • The server's instructions say 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

  • assignTo on add_task and set_task_status must 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_progress is refused on a task that is another agent's.
  • need_review on a task another agent handed the caller hands it back to the agent in assignedBy.
  • set_task_status's note is 2,000 characters at most.

Tools

  • set_task_status is marked destructiveHint: true, and the read tools say destructiveHint: false. Every tool's annotations carry a title.
  • add_task's description is the same for every account. Instead, list_todos without since or task answers agents, the names assignTo takes.
  • 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 instructions say that a task handed back is the other agent's answer: close it with done, or hand it back with assignTo. A task that waits on the person is blocked.

Sign-in

  • Two clients that register with the same client_name within 10 minutes of each other go by name and name-2.

Files

  • A file declared again in files before 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:read lists tasks and subscribes to events. offhand:report adds tasks and says where a task stands. The person can untick either one.

Tools

  • list_todos lists the person's tasks, by status, by words (query), by assignedTo ("me", a name, or "none"), by handedBy "me", or one task. With since, the cursor the last listing answered, it lists only what changed after it. Without since it answers check, which says how to check for work.
  • add_task adds a task to the person's list, signed with the agent's name. With assignTo it hands the task to another agent.
  • set_task_status says where a task stands, with a note: proposed, in_progress, blocked, need_review or done. in_progress takes a task and is refused while another agent works on it. done is accepted only on a task another agent handed the caller. With assignTo it 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 at initialize, say how an agent checks for its work: list_todos with assignedTo "me" and since, in_progress to take a task, then done or blocked.

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 with events/subscribe.
  • A webhook the person gives an agent on the account page starts that agent when a task is handed to it.

Files

  • add_task and set_task_status take files and answer an upload link for each. list_todos gives each file a download link that works for 10 minutes. A file is 25 MB at most, and a task holds 10.

Server

  • serverInfo names the server offhand, titled Offhand, with a description, the website and an icon.