# 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](#quick-example)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [CLI](#cli)
- [MCP Server](#mcp-server)
- [Authoring Model](#authoring-model)
- [Examples](#examples)
## Quick Example
```text
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
```bash
cargo install hen
```
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:
```bash
docker build -t hen:latest .
```
## Quick Start
Verify a collection without executing shell commands or network requests:
```bash
hen verify ./examples/lorem.hen
```
Run every request in a collection non-interactively:
```bash
hen run ./examples/lorem.hen all --non-interactive
```
Emit machine-readable output for scripts or CI:
```bash
hen run ./examples/lorem.hen all --non-interactive --output json
```
## CLI
Hen has two primary commands:
- `hen run` executes a collection or request.
- `hen verify` parses 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 `.hen` file, Hen selects it automatically.
- If a collection contains multiple requests, provide an index or `all` to bypass the picker.
- The text CLI prompts for unresolved `[[ prompt ]]` placeholders.
- `--non-interactive` disables selection prompts and fails when required prompt values are missing.
- Use repeated `--input key=value` flags to provide prompt values up front.
### Useful options
- `--output text|json|ndjson|junit` selects human or machine-readable output.
- `--parallel` runs independent requests concurrently.
- `--max-concurrency N` throttles parallel execution.
- `--continue-on-error` keeps unaffected dependency branches running.
- `--benchmark N` benchmarks a request instead of running it once.
- `--export` renders 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`.
```text
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](syntax-reference.md) and the schema examples under [examples/](examples/).
## MCP Server
Hen also ships with `hen-mcp`, a stdio MCP server for editors and agents. It is intentionally non-interactive:
- use `hen` for terminal-first, prompt-driven workflows
- use `hen-mcp` when an MCP client needs structured access
- provide any `[[ prompt ]]` values explicitly through tool inputs
### Running the server
If `hen-mcp` is on your `PATH`:
```bash
hen-mcp
```
From a checkout of this repository:
```bash
cargo run --bin hen-mcp
```
For normal MCP client usage, prefer a compiled binary:
```bash
cargo build --release
./target/release/hen-mcp
```
### Example configuration
VS Code uses `.vscode/mcp.json`:
```json
{
"servers": {
"hen": {
"type": "stdio",
"command": "/absolute/path/to/hen-mcp"
}
},
"inputs": []
}
```
Claude Code uses `.mcp.json`:
```json
{
"mcpServers": {
"hen": {
"type": "stdio",
"command": "/absolute/path/to/hen-mcp"
}
}
}
```
If `hen-mcp` is installed globally, `command` can simply be `hen-mcp`.
### Exposed MCP surface
- `run_hen`: run a collection or request non-interactively
- `verify_hen_syntax`: validate a file or inline source without execution
- `get_hen_authoring_guide`: return built-in usage or syntax docs
- `hen://authoring-guide` and `hen://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`, and `protocol = ws`.
- Captures: `& body.token -> $TOKEN` stores response data for later requests, assertions, and callbacks.
- Assertions: `^` lines validate status, headers, body fields, structural JSON matches, and schema targets.
- Dependencies: `> requires: Request Name` creates a DAG so setup requests run before dependents.
- Fragments: `<< file.hen` reuses 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 `~~~graphql` documents.
- MCP: MCP-over-HTTP authoring with generated JSON-RPC envelopes and reusable sessions.
- SSE: named streaming sessions with `receive` steps and timeout windows.
- WebSocket: `open`, `send`, `exchange`, and `receive` flows over a named session.
### Full syntax guide
The complete authoring grammar lives in [syntax-reference.md](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](examples/lorem.hen): basic HTTP requests
- [examples/json_response_captures.hen](examples/json_response_captures.hen): captures and JSON paths
- [examples/filtered_selector_variables.hen](examples/filtered_selector_variables.hen): selector variables in captures and assertions
- [examples/schema_scalar_checks.hen](examples/schema_scalar_checks.hen): scalar validation
- [examples/schema_object_validation.hen](examples/schema_object_validation.hen): object schema validation
- [examples/schema_root_array_validation.hen](examples/schema_root_array_validation.hen): root-array schemas
- [examples/schema_fragment_reuse.hen](examples/schema_fragment_reuse.hen): declaration reuse through fragments
- [examples/structural_json_matching.hen](examples/structural_json_matching.hen): structural JSON assertions
- [examples/graphql_protocol.hen](examples/graphql_protocol.hen): GraphQL authoring
- [examples/mcp_protocol.hen](examples/mcp_protocol.hen): MCP-over-HTTP sessions
- [examples/sse_protocol.hen](examples/sse_protocol.hen): server-sent events
- [examples/ws_protocol.hen](examples/ws_protocol.hen): WebSocket sessions