Skip to main content
Glama
README.md
# 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.

TDQS

A4.1/5.0

Scored across 14 tools

Disambiguation4/5

Most tools are clearly distinct, but halowerk_katalog, halowerk_preis, and cost_estimate all relate to pricing/cost estimation, which could lead to misselection if an agent is looking for a specific cost check. The descriptions are detailed enough to clarify, but the overlap is notable.

Naming Consistency3/5

The first two tools use a German brand prefix (halowerk_katalog, halowerk_preis) while the rest follow an English noun_verb or noun_noun pattern (e.g., cost_estimate, output_validate, cve_check). This mixed language and style is inconsistent but still readable and predictable after the first two.

Tool Count5/5

14 tools is well within the typical 3-15 range and each tool covers a distinct utility niche, from cost estimation and validation to security checks and document diff. The count feels appropriate for a general-purpose paid utility server.

Completeness5/5

Each tool appears to cover its advertised function completely: state_store offers full CRUD, security tools verify and report, and validation tools handle edge cases. There are no obvious dead ends or missing operations for the server's broad utility scope.

Maintenance

ActivitySlowing
ResponsivenessNo issues