Skip to content

Developers and agents

The API is the product

Hubtask was built backend first. The specification is written before the code and the code is generated from it; the interface people click is one client of that contract, with no private endpoints and no shortcuts of its own.

The API reference The OpenAPI contract API guidelines

One registry

Register once, reachable three ways

A use case is declared in one place with its inputs, its permissions and its side effects. REST routes, MCP tools and automation actions are all projections of that declaration — which is why they cannot fall out of step, and why a check in the build fails if they ever do.

REST

For your scripts and services

Cursor pagination and no page numbers, Idempotency-Key on every mutation, ETag and If-Match for concurrency, and problem documents with a machine-readable code and parameters instead of prose to regex.

MCP

For agents, inside your instance

Tools named after the use case, input schemas identical to the REST bodies, read-only and destructive hints so a client can ask before acting, resources addressable by URI, and prepared prompts.

RULES

For things that should happen without you

The same catalogue as rule actions, with conditions in an expression language, a dry run, and protection against a rule that triggers itself.

Ask before you guess

An installation describes itself

Installations differ: one has the vector extension and one does not, one has object storage and one writes to a volume, one has an AI provider configured and one has deliberately none. A client that hard-codes those assumptions is a client that breaks on somebody else’s box.

So the server answers what it can do. Which capabilities each item type carries, which fields are queryable and with which comparisons, which layouts exist, whether semantic search is available — all of it read from the installation rather than compiled into the client.

The same principle points the other way: a client must tolerate a field it does not know. That is a binding requirement on every first-party client and the reason a server upgrade does not break an older one.

# What can this installation do?
GET /api/v1/meta/capabilities

# What is degraded right now?
GET /api/v1/meta/health

# A composable query, not a search box
POST /api/v1/items:query
{
  "filter": "due_at < now+7d and label = 'release'",
  "limit": 50
}

Agents

An MCP server that runs where your data already is

Every large task tool now offers an MCP server, and nearly all of them are a hosted endpoint you authorise against their cloud — the agent reads your tasks there. Hubtask’s MCP server is an adapter in the process you started. Nothing leaves the machine unless you configured something for it to leave to.

The security model is the interesting part, and it is the one thing that could not be added later: because authorisation lives in the application layer, an MCP tool call carries no permission logic of its own. An agent holds a scoped credential and is refused precisely what a person with that credential would be refused — and its actions are recorded in the trail as an agent’s.

ai-first.md §1

What an agent gets

  • Tools The use case catalogue, in snake case, with the preconditions and side effects the registry already knows.
  • Resources Hubs, items and views addressable as hubtask:// URIs — a read that is already in the catalogue, reached by URI instead of by argument.
  • Prompts Prepared and versioned, from the same store the product’s own provider calls read.
  • A stream A session identifier that any process can verify without shared state, and the same connection limits a browser’s stream gets.

The rest of the surface

Everything else you would ask for

hubctl

The command line client. Its types are generated from the same specification, it prints a table for a person and the API’s own payload with --json for a pipe — one document on standard output and every diagnostic on standard error, so it composes.

Events out

Webhook subscriptions with an HMAC signature, retries and a dead-letter path, carrying published CloudEvents schemas, plus trigger polling endpoints. Generated nodes for n8n and Zapier come with the ecosystem milestone.

SDKs, and the one that exists

The TypeScript client the first-party applications use is generated from the contract, so a rename in the specification becomes a type error in the change that made it rather than in somebody’s production two months later. Published SDKs for TypeScript, Go and Python are an ecosystem milestone and are not out yet — until then the contract generates one for whichever language you need.

Offline conformance

Building your own client? The synchronisation contract is specified — client-assigned identifiers, an operation id per mutation, a hybrid logical clock per field change, defined behaviour when access is revoked or a cursor is too old. The conformance runner that will check an implementation against a real instance, hubctl sync-conformance, arrives with the synchronisation milestone.

offline-sync.md §9

Stability

What v1 promises

  • The contract is frozen at 1.0 API v1 is stable from the first stable release, with a deprecation process that has been exercised rather than written down.
  • Event schemas are versioned and published, so a consumer is not reverse-engineering a payload.
  • Migrations are forward only and safe for a rolling update — expand, then contract, never a change to a migration that has run.
  • One version for everything The server and every first-party client share a single version number. There is no compatibility matrix to keep in your head.
versioning-release.md