handwork
README.md
# 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:
```bash
npx -y @reneturcios/handwork mcp
```
MCP client configuration:
```json
{
"mcpServers": {
"handwork": {
"command": "npx",
"args": ["-y", "@reneturcios/handwork", "mcp"]
}
}
}
```
In a container (the default command is `mcp`):
```bash
docker run -i ghcr.io/cloudcorprecords/handwork
docker run --rm ghcr.io/cloudcorprecords/handwork --version
```
## CLI
```bash
handwork mcp # serve the tools over stdio
handwork --version # print the version
```
Any other subcommand prints usage and exits with code 2.
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # node test runner via tsx; stubbed upstream, no network
npm run dev # run the CLI from source
```
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`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing