handwork
Some jobs need a person in the physical world: something made,
measured, assembled, tested, or shipped. handwork is a small MCP
server that connects an agent to a human service desk that takes
on exactly that kind of work. It exposes three tools — a service
catalogue, a quote request, and a status lookup — and forwards
each call to the desk's public remote endpoint, returning the
answer unchanged.
Asking for a quote is not placing an order. Nothing is charged
and nothing is made until a quote comes back by e-mail and is
accepted there; the tools themselves carry no ordering or
payment capability.
Tools
list_services — what the service will and will not do, the
categories it refuses, example prices, how payment works, and
the key contract terms. Takes no arguments and needs no
authentication.
request_quote — describe a physical-world task (what is to
be done, which services it needs, deliverables, deadline,
delivery address, input files, currency) along with the
client's invoice details, and a human screens it and replies
with a fixed-price quote by e-mail within 24 hours. The reply
carries a quote_id and an access_token; keep the token,
it is the only way to read the request back. No field at the
top level is required, but the nested task object requires a
description and the nested client object requires email
and name.
get_status — the state of an earlier quote request. Both
id (the quote_id) and access_token are required. Records
are kept for 90 days, and the quote itself arrives by e-mail.
How it works
handwork is a forwarding client, not a reimplementation. It
serves tools/list itself, from the tool definitions the remote
publishes, and for every tools/call it opens a streamable-HTTP
JSON-RPC session with the upstream — initialize, then
notifications/initialized, then the call, carrying the
Mcp-Session-Id header whenever the upstream issues one — and
passes the upstream result through verbatim. If the upstream
cannot be reached or answers with an error, the call fails with
a handwork error: message instead of a fabricated result.
The upstream endpoint defaults to https://handsforagents.com/mcp.
Setting the HANDS_MCP_URL environment variable points the
client at a different endpoint (a reconstruction affordance; the
published service itself names no override).
Run it
As an MCP server over stdio:
MCP client configuration:
In a container (the default command is mcp):
CLI
Any other subcommand prints usage and exits with code 2.
Development
The tests drive the forwarding core against a fake JSON-RPC
upstream injected in place of fetch, covering the handshake
order, session handling, verbatim pass-through, event-stream
responses, error surfacing, and a check that the served
tools/list matches the captured upstream surface exactly.
License
MIT — see LICENSE.