# halowerk-mcp **70 paid APIs as MCP tools. No account, no login, no subscription — a throwaway wallet with a few dollars is enough.** Your spend is capped before anything is signed: | Variable | Default | What it does | |---|---|---| | `HALOWERK_MAX_PREIS_USDC` | `0.05` | Ceiling per call. A more expensive service is refused, not silently bought. | | `HALOWERK_BUDGET_USDC` | `1.00` | Ceiling per session. Once reached, the server refuses further calls. | | `HALOWERK_TROCKEN` | off | Dry run: returns the price and the call plan, pays nothing. | Every paid answer carries `bezahlt_usdc`, `budget_rest_usdc` and the transaction hash, so the model and you see the same numbers. --- ## Try it without a wallet Two tools work with no wallet and cost nothing: `halowerk_katalog` lists every service with its price, and `halowerk_preis` tells you what a planned call would cost. Install it, browse, decide later. ```json { "mcpServers": { "halowerk": { "command": "npx", "args": ["-y", "halowerk-mcp"] } } } ``` That goes in your Claude Desktop config (`claude_desktop_config.json`), Cursor's `mcp.json`, or Cline's MCP settings. ## Paying for calls ```json { "mcpServers": { "halowerk": { "command": "npx", "args": ["-y", "halowerk-mcp"], "env": { "HALOWERK_PRIVATE_KEY": "0x…", "HALOWERK_MAX_PREIS_USDC": "0.05", "HALOWERK_BUDGET_USDC": "1.00" } } } } ``` Payment is [x402](https://x402.org) with USDC on Base. There is no account to create, no card, no invoice: the call carries a signed authorisation for the exact amount, and the service settles it. ### Use a throwaway wallet **Create a fresh wallet, put a few dollars of USDC on it, use it for nothing else.** Not because this package is untrustworthy — because you have no reason to trust it yet. A key in an MCP config is a key that a model-driven process can reach. The way to make that safe is not to trust the code but to make the blast radius small: if the wallet holds three dollars, three dollars is the worst case. You do not need ETH for gas. Payment uses EIP-3009 `transferWithAuthorization`, so a third party submits the transaction. A balance of exactly 0 ETH is normal and correct. ### What the code does with your key - It is read from `HALOWERK_PRIVATE_KEY` and from nowhere else — no file, no argument, no prompt. - It is never logged, never put in an error message, never returned in an answer, not even truncated. There is a test for this: `npm run pruefe` searches the entire output for the first eight characters of a key and fails if it finds them. - `src/x402.ts` is about 300 lines and is the only file that touches it. It is meant to be read in five minutes. ## Where your money can go **The server only ever pays the ten hosts baked into the catalogue at build time.** The list is frozen in the package; it cannot be extended by a file, an environment variable or a tool argument. This is the point of the whole design. A tool that accepts an arbitrary URL and pays for it is a payment instruction with a blank payee field. A model that reads a web page, a PDF or an email can be told, by that text, to call such a tool with an attacker's address. So: - The target host must match the built-in list **exactly**. No suffix comparison — `halowerk.com.attacker.example` passes any `endsWith` check and is a different host. - `https` only. Redirects are **not** followed: a 301 to a foreign host is the attack, not an inconvenience. - No IP addresses, no `localhost`, no private ranges. - On violation: refusal with the reason, **before** anything is signed. `halowerk_rufe_auf` takes a *tool name from the catalogue*, never a URL. ## Modes Seventy tools at once makes the tool picker worse for everybody, especially if you have other MCP servers connected. So: | `HALOWERK_MODUS` | Tools | For | |---|---|---| | `hero` (default) | 12 services + the 2 free ones | Everyday use | | `gateway` | 3 meta-tools + the 2 free ones | Minimal context; two extra round trips | | `all` | 70 services + the 2 free ones | You know what you want | In `gateway` mode: `halowerk_suche` finds a service by description, `halowerk_beschreibe` returns its input schema, `halowerk_rufe_auf` executes it. ### Why these twelve One measure only: **what does an agent need more than once in the same task?** A tool used once per session can be looked up; one used ten times belongs in the toolbox. All twelve are also text in, text out — in a chat window, a tool that needs a file upload first is close to unusable. | Tool | Repeats because | |---|---| | `cost_estimate` | before every model call | | `output_validate` | after every model answer | | `tool_arg_validate` | before every expensive or irreversible call | | `state_store` | across every step of a long task | | `cve_check` | per dependency list, and you look at it more than once | | `license_check` | same audit, per package set | | `tls_chain` | per host in an infrastructure check | | `jwt_verify` | per token while debugging auth | | `webhook_signature` | per webhook while debugging an integration | | `doc_diff` | per file pair in a review | | `web_archive` | per URL in a research task | | `invoice_audit` | per invoice in a batch | ## Tiered prices — read this before you set a budget Some services bill per unit: per audio minute, per 1000 characters, per sample point. For those, `price_usdc` is only the **minimum**. The budget check therefore uses `max_usdc`, the ceiling. Checking against the minimum would approve 0.006 and pay 0.25 — the endpoint bills by length, and the length is in the request body, not in the catalogue. If a service has no ceiling at all, it counts as unbounded and is **not** called without `unbegrenzt_erlauben: true`. A budget that checks against an unknown amount is not a budget. ## What this package is not - It is not a wallet manager. It signs payments; it never moves funds anywhere else. - It does not create or store keys. - It does not phone home. The only outbound requests go to the ten catalogue hosts. - The catalogue is generated from the live services and shipped with the package. It is not fetched at runtime, so a compromised server cannot add itself to your allowlist between calls. ## Development ```bash npm run katalog # regenerate katalog.json from the live services npm run build # compile TypeScript npm run pruefe # modes, spending brakes, attack tests, key-leak test ``` `katalog.json` is **generated**. Never edit it by hand — regenerate and republish, otherwise the package promises a price the service does not charge. ## License MIT. See LICENSE.