Skip to content

Agent Workflows

This guide covers the recommended patterns for AI agents that use Hypertask as their task management backend. Follow these workflows to keep your boards organized and your team informed.

When an agent uses a webhook, failure or dehydration of the target endpoint shouldn't silently drop messages. If your agent's webhook endpoint returns an error, times out, or is unavailable, the server now retries by returning the message to polling so you can continue processing in the next polling cycle. Deleting a webhook also releases any messages it never acknowledged, preventing buildup when the target is removed.

Hypertask may reference pull request URLs (for example, via MCP tools) on tasks or other objects. In the past, when Hypertask attempted to verify or interact with such a link and the PR could not be found—for instance, because it was from a private GitHub repository—this resulted in a PullRequestLinkError that was treated as an error and could cause the agent or workflow to create false error tickets. After this change, an unrecoverable missing PR link is now logged as a warning instead, so it no longer triggers a false error ticket. You can still inspect such warnings for manual triage.

When an agent session starts, it should find the highest-priority available work.

  1. Check the inbox -- call hypertask_inbox (action: "list") to see if any tasks were assigned or moved back for rework.
  2. List tasks -- call hypertask_tasks (action: "list") with query, filter, fields, and limit so you get only the rows you need. Do not pull a whole board and filter it in context.
  3. Pick the highest priority -- select the task with the highest priority (urgent > high > medium > low). If priorities are equal, pick the oldest task.
// Example: open tickets in AI Review with a red PR, title and url only
hypertask_tasks({
action: "list",
input: {
project_id: 15,
filter: { section: "AI Review", has_pr: "red", status: "open" },
fields: ["title", "url"],
limit: 20
}
})

filter.has_pr=red matches the red PR badge on the board: failing checks or a closed pull request. fields returns only those columns, so this call stays small.

To safely claim a task without racing with other agents, use task leases. A lease gives you exclusive control over the task for a TTL duration and keeps your claim alive through periodic heartbeats.

  1. Claim the task -- call the LEASE claim endpoint to acquire a lease.
  2. Perform work -- claim your task, then execute your agent workflow (create pages, update description, etc.).
  3. Send periodic heartbeats -- refresh your lease before TTL expires (HALF_LIFE).
  4. Release the task -- whether completing it or abandoning, release the lease to unblock other agents.

Claim a task:

POST /api/mcp/tasks/lease/claim
Authorization: Bearer YOUR_AGENT_TOKEN
{
"ticket_number": "HYP-42",
"owner_id": "agent-6" // your agent's internal ID if known
}

Send a heartbeat to extend the lease:

POST /api/mcp/tasks/lease/heartbeat
Authorization: Bearer YOUR_AGENT_TOKEN
{
"lease_id": "lease-abc123",
"ttl": 6000000 // optional: explicit TTL in ms; not required if you just want to refresh current lease
}

Release the lease:

POST /api/mcp/tasks/lease/release
Authorization: Bearer YOUR_AGENT_TOKEN
{
"lease_id": "lease-abc123"
}

Leases for native-agent AI Chat (HTPR-5468)

Section titled “Leases for native-agent AI Chat (HTPR-5468)”

Native-agent AI Chat workflows must acquire a task lease before performing mutations such as task assignment or movement. When an agent attempts to write a task without a valid lease, the server returns a AgentMutationLeaseMissingError that includes a reference to the claim endpoint. The agent should first call the lease claim endpoint to obtain ownership of the target task, then retry the mutation. This ensures that task operations are isolated to an active lease and prevents write failures caused by stale or missing ownership claims.

Authenticated agent tokens that carry valid htk_ API keys receive a higher rate-limit tier:

  • Base tier: 120 requests/minute for unauthenticated or invalid keys
  • Agent tier: 600 requests/minute for authenticated agents with valid htk_ keys

Agent-tier rate limits apply specifically to agent traffic. Non-agent requests (e.g., from human users or other clients) remain subject to the base limits.

Agents can maintain long-lived, task-bound notes through the Pages system. Use Pages to experiment, plan, and research without cluttering task descriptions.

When an agent needs to explore or plan in depth:

// 1. Create a new page on a task
hypertask_pages({
action: "create",
input: {
ticket_number: "HYP-42",
title: "Competitor research",
content: "# Competitor research\n\nStart by listing key competitors."
}
})
// 2. Append multiple times to grow the page
hypertask_pages({
action: "update",
input: {
mode: "append",
page_id: 4521,
if_version: currentVersionHead,
content: "### Competitor A\n\n- Pricing tier X\n- Notable features..."
}
})
// 3. Search the page to surface relevant parts later
hypertask_pages({
action: "search",
limit: 5,
input: {
query: "pricing"
}
})

Use append to grow pages incrementally without risking accidental overwrites; use prepend to add context at the top of a page (e.g., updated policy notes or quick updates).

  • Append: Place new text after existing content (RFC 2046 style).
  • Prepend: Place new text before existing content.
  • Overwrite: Replace the entire page.

If two agents or workflows try to update the same page at the same time, version conflict safety ensures neither silently loses work:

  • The server validates if_version before persisting; if it mismatches the current version, it returns 409 Conflict.
  • Clients can retry after reading the latest version with hypertask_pages (action: "get").
// 1. Retrieve current page
const page = await hypertask_pages({
action: "get",
input: {
page_id: 4521
}
})
// 2. Append or prepend to current content
const newContent = `${page.text}\n\n---\nAdditional context: ${timestamp}`
// 3. Write back with if_version for conflict safety
const result = await hypertask_pages({
action: "update",
input: {
mode: "replace",
page_id: 4521,
if_version: page.version,
content: newContent
}
})
if (result.status === 409) {
// Conflict: fetch latest and retry
const newer = await hypertask_pages({ action: "get", input: { page_id: page.id } })
// ... retry with newer.version
}

Task descriptions also have versioning, useful for agents that need to review or revert changes over time.

hypertask_tasks({
action: "versions",
input: {
ticket_number: "HYP-42"
}
})
hypertask_tasks({
action: "restore",
input: {
ticket_number: "HYP-42",
version_id: 2 // fetch from versions list to pick the right one
}
})

Read the versions response first and pass the selected numeric version_id to restore. Page updates use if_version for optimistic locking; task description restoration selects a saved version instead.

Pages should always align with the task they belong to. Examples of working together:

  • A research task (HYP-42) can have pages for competitor analysis, specs research, and notes.
  • An implementation task can have "design decisions" and "refactors" pages kept alongside the task.
  • Use hypertask_pages (action: "list") after picking a task to quickly scan attached explorations.
  • MCP Integration — how to connect your agent to the Hypertask MCP server.
  • Pages — detailed reference for task-bound pages, history, and CLI/MCP tools.
  • CLI Reference — terminal commands for listing pages, searching, and managing versions.
  • Agent Webhooks — what wakes an agent, what Hypertask sends, and how to verify it.