
A lightweight, file-based CLI API client with age-encrypted secrets, first-class GraphQL support, and a built-in MCP server for AI agent workflows.
<p align="center">
<img alt="Hulak" src="https://raw.githubusercontent.com/xaaha/hulak/main/assets/hulak-logo.svg" width="180" />
</p>
<h1 align="center">Hulak</h1>
<h3 align="center">
Your messenger in the terminal.
</h3>
<p align="center">
<a href="#quick-start">Quick Start</a> •
<a href="#graphql-explorer">GraphQL Explorer</a> •
<a href="#project-layout">Project Layout</a> •
<a href="#documentation">Documentation</a>
</p>
---
### Run one request, a whole directory, or stay interactive
<img alt="Concurrent Execution" src="https://assets.kitploit.com/production/public/readmes/12535/3ea47749f291ed181923d64f3751b68e0fa035e3c16ec44c973a65fb32ee4c5a.gif" width="720" />
```bash
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`.
### Dedicated GraphQL Explorer
<img alt="GraphQL Explorer" src="https://assets.kitploit.com/production/public/readmes/12535/be3004f25dc07831b622ac6bae4a8cf276dbe450518d70d0de4641accd1cb454.gif" width="720" />
Browse schemas from multiple endpoints. Search operations. Build queries interactively. Execute inline. Save generated files from the terminal.
## Quick Start
### Install
Hulak ships via [xaaha/tap](https://github.com/xaaha/homebrew-tap). Homebrew 6.0+ requires explicit trust for third-party taps; without it, `brew upgrade` silently skips hulak. One-time step per machine:
```bash
brew trust xaaha/tap
brew install --cask xaaha/tap/hulak
```
Other install options:
- `go install github.com/xaaha/hulak@latest`
- Build from source with `go build -o hulak`
#### Shell completion (go install / source builds)
Homebrew installs completion automatically. If you installed via `go install`
or built from source, opt in once:
```bash
# 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`.
### Path A. API client with encrypted secrets (default)
```bash
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:
```bash
hulak example api # writes example-api.hk.yaml you can run
```
> [!Note]
> For Other types run: `hulak example`. `example` sub-command gives you a quick way to write a request file you can modify. For more info run `hulak example -h`
To set up a secret you can run:
```bash
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:
```yaml
method: POST
url: "{{.placeholder}}"
# rest of the body of the file remains same
```
Run the request:
```bash
hulak run example-api.hk.yaml --env prod
```
### Prefer plaintext `env/*.env` files instead of encrypted secrets?
```bash
hulak init classic
```
Plaintext mode is fully supported. See [docs/environment.md](https://github.com/xaaha/hulak/blob/main/docs/environment.md) for more info
## Encrypted Secrets Vault Or Plaintext `.env` files
Hulak runs in two modes. Pick once during `hulak init`. You can migrate later.
- **Vault (default):** secrets live in `.hulak/store.age`, encrypted with an age or SSH keypair. Safe to commit. Teams share via a recipients file. See [docs/store.md](https://github.com/xaaha/hulak/blob/main/docs/store.md).
- **Plaintext:** secrets live in plaintext `env/*.env` files. Simpler, no encryption. Add `env/` to `.gitignore`. See [docs/environment.md](https://github.com/xaaha/hulak/blob/main/docs/environment.md).
Running classic and want to switch? See [docs/migrating-to-vault.md](https://github.com/xaaha/hulak/blob/main/docs/migrating-to-vault.md).
## Use it from an AI agent (MCP)
Hulak ships a built-in [MCP](https://modelcontextprotocol.io) 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:
```bash
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](https://github.com/xaaha/hulak/blob/main/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](https://github.com/xaaha/hulak/blob/main/docs/mcp.md).
## Commands
| Command | Purpose | Read more |
| --------- | -------------------------------------- | ---------------------------------------------------------- |
| `run` | Execute request file(s) or a directory | [body.md](https://github.com/xaaha/hulak/blob/main/docs/body.md), [actions.md](https://github.com/xaaha/hulak/blob/main/docs/actions.md) |
| `gql` | GraphQL explorer TUI | [graphql-explorer.md](https://github.com/xaaha/hulak/blob/main/docs/graphql-explorer.md) |
| `secrets` | Encrypted vault CRUD | [store.md](https://github.com/xaaha/hulak/blob/main/docs/store.md) |
| `init` | Initialize a hulak project | [store.md](https://github.com/xaaha/hulak/blob/main/docs/store.md) |
| `migrate` | Postman to hulak conversion | [migrating-to-vault.md](https://github.com/xaaha/hulak/blob/main/docs/migrating-to-vault.md) |
| `example` | Scaffold sample request files | — |
| `doctor` | Check project health | — |
| `mcp` | Serve requests to AI agents over MCP | [mcp.md](https://github.com/xaaha/hulak/blob/main/docs/mcp.md) |
| `version` | Print version | — |
Run `hulak <command> --help` for flags and per-command examples.
### Picker behavior
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`).
- Non-interactive shells require `--env <name>`.
## Common Pitfalls
- **Never commit `~/.config/hulak/identity.txt`.** That is your private key. Mode 0600. Back it up first. See [docs/store.md#identity-backup](https://github.com/xaaha/hulak/blob/main/docs/store.md#identity-backup).
- **On `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`.
- **GUI editors need a wait flag for `secrets edit`.** Use `EDITOR="code -w"` or `EDITOR="zed --wait"`. Without it the editor returns immediately and changes are lost.
- **Merge conflicts on `store.age` need a recipe.** See [docs/versioning.md#merge-conflicts](https://github.com/xaaha/hulak/blob/main/docs/versioning.md#merge-conflicts).
## Project layout
```text
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.
```
## GraphQL Explorer
Start the explorer with a file or a directory:
```bash
hulak gql e2etests/gql_schemas/countries.yml
hulak gql .
hulak gql -env staging ./collections/graphql
```
Read the full guide in [docs/graphql-explorer.md](https://github.com/xaaha/hulak/blob/main/docs/graphql-explorer.md).
## Documentation
Start here for the full reference:
- [Encrypted Store](https://github.com/xaaha/hulak/blob/main/docs/store.md). Encryption model, team sharing, CI.
- [Migrating to the Vault](https://github.com/xaaha/hulak/blob/main/docs/migrating-to-vault.md). From `env/` to `.hulak/`.
- [Versioning Your Vault](https://github.com/xaaha/hulak/blob/main/docs/versioning.md). Git workflow for secrets.
- [Comparison](https://github.com/xaaha/hulak/blob/main/docs/comparison.md). Hulak vs SOPS, Bruno, and friends.
- [Request Body](https://github.com/xaaha/hulak/blob/main/docs/body.md)
- [Actions](https://github.com/xaaha/hulak/blob/main/docs/actions.md)
- [Environment Secrets (classic mode)](https://github.com/xaaha/hulak/blob/main/docs/environment.md)
- [Response Files](https://github.com/xaaha/hulak/blob/main/docs/response.md)
- [GraphQL Explorer](https://github.com/xaaha/hulak/blob/main/docs/graphql-explorer.md)
- [Auth 2.0](https://github.com/xaaha/hulak/blob/main/docs/auth20.md)
- [MCP Server](https://github.com/xaaha/hulak/blob/main/docs/mcp.md). Expose your requests to AI agents.
For the live command surface, run:
```bash
hulak help
hulak <command> --help
```
## Schema Support
The Hulak schema is available in the [Schema Store](https://www.schemastore.org/), 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:
```text
https://raw.githubusercontent.com/xaaha/hulak/refs/heads/main/assets/schema.json
```
## Contributing
```bash
git clone https://github.com/xaaha/hulak.git
cd hulak
mise install
```
See [CONTRIBUTING.md](https://github.com/xaaha/hulak/blob/main/CONTRIBUTING.md) for the full development workflow.
## Support the Project
If Hulak is useful to you, open an issue, suggest a feature, send a pull request, or sponsor the project.