That indirection is the whole design — a key referenced as {secrets.key} is substituted at send time and redacted from the response, so an API token never enters the transcript, and HAL_ALLOW_ patterns stop a secret from being sent to a host it was not meant for. The OpenAPI mode is the second reason to reach for it: point it at a specification and the endpoints arrive as tools, which beats teaching a model to hand-assemble paths. Treat it as powerful by construction — with no host restrictions configured, these seven tools can reach anything the machine can.
A general HTTP client for models. Seven verb tools plus a secret-substitution scheme: credentials live in the environment and are referenced as {secrets.key}, so the model composes requests with them without ever seeing their values.
- http-get, http-post, http-put, http-patch, http-delete, http-head and http-options, each taking a URL, headers, and where relevant a body and content type
- {secrets.key} placeholders substituted in the URL, headers and body from HAL_SECRET_ variables — the actual values are redacted from what comes back
- list-secrets returns only the key names available, never the values, so the model can see what it may reference
- HAL_ALLOW_ variables restrict a namespaced secret to specific URLs, so a key meant for one vendor cannot be sent to another host
- An OpenAPI or Swagger specification named in HAL_SWAGGER_FILE — a local path or a URL, JSON or YAML — is turned into tools automatically, with HAL_API_BASE_URL overriding the servers the spec declares
No account of its own — it needs whatever the APIs you point it at need. It runs as npx hal-mcp. Secrets go in HAL_SECRET_ prefixed variables, one per credential; HAL_ALLOW_ variables bind namespaced secrets to permitted URL patterns; HAL_SWAGGER_FILE and HAL_API_BASE_URL switch on the generated-tools mode. Note what it does not have: no allowlist of hosts by default, so a request can go anywhere the machine can reach.
One command — npx hal-mcp
