hatchet-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hatchet-mcplist my workflows"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hatchet-mcp
Unofficial, community project — not affiliated with, sponsored by, or endorsed by Hatchet. It is an independent integration that talks to Hatchet only through the public REST API via the official
hatchet-sdk.
An operational MCP (Model Context Protocol) server for Hatchet,
the durable orchestration engine. It exposes Hatchet's live state — and, optionally, its
control surface — to an LLM over the Hatchet REST API (via the official hatchet-sdk
feature clients) using the stdio transport.
It is a control tower for a Hatchet tenant: inspect workflow definitions, runs, tasks, logs, workers, events, cron/scheduled triggers, rate limits, filters, queue/task metrics, run timings, and OpenTelemetry traces — and, when explicitly enabled, trigger/cancel/replay runs, push events, pause/resume workflows and workers, and manage cron/scheduled/filters.
Read-only by default. Out of the box it never triggers, cancels, replays, or mutates
anything, so it is safe to point at a production tenant. Mutating tools are unregistered
until you opt in with HATCHET_MCP_READ_ONLY=false.
Design background lives in
docs/init/. Seedocs/init/mcp-server-design.mdfor the full tool surface and security model.
Quick start
Get a token. Visit your Hatchet dashboard → Settings → API Tokens → Create. The token is shown only once. (For self-hosted with an internal token URL, note the public REST URL — set it as
HATCHET_CLIENT_SERVER_URL.)Run the server.
uvx hatchet-mcp(works with no prior install beyonduvitself).Set the token. Either
export HATCHET_CLIENT_TOKEN=<your-token>in your shell, or put it in your MCP client'senv:block — see Use it from an MCP client for a copy-pasteable.mcp.json.Ask the LLM. Try "list my workflows" or "show runs from the last hour". The 24 read tools are available immediately; mutating tools stay hidden until you set
HATCHET_MCP_READ_ONLY=false.
Install & run
# From PyPI
uvx hatchet-mcp
# Directly from a git checkout, no install
uvx --from git+https://github.com/DanMeon/hatchet-mcp hatchet-mcp
# From a local clone
uvx --from . hatchet-mcp
# Local development
uv run hatchet-mcpAll launch the same stdio MCP server. Configuration is environment-only because uvx
makes passing CLI flags awkward. With no HATCHET_CLIENT_TOKEN the server fails fast
and exits non-zero — it never starts a half-configured server.
Use it from an MCP client
The repo ships a .mcp.json.example for project-scoped setup. Copy it to
.mcp.json (gitignored, so your token stays local) and fill in the token:
cp .mcp.json.example .mcp.json
# then edit .mcp.json → set HATCHET_CLIENT_TOKENOr register it directly with the CLI:
claude mcp add hatchet -e HATCHET_CLIENT_TOKEN=<your-token> -- uvx hatchet-mcpOr the JSON config block (Claude Desktop / Claude Code). This example opts into the mutating tools:
{
"mcpServers": {
"hatchet": {
"command": "uvx",
"args": ["hatchet-mcp"],
"env": {
"HATCHET_CLIENT_TOKEN": "<your-token>",
"HATCHET_CLIENT_SERVER_URL": "https://<self-host-url>",
"HATCHET_MCP_READ_ONLY": "false"
}
}
}
}Omit HATCHET_MCP_READ_ONLY (or set it to true) to keep the safe, read-only posture.
Multiple tenants
A Hatchet token is scoped to exactly one tenant, so to operate several tenants you run one server instance per tenant — each with its own token — and register them as distinct MCP servers. No special configuration is needed; the client picks the server by name.
{
"mcpServers": {
"hatchet-prod": {
"command": "uvx",
"args": ["hatchet-mcp"],
"env": { "HATCHET_CLIENT_TOKEN": "<prod-token>" }
},
"hatchet-staging": {
"command": "uvx",
"args": ["hatchet-mcp"],
"env": { "HATCHET_CLIENT_TOKEN": "<staging-token>", "HATCHET_MCP_READ_ONLY": "false" }
}
}
}This keeps tenant tokens in separate processes (no token mixing). See
docs/init/multitenancy-and-dependencies.md §1 for the rationale and the
alternative (a single server with a tenant argument), which was considered and not adopted.
Configuration (environment only)
Env var | Required | Default | Meaning |
| yes | — | Hatchet API token (a JWT). Server URL and tenant are decoded from it. |
| no | from token | REST base URL override (for a self-host whose token embeds an unreachable internal URL). |
| no |
| The mutation gate. |
If HATCHET_CLIENT_TOKEN is missing the server fails fast at startup and exits — no
silent fallback. The token is never logged, echoed, or included in any error message
(even when the SDK rejects it, only the exception type is surfaced).
Safety model
This server can drive a production orchestrator, so safety is layered:
Read-only by default.
HATCHET_MCP_READ_ONLYdefaults totrue. In that mode the 17 mutating tools are not registered at all — an MCP client cannot see or call them.Defense in depth. Even if a mutating handler is somehow reached in read-only mode, it re-checks the gate and refuses.
Destructive annotations. Every mutating tool is advertised with
destructiveHint=true(and an accurateidempotentHint) so MCP clients can require human approval before each call.Bulk guardrails.
cancel_runs/replay_runsdefault to a dry run — they return the matching run IDs without acting. You must re-call withdry_run=falseto mutate. They also refuse to act on more than 500 matching runs, forcing a narrower filter.Token confidentiality. The token is never written to stdout (the JSON-RPC channel), stderr, tool responses, or error messages.
Single tenant. One token scopes the whole server to one Hatchet tenant (its
subclaim).
Tools
41 tools total: 24 read-only (always registered) + 17 mutating (registered only
when HATCHET_MCP_READ_ONLY=false).
Read-only (24) — always available
Tool | Hatchet SDK / REST call | Purpose |
|
| List workflow definitions (name, paused, versions) |
|
| One workflow definition by ID |
|
| List workflow/task runs (time, status, workflow, worker, metadata filters). Excludes payloads by default — use |
|
| One run in detail (task tree / DAG shape, inputs, outputs) |
|
| Status only — lightweight polling |
|
| One task run by ID (status, attempt, worker, I/O) |
|
| Log lines for a single task run |
|
| Orchestration event timeline for a task run (state transitions) |
|
| List workers (status, slots, registered actions) |
|
| One worker by ID (slot state, recent runs, registered actions) |
|
| List ingested events (key, time, workflow, run-status, metadata) |
|
| One event with full payload + triggered-run summary |
|
| Distinct event keys in the tenant |
|
| List cron triggers |
|
| One cron trigger by ID |
|
| List scheduled (one-off, future) runs |
|
| Rate limits with current consumption |
|
| Event filters (CEL expressions) |
|
| One event filter by ID |
|
| Test a CEL expression against sample input (no filter created) |
|
| Native per-queue depth |
|
| Task counts grouped by status |
|
| Task waterfall timings for a run |
|
| OpenTelemetry spans for a run |
Mutating (17) — only when HATCHET_MCP_READ_ONLY=false
Tool | Hatchet SDK / REST call | Idempotent | Purpose |
|
| no | Trigger a new workflow run by name |
|
| no | Cancel runs by IDs or filter — dry-run default, 500 cap |
|
| no | Replay runs by IDs or filter — dry-run default, 500 cap |
|
| no | Restore an evicted durable task |
|
| no | Push an event (may trigger event-driven workflows) |
|
| yes | Pause a workflow definition |
|
| yes | Resume a paused workflow definition |
|
| yes | Pause a worker |
|
| yes | Resume a worker |
|
| no | Create a cron trigger |
|
| yes | Delete a cron trigger |
|
| no | Schedule a one-off future run |
|
| yes | Delete a scheduled run |
|
| yes | Change a scheduled run's trigger time |
|
| no | Create an event filter (CEL) |
|
| yes | Update an event filter |
|
| yes | Delete an event filter |
Status enums differ by engine generation and are passed through unchanged (no lossy remapping). v1 runs/tasks use
QUEUED · RUNNING · COMPLETED · CANCELLED · FAILED; legacy objects usePENDING · RUNNING · SUCCEEDED · FAILED · CANCELLED · QUEUED · BACKOFF. Seedocs/init/overview-and-concepts.md§5.
Response size and limits
A live tenant can hold thousands of runs, each with large input/output payloads, so a naive
list_runs can return several megabytes and blow past an MCP client's context window. The
read tools follow the same "keep lists small, fetch detail on demand" pattern as the GitHub,
Sentry, and Grafana MCP servers:
Lists exclude heavy payloads by default.
list_runsreturns run metadata — id, status, workflow, timings — but not each run's input/output. Passinclude_payloads=true(ideally with a smalllimit) for the full rows, or fetch one run's payloads withget_run.Every list tool defaults and caps its
limit. Unset resolves to 50, the hard cap is 100, and a value below 1 is rejected.get_task_logsis the exception — 1000 log lines, capped at 1000. Useoffsetto page where the tool exposes it.Single-item
get_*tools are never truncated.get_run/get_task/get_eventreturn the whole object — the one item is the point, so they bypass the size guard below.A ~500 KB ceiling backstops every list result. Anything larger is rejected with a message explaining how to narrow it (smaller
limit, tighter time window or statuses) instead of silently overflowing your context. This also protects tools whose upstream call takes nolimit, such aslist_workers.
Resources & prompts
In addition to tools, the server exposes read-only MCP resources (URI-addressable views that reuse the read tools, so their JSON is identical) and operator prompts. Both are always available and add no mutating surface.
Resources:
URI | Backed by |
|
|
|
|
|
|
|
|
|
|
Prompts:
Prompt | Arguments | Orchestrates |
|
|
|
|
|
|
|
|
|
How it talks to Hatchet
MCP client (Claude Code, …)
│ stdio (JSON-RPC)
▼
hatchet-mcp (Python, FastMCP)
│ hatchet-sdk feature clients, async aio_* methods
│ Authorization: Bearer <HATCHET_CLIENT_TOKEN>
▼
Hatchet REST API (/api/v1/stable/… + /api/v1/…)REST only — never the gRPC worker dispatcher protocol. A single token scopes the server to
a single tenant (resolved from the token's sub claim by the SDK).
Development
uv sync # install runtime + dev deps on Python 3.10+
uv run pytest # full test suite — needs no token, performs no real mutation
uv run ruff check src tests
uv run ruff format --check src tests
uv run pyright
uv run hatchet-mcp # needs HATCHET_CLIENT_TOKEN in the environmentContributing
Contributions are welcome. See CONTRIBUTING.md for development setup,
quality gates, project conventions, and the maintainer release process.
Security
hatchet-mcp can drive a production orchestrator and handles an API token. Please report
vulnerabilities privately — see SECURITY.md. Don't open a public issue
for security reports.
License
MIT — see LICENSE.
"Hatchet" and any related marks belong to their respective owners. This is an independent project and is not affiliated with or endorsed by Hatchet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DanMeon/hatchet-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server