Hen
Run API requests as files, from the command line or through MCP.
Hen keeps request definitions, assertions, captures, dependencies, and protocol-specific behavior in a single .hen file. It works well for local exploration, CI, and editor or agent integrations.
Table of Contents
Quick Example
name = Test Collection File
description = A collection of mock requests for testing this syntax.
$ API_KEY = $(./get_secret.sh)
$ USERNAME = $(echo $USER)
$ API_ORIGIN = https://lorem-api.com/api
$ ROLE = [admin, user, guest]
---
Some descriptive title for the prompt.
POST {{ API_ORIGIN }}/echo
* Authorization = {{ API_KEY }}
? query_param_1 = value
~~~ application/json
{
"username": "{{ USERNAME }}",
"password": "[[ password ]]",
"role": "{{ ROLE }}"
}
~~~
^ & status == 200
! sh ./callback.sh
This single file can define variables, prompt inputs, mapped requests, assertions, and callbacks. Add > requires: when later requests depend on earlier ones, and use response captures to thread values through a collection.
Installation
This installs both hen and hen-mcp.
Container Image
The repository also ships a container image that includes both binaries.
Build it locally with Docker:
Quick Start
Verify a collection without executing shell commands or network requests:
Run every request in a collection non-interactively:
Emit machine-readable output for scripts or CI:
CLI
Hen has two primary commands:
hen runexecutes a collection or request.hen verifyparses and validates a collection without making requests.
The default hen [PATH] [SELECTOR] form still works for interactive terminal use, but hen run ... is the clearer choice for CI and automation.
Selection and prompts
- If a directory contains one
.henfile, Hen selects it automatically. - If a collection contains multiple requests, provide an index or
allto bypass the picker. - The text CLI prompts for unresolved
[[ prompt ]]placeholders. --non-interactivedisables selection prompts and fails when required prompt values are missing.- Use repeated
--input key=valueflags to provide prompt values up front.
Useful options
--output text|json|ndjson|junitselects human or machine-readable output.--parallelruns independent requests concurrently.--max-concurrency Nthrottles parallel execution.--continue-on-errorkeeps unaffected dependency branches running.--benchmark Nbenchmarks a request instead of running it once.--exportrenders the request as a curl command.
Schema validation
Hen supports collection-local scalar and schema declarations plus built-in targets such as UUID, EMAIL, NUMBER, DATE, DATE_TIME, TIME, and URI.
scalar HANDLE = string & len(3..24) & pattern(/^[a-z][a-z0-9_]*$/)
schema User {
id: UUID
email: EMAIL
handle: HANDLE
}
For the full declaration grammar and more examples, see syntax-reference.md and the schema examples under examples/.
MCP Server
Hen also ships with hen-mcp, a stdio MCP server for editors and agents. It is intentionally non-interactive:
- use
henfor terminal-first, prompt-driven workflows - use
hen-mcpwhen an MCP client needs structured access - provide any
[[ prompt ]]values explicitly through tool inputs
Running the server
If hen-mcp is on your PATH:
From a checkout of this repository:
For normal MCP client usage, prefer a compiled binary:
Example configuration
VS Code uses .vscode/mcp.json:
Claude Code uses .mcp.json:
If hen-mcp is installed globally, command can simply be hen-mcp.
Exposed MCP surface
run_hen: run a collection or request non-interactivelyverify_hen_syntax: validate a file or inline source without executionget_hen_authoring_guide: return built-in usage or syntax docshen://authoring-guideandhen://readme: built-in resources for clients that read docs directly
Authoring Model
Hen files are plain text collections made of a preamble and one or more requests separated by ---.
Core concepts
- Variables:
$ NAME = value, shell substitutions with$(...), prompt placeholders with[[ name ]], and simple arrays for mapped requests. - Requests: HTTP by default, plus explicit
protocol = graphql,protocol = mcp,protocol = sse, andprotocol = ws. - Captures:
& body.token -> $TOKENstores response data for later requests, assertions, and callbacks. - Assertions:
^lines validate status, headers, body fields, structural JSON matches, and schema targets. - Dependencies:
> requires: Request Namecreates a DAG so setup requests run before dependents. - Fragments:
<< file.henreuses shared request snippets or declarations. - Callbacks:
!lines run shell commands after request execution. - Guards:
[predicate]can gate assertions or fragment imports.
Protocol support
- HTTP: ordinary request and response workflows.
- GraphQL: GraphQL-over-HTTP with
operation,variables, and~~~graphqldocuments. - MCP: MCP-over-HTTP authoring with generated JSON-RPC envelopes and reusable sessions.
- SSE: named streaming sessions with
receivesteps and timeout windows. - WebSocket:
open,send,exchange, andreceiveflows over a named session.
Full syntax guide
The complete authoring grammar lives in syntax-reference.md. That file covers:
- variables and prompts
- headers, query parameters, form data, and body blocks
- protocol-specific directives
- declarations, captures, assertions, callbacks, and dependencies
Examples
The fastest way to learn the format is to run the included examples:
- examples/lorem.hen: basic HTTP requests
- examples/json_response_captures.hen: captures and JSON paths
- examples/filtered_selector_variables.hen: selector variables in captures and assertions
- examples/schema_scalar_checks.hen: scalar validation
- examples/schema_object_validation.hen: object schema validation
- examples/schema_root_array_validation.hen: root-array schemas
- examples/schema_fragment_reuse.hen: declaration reuse through fragments
- examples/structural_json_matching.hen: structural JSON assertions
- examples/graphql_protocol.hen: GraphQL authoring
- examples/mcp_protocol.hen: MCP-over-HTTP sessions
- examples/sse_protocol.hen: server-sent events
- examples/ws_protocol.hen: WebSocket sessions