AI Task Management Blog for Solo Founders and Small Teams

AI agent task management: the claim loop as a contract, not a prompt

How to manage AI agent tasks with a claim loop the server enforces: leases, heartbeats, questions, receipts and a limit on human attention.

Weft is the AI task manager for solo founders and small teams.

All articles

By Andrei Finogeev ·

AI agent task management works when the board, not the prompt, owns the loop: the agent asks what to do, claims one task with a lease that expires if it goes quiet, asks the person only for decisions that are theirs, and finishes with a receipt someone can check. In Weft each of those steps is an MCP tool the server checks, so an agent that skips a step gets refused or loses the task instead of quietly drifting out of sync.

We make Weft. Facts about other products come from their official pages, checked on 27 October 2026.

Why does a task list pasted into the chat stop working?

Pasting tasks into a chat is the first thing everyone tries, and it works for an afternoon. Then the chat ends, and the state ends with it. The agent knew which item it had finished, which one it gave up on and what it was unsure about. Now nobody does.

The person who pasted the list becomes the relay, copying results back to the real board and redoing work a second session picked up because nothing said it was taken.

Board access fixes the snapshot problem, not the rest. If the only tools are “move card” and “add comment”, the loop still depends on the agent following a convention written in its instructions. Conventions break exactly when things go wrong: the agent crashes mid-run, or two agents start at the same moment.

What does the claim loop look like as a contract?

In Weft the loop has five steps, and each one is a separate tool on one MCP endpoint, https://letsweft.com/api/mcp. The server keeps the state between them, so the loop survives the end of any chat.

  1. get_my_work: ask before choosing. The answer covers what this client already holds, what is waiting on the person, what is overdue or due soon, and whether there is room to start anything at all.
  2. start_task: claim with a lease. The claim lasts 20 minutes and moves the task to Doing. The response carries a runId, a leaseToken and renewEverySeconds: 300. A second client trying the same task gets already_claimed and a hint not to duplicate the work.
  3. report_progress: the heartbeat. Each call with the run id and lease token renews the lease. If the agent dies, the heartbeats stop, and 20 minutes later the run is marked stale and the task goes back to unassigned for anyone to pick up. A lost lease answers lease_lost, so the agent knows it no longer owns the work.
  4. request_input: only for decisions that are the person’s. A question of up to 500 characters, with up to 10 options. The claim is kept while the agent waits.
  5. complete_task: finish with a receipt. outcome, artifacts (evidence such as a URL, a commit or a file hash), notDone, unknowns and nextStep.

Why a lease and not a status? Because silence is the only signal a crashed agent can send. A card in Doing says someone was working on it once. A lease says someone is working on it now, and stops saying so on its own when that is no longer true.

The claim itself is a single database insert guarded by a unique index. When two agents race, the database decides who wins, so both cannot get the task. Two “Claimed” comments posted a second apart, by contrast, are both valid comments.

When should the agent call request_input?

When it reaches something only the person can decide: anything irreversible such as money, publishing, production or legal, or a real fork with no reasonable default. Not to ask permission to keep going.

That restraint matters because a question costs the person the same attention a finished task does, and in Weft it counts toward the same limit. The question lands in the Inbox, with a mobile push and, for items waiting 20 minutes or more, an email nudge. Weft never calls the agent back: the answer arrives at its next start_task or get_my_work. While the question is open the agent keeps the task for 60 minutes; after that the lease drops but the question stays.

What goes into a complete_task call?

A short outcome, evidence, and an honest account of the edges. Here is a realistic payload for a bug fix:

{
  "id": "9b2f6c1e-4d7a-4c3b-8e21-5a0f3d9c7b14",
  "runId": "d41e8a90-2f6b-4e17-9c3a-71b5e0a4c8f2",
  "leaseToken": "lt_3f9a…",
  "outcome": "Fixed the 500 on /api/invoices when the customer has no billing address. Fix is in PR #418; the route now returns 422 with a field error.",
  "artifacts": [
    { "kind": "url", "uri": "https://github.com/acme/app/pull/418" },
    { "kind": "commit", "uri": "a1c9e07" },
    { "kind": "url", "uri": "https://preview-418.acme.dev/api/invoices/health", "httpStatus": 200 }
  ],
  "claims": [
    "Added a test for an empty billing address; the invoices test file passes locally"
  ],
  "notDone": [
    "Did not merge the PR",
    "Did not backfill the 14 invoices that failed last week"
  ],
  "unknowns": [
    "Whether the mobile app shows the 422 message or a generic error"
  ],
  "nextStep": "Merge PR #418 to main"
}

Artifacts are things the person can check without taking the agent’s word for it. notDone and unknowns are not confessions; they separate a result you can rely on from one you rebuild from the diff. The call never fails for missing evidence, because losing finished work is worse than recording it unverified. More on reading these receipts in what did my AI agent do.

How is this different from moving a card and posting a comment?

Hypertask’s guide to the same loop (claim, update, report, close) is a good description of the habit. Its MCP version of a claim is loading the task, moving it to the working section and posting a claim comment, guided by a prompt the team writes into the agent’s instructions. Here is the same loop step by step:

Loop stepConvention-only board (the agent moves a card and comments)What Weft enforces, and with which MCP tool
Pick workThe agent lists tasks and chooses. Nothing tells it the person is already buried in reviews.get_my_work returns what this client already holds, what waits on the person, what is overdue, and whether there is room to start anything.
ClaimMove the card to Doing and post “Claimed.” Two agents can do this at the same moment and both believe they own it.start_task takes a 20-minute lease in one database write guarded by a unique index. The loser gets already_claimed with the task id and title.
Stay aliveProgress comments, if the agent remembers. A crashed agent leaves a card in Doing indefinitely.report_progress renews the lease (the agent is told to do it every 5 minutes). After 20 silent minutes the run is marked stale and the task is free again.
AskA “Blocked:” comment. The agent stops or guesses; the card may still look in progress.request_input puts a question with up to 10 options in the person’s Inbox and keeps the claim (60 minutes while parked). The answer comes back through start_task or get_my_work.
ReportA free-text final comment. Its shape depends on how good the prompt was.complete_task takes named fields: outcome, artifacts, notDone, unknowns, nextStep.
Close or reviewThe agent moves the card to Review or Done, whichever the prompt said.By default the task goes to Done. It stops in the Inbox for Accept / Rework / Later / Drop when the task needs review or a verification check fails.
OverloadNothing. Agents keep starting work and the Review column grows.start_task refuses with attention_queue_full once 5 items (one person) or 10 (team) wait on people, or 45 minutes of review.

To be fair to Hypertask: it does have real leases. Its documentation lists lease claim, heartbeat and release endpoints, and its Known limitations table says task leases, evidence and escalation are REST endpoints only, by design (Hypertask MCP overview). Its tools reference has no lease tool among its 21 MCP tools (tools reference). Its CLI can claim too, as an optional command (changelog, CLI reference). So a scripted agent on Hypertask can hold a lease; an agent working through MCP in Claude Code or Cursor gets the card-and-comment version unless someone wires the REST calls in.

If your agents run as scripts and CI jobs, Hypertask’s CLI and REST API are a real advantage, and Weft has neither: no CLI, no public REST API, no webhooks. Weft is for agents that live inside an MCP client and need the loop to hold there.

What does the person see?

Most of the time, a card in Done: by default a completed task goes straight there with its outcome and evidence attached.

A task stops in the person’s Inbox when it was marked as needing review, or when a verification check fails. There the person picks one of four answers:

  • Accept: the work stands. If the agent passed a nextStep, the person sees it above the button (“If you accept, the agent will …”), and accepting approves exactly that step, nothing broader. The approval is good for 72 hours and returns to the agent through get_my_work or start_task.
  • Rework: send it back, with a note saying what is wrong.
  • Later: not now. Drop: stop working on it.

The Inbox is on the web, and when something enters it the person also gets a push on the Weft mobile app. The nextStep handshake keeps an agent from treating “looks fine” as permission to merge, deploy and send: it may do the one approved step, then complete the task again.

Why does the agent get refused instead of starting more work?

Because attention, not work, is the scarce resource. An agent can start ten things in the time a person reviews one.

Weft counts what is waiting on people: tasks waiting for review plus open questions. When that reaches 5 items in a one-person workspace, 10 in a team, or about 45 minutes of estimated review time, whichever comes first, start_task refuses with attention_queue_full. The limit depends on how many people are in the workspace, not on the plan.

The refusal is an instruction, not a dead end. It reports the queue size, the age of the oldest item and the calls still allowed: report_progress, get_my_work, get_board_state and search. A step the person already approved on that card is exempt, so an accepted “merge PR #418” is not blocked by the queue.

How do I set this up?

Connect your client and sign in through the browser; there is no key to copy. Weft issues refresh tokens, so the client renews the sign-in itself. In Claude Code it is one command, claude mcp add --transport http weft https://letsweft.com/api/mcp (setup page). Cursor has a one-click install (Cursor), Codex needs a config entry and codex mcp login weft (Codex), and ChatGPT has a published Weft app on every plan including Free (ChatGPT). The server describes the loop to the agent itself, so no lifecycle prompt is needed.

For a Claude Code walkthrough see a task board for Claude Code. For several agents on one board, where leases and already_claimed matter most, see multiple AI agents, one board. The protocol itself is documented at modelcontextprotocol.io, and other MCP boards are compared on MCP task managers.

What doesn’t Weft do here?

  • No CLI, public REST API or webhooks, so cron jobs and CI pipelines cannot drive the loop outside an MCP client.
  • No GitHub or Slack integration. Evidence is whatever the agent links in artifacts.
  • No built-in AI. The thinking happens in your own AI client, which is also why Weft needs no AI credits.

Free covers 50 tasks and 200 AI calls a month. Pro is $7 per seat a month or $60 per seat a year (pricing).

Isn’t a good prompt enough to make agents follow the loop?
A prompt describes the loop; it cannot enforce it. It does not stop two agents claiming the same task, and it cannot free a task held by an agent that crashed. In Weft the claim is a lease the server owns, so those cases are handled whether or not the agent remembered its instructions.
What happens if my agent crashes halfway through?
Its heartbeats stop. Twenty minutes after the last report_progress the run is marked stale, the lease token is cleared and the task is unassigned again, so another agent or a person can pick it up. The card does not sit in Doing for a week.
Does every finished task wait for me to review it?
No. By default a completed task goes straight to Done with its outcome and evidence. It stops in your Inbox for Accept, Rework, Later or Drop only when the task needs review or a verification check fails.
Why would I want my agent to be refused work?
Because otherwise it keeps producing things you have no time to check. Once 5 items (10 for a team) or about 45 minutes of review are waiting on people, start_task returns attention_queue_full and points the agent at what it can still do. Clearing the queue unblocks it.
Hypertask has leases too. Why does MCP matter?
Hypertask’s leases are REST endpoints, by its own documentation (MCP overview), and its CLI can claim as well. That suits scripted agents. An agent working through MCP tools in an editor or chat does not get them there, and in Weft it does: start_task, report_progress and complete_task are MCP tools.