
Lightweight file-based CLI API client with age-encrypted secrets, first-class GraphQL support and MCP server for agentic workflow.
REST · GraphQL · OAuth
Quick Start • GraphQL Explorer • Project Layout • Documentation
hulak run ./requests/
Hulak runs request files directly from your project. It supports concurrent directory execution. It falls back to an interactive picker when you simply run hulak.
Browse schemas from multiple endpoints. Search operations. Build queries interactively. Execute inline. Save generated files from the terminal.
Hulak ships via xaaha/tap. Homebrew 6.0+ requires explicit trust for third-party taps; without it, brew upgrade silently skips hulak. One-time step per machine:
brew trust xaaha/tap
brew install --cask xaaha/tap/hulak
Other install options:
go install github.com/xaaha/hulak@latestgo build -o hulakHomebrew installs completion automatically. If you installed via go install
or built from source, opt in once:
# zsh
hulak completion zsh > "${fpath[1]}/_hulak" # then restart your shell
# bash (macOS, Homebrew bash-completion)
hulak completion bash > $(brew --prefix)/etc/bash_completion.d/hulak
# bash (Linux)
hulak completion bash | sudo tee /etc/bash_completion.d/hulak >/dev/null
Zsh requires autoload -Uz compinit && compinit in your .zshrc.
mkdir my-apis && cd my-apis
hulak init # creates .hulak/store.age + identity
Scaffold a starter request, to quickly check how a request file looks run:
hulak example api # writes example-api.hk.yaml you can run
[!Note] For Other types run:
hulak example.examplesub-command gives you a quick way to write a request file you can modify. For more info runhulak example -h
To set up a secret you can run:
hulak secrets keys set placeholder https://jsonplaceholder.typicode.com/posts -env prod
Now, in your example-api.hk.yaml file, you can reference this secret:
method: POST
url: "{{.placeholder}}"
# rest of the body of the file remains same
Run the request:
hulak run example-api.hk.yaml --env prod
env/*.env files instead of encrypted secrets?hulak init classic
Plaintext mode is fully supported. See docs/environment.md for more info
.env filesHulak runs in two modes. Pick once during hulak init. You can migrate later.
.hulak/store.age, encrypted with an age or SSH keypair. Safe to commit. Teams share via a recipients file. See docs/store.md.env/*.env files. Simpler, no encryption. Add env/ to .gitignore. See docs/environment.md.Running classic and want to switch? See docs/migrating-to-vault.md.
Hulak ships a built-in MCP server, so agents like Claude Code, Cursor, and Zed can drive your API collection in plain language — "list the requests", "dry-run login against staging", "call getUser and show the response".
For Claude Code, add it with one command:
claude mcp add hulak -s user -- hulak mcp --project api=~/work/api-tests
Cursor, Zed, Codex, opencode, and Pi use a small config file instead. See docs/mcp.md for each.
Secrets never leave your machine: the agent works with request and environment names, never decrypted values. Reads and dry-runs are read-only; writes are schema-validated; response files aren't saved unless asked.
Full setup, tool reference, and safety model: docs/mcp.md.
Run hulak <command> --help for flags and per-command examples.
Omitting --env opens an interactive picker.
hulak run and hulak gql only prompt when files reference {{.key}}.hulak secrets subcommands prompt every time (except secrets list).--env <name>.~/.config/hulak/identity.txt. That is your private key. Mode 0600. Back it up first. See docs/store.md#identity-backup.hulak init, -env creates env files. It is a setup flag, not a runtime selector. hulak init -env staging prod scaffolds two envs.env is an alias for secrets. hulak env list works the same as hulak secrets list.secrets edit. Use EDITOR="code -w" or EDITOR="zed --wait". Without it the editor returns immediately and changes are lost.store.age need a recipe. See .my-project/
├── .hulak/
│ ├── store.age # encrypted secrets (safe to commit)
│ └── recipients.txt # public keys of recipients (safe to commit)
├── requests/
│ ├── create-user.hk.yaml
│ └── get-user.hk.yaml
└── (your project files)
~/.config/hulak/
└── identity.txt # YOUR private key. NEVER commit. Mode 0600.
Start the explorer with a file or a directory:
hulak gql e2etests/gql_schemas/countries.yml
hulak gql .
hulak gql -env staging ./collections/graphql
Read the full guide in docs/graphql-explorer.md.
Start here for the full reference:
env/ to .hulak/.For the live command surface, run:
hulak help
hulak <command> --help
The Hulak schema is available in the Schema Store, so editors that support Schema Store can automatically enable completion for .hk.yaml and .hk.yml files.
You can also point your YAML language server directly at:
https://raw.githubusercontent.com/xaaha/hulak/refs/heads/main/assets/schema.json
git clone https://github.com/xaaha/hulak.git
cd hulak
mise install
See CONTRIBUTING.md for the full development workflow.
If Hulak is useful to you, open an issue, suggest a feature, send a pull request, or sponsor the project.
| Command | Purpose | Read more |
|---|
run | Execute request file(s) or a directory | body.md, actions.md |
gql | GraphQL explorer TUI | graphql-explorer.md |
secrets | Encrypted vault CRUD | store.md |
init | Initialize a hulak project | store.md |
migrate | Postman to hulak conversion | migrating-to-vault.md |
example | Scaffold sample request files | — |
doctor | Check project health | — |
mcp | Serve requests to AI agents over MCP | mcp.md |
version | Print version | — |