Install
$ agentstack add mcp-subzone-agentctl ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
AgentCTL
> The CLI binary is m for ergonomics — the product name is AgentCTL.
A small, single-binary CLI for running AI agents defined as Markdown files against your choice of LLM. Aimed at developers and DevOps people who live in the terminal and want to script agentic work without IDE lock-in or SDK sprawl.
Current version: v0.8.3 | Go version: 1.26+ | Binary size: ~8.4 MB | Docker image: ~16 MB
Status: beta. Desktop control plane with MoE chat, extensions, knowledge graph, and session persistence. Tagged releases ship CLI packages and AgentCTL desktop builds.
$ m
» fix the failing test in api/handler.go
→ fs_read api/handler.go
→ shell go test ./api/...
→ fs_write api/handler.go (patch: nil check)
Overwrite api/handler.go? [y/N]: y
→ shell go test ./api/...
PASS
→ git commit -m "fix: nil check in handler"
Full docs site (EN + SR): ****
Quick Start (5 minutes)
# 1. Install (macOS — pick one)
brew tap subzone/tap && brew install subzone/tap/m
# or: curl -sL https://github.com/subzone/Agentctl/releases/latest/download/m_0.1.1_macos.pkg -o m.pkg && sudo installer -pkg m.pkg -target /
# 2. Run the setup wizard
m
# Pick Ollama (free, local) or paste an API key for Anthropic/OpenAI/Gemini/Alibaba
# 3. Your first chat (with Steva Đubre fixing himself!)
» help me fix the failing test in internal/engine/engine_test.go
→ fs_read internal/engine/engine_test.go
→ shell go test ./internal/engine/...
→ fs_write internal/engine/engine_test.go (patch: add nil check)
Overwrite? [y/N]: y
→ shell go test ./internal/engine/...
PASS
→ git commit -m "fix: nil check in engine test"
# 4. Slash commands
» /help # show available commands
» /reset # clear history
» /undo # revert last fs_write
» /model ollama/qwen3-coder # switch model mid-session
» /exit # leave
# 5. Run a specific agent
m run examples/agents/devops.md "review the Dockerfile"
m chat examples/agents/coder.md
# 6. Pipe mode — use with Unix tools
cat error.log | m pipe "explain this error"
git diff | m pipe "write a commit message"
kubectl get pods | m pipe "which pods are unhealthy?"
# 7. Reference files in chat with @
» @main.go fix the nil check on line 42
# (file content is auto-inlined — no tool call needed)
# 8. Create your own agent
m new my-agent
# edit my-agent.md, then: m chat my-agent
# 9. Check your setup
m doctor
# 10. See what the agent changed
m diff
# 11. Track costs
m cost
# 12. Shell completions
m completion zsh > "${fpath[1]}/_m"
Why this exists
- Agents are files, not config — define an agent as a Markdown file with
YAML frontmatter, version it in git alongside your code, share it like any other source file.
- No LLM SDK dependencies — every provider client is plain
net/http+
encoding/json. The build won't break when a vendor SDK changes.
- CLI-first, IDE-agnostic — pipes, scripts, cron, CI all work because
it's a normal binary that reads stdin and writes stdout.
- Plays well with existing tooling —
kubectl,terraform,helm,
git, make are reachable through the shell tool. Not a replacement for Cursor or Claude Code; a complementary tool for terminal-driven dev/DevOps work.
Install
| Platform | How | |----------|-----| | macOS (Homebrew) | brew tap subzone/tap && brew install subzone/tap/m | | macOS (pkg) | Download .pkg from [latest release][releases] → double-click. Installs to /usr/local/bin/m. | | Windows | Download .zip from [latest release][releases] → extract m.exe to a folder on your PATH. | | Linux (Debian/Ubuntu) | sudo dpkg -i m_*_linux_amd64.deb | | Linux (other) | Tarball: tar -xzf m_*_linux_amd64.tar.gz && sudo mv m /usr/local/bin/ | | From source | go install github.com/subzone/Agentctl/cmd/m@latest (requires Go 1.26+) |
First run launches a setup wizard:
m
# Pick a provider (Ollama / Anthropic / OpenAI / Gemini / Alibaba / LiteLLM)
# Paste an API key (or skip for Ollama)
# Done — drops you into a chat with the default agent
Verify your setup:
m doctor
# Checks config, API key, model reachability, tools (git, grep, rg)
Shell completions
# bash
m completion bash > /etc/bash_completion.d/m
# zsh
m completion zsh > "${fpath[1]}/_m"
# fish
m completion fish > ~/.config/fish/completions/m.fish
API keys are stored in the OS keychain (macOS Keychain / Linux libsecret). Never in config files, never in plaintext.
Auto-update notifications
AgentCTL checks GitHub for new releases once per day. If a newer version exists, you'll see a dim notice on startup:
↑ update available: v0.0.29 → v0.0.32 (brew upgrade subzone/tap/m)
This is non-blocking, cached, and silent on errors. No data is sent — it only reads the public releases API.
API key fallback
If you don't want to use the keychain (or secret-tool isn't installed on Linux), you can set API keys via environment variables instead:
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
export GEMINI_API_KEY=...
export DASHSCOPE_API_KEY=... # Alibaba
export LITELLM_API_KEY=...
The CLI checks keychain first, then falls back to the environment variable. This works for both the main m command and for model discovery (m config scan).
Defining an agent
A complete agent is one Markdown file:
---
name: devops
type: agent
model: anthropic/claude-sonnet-4-6
fallback:
- anthropic/claude-haiku-4-5-20251001
- openai/gpt-4.1
tools:
- shell
- fs_read
- fs_write
- git
- test_run
- web_fetch
- code_search
temperature: 0.3
pii_guard: redact
thinking_phrases:
- "analyzing"
- "reading code"
- "checking config"
---
You are a DevOps engineer.
Explore the project with fs_list before editing.
Make targeted changes with fs_write.
Always consider security.
Fallback models: when the primary model returns 429 (rate limit), the agent automatically tries the next model in the fallback list. The session switches to the first one that works.
Thinking phrases: customize the spinner text shown while the agent works. Overrides theme defaults. Useful for non-English agents.
Run it:
m chat examples/agents/devops.md
m run examples/agents/devops.md "audit the Dockerfile"
The repo ships 32 example agents in [examples/agents/](examples/agents/), including coder, reviewer, planner, k8s-debug, terraform-plan, helm-deploy, ticket-worker, plus persona variants (steva-djubre.md, steve-trash.md).
Bundled agents
All 32 example agents are embedded in the binary. No need to clone the repo — they're available immediately after install:
# List all available agents (bundled + user-created)
m list
# Run a bundled agent by name — extracted on first use
m chat devops
m run reviewer "check the auth module"
m chat steva-djubre
On first run (or when you reference a bundled agent), the .md file is extracted to ~/.config/m/agents/ (or ~/Library/Application Support/m/agents/ on macOS). You can edit these freely — your changes are never overwritten.
To reset a bundled agent to its original version, just delete it and run again:
rm ~/.config/m/agents/devops.md
m chat devops # re-extracts the bundled version
Built-in tools
| Tool | Purpose | User confirmation | |-------------|------------------------------------------|-------------------| | shell | Run a shell command | yes (per call) | | fs_read | Read a file | no | | fs_write | Create or patch a file | yes (diff preview) | | fs_list | List a directory (recursive, skips .git/node_modules) | no | | git | Common git operations | yes for writes | | test_run | Run the project's test command | no | | web_fetch | Fetch a URL and extract readable text | no | | code_search| Search codebase: text (grep) + symbol index | no | | delegate | Call a sub-agent | no |
fs_write writes are reversible via /undo.
Providers
Selected per-agent via model: provider/model-name. Switch providers mid-session with /model provider/model.
| Provider | Transport | Notes | |------------|-------------|-------| | ollama | NDJSON | Local, free. Default for the wizard. | | anthropic| Custom SSE | Claude family. Native tool use, response-tool for structured output. | | openai | OpenAI SSE | GPT-4o / GPT-4.1. json_schema strict mode. | | gemini | OpenAI-compat | gemini-2.5-pro / flash via Google's OpenAI-compat endpoint. | | alibaba | OpenAI-compat | DashScope: qwen-plus / turbo / max. | | litellm | OpenAI-compat | Proxy passthrough — opens up ~100 more models. |
All clients are stdlib-only. Gemini, Alibaba and LiteLLM use a WithCompat() flag that disables OpenAI-specific stream options.
MCP integrations
Five MCP server definitions ship in [examples/mcp/](examples/mcp/):
github— PR/issue/repo operations (stdio)jira— search, read, create, update, transition issues (stdio)confluence— search, read, create, update pages (stdio)datadog— monitoring, alerts, dashboards (HTTP)slack— channels, messages, users (SSE)
Reference one from an agent:
mcp: [jira, confluence]
Tools are namespaced (jira__get_issue, confluence__update_page) and merged into the same registry as built-ins. Supported transports:
| Transport | How it works | |-----------|-------------| | stdio | Spawns a subprocess, JSON-RPC over stdin/stdout | | http | POST JSON-RPC to a URL, get JSON-RPC response | | sse | POST JSON-RPC, receive response via Server-Sent Events |
Pipe mode
m pipe reads stdin, applies an instruction, and writes to stdout. No REPL, no TUI — pure Unix pipe:
# Explain an error
cat error.log | m pipe "explain this error and suggest a fix"
# Generate a commit message from a diff
git diff --staged | m pipe "write a conventional commit message"
# Analyze infrastructure
kubectl get pods -A | m pipe "which pods are unhealthy and why?"
# Chain agents
m run reviewer "check auth" | m pipe "summarize the issues as a TODO list"
# Override model
cat main.go | m pipe -m openai/gpt-4.1 "find bugs"
@file context
Reference files directly in your prompt with @path. The file content is automatically inlined — no tool call needed:
» @src/handler.go fix the nil pointer on line 42
included: src/handler.go
→ fs_write src/handler.go (patch: add nil check)
» @Dockerfile @docker-compose.yml optimize for smaller image size
included: Dockerfile, docker-compose.yml
Works in both REPL and TUI. Paths are relative to cwd.
MCP server management
Install and configure MCP servers with one command:
# List available MCP server definitions
m mcp list
# Check what's installed
m mcp status
# Install + configure a server (installs binary, prompts for credentials)
m mcp setup jira
m mcp setup github
m mcp setup confluence
# Auto-setup ALL servers an agent needs
m mcp setup developer-hub
Credentials are stored in the OS keychain. Install methods (pip/npm/brew) are defined in the MCP server definition files.
Session management
# List saved sessions
m session list
# Export a session to JSON or Markdown
m session export _autosave --format json --output session.json
m session export fixing-auth --format markdown --output review.md
# Delete a session
m session delete old-session
# Track costs across sessions
m cost
Reviewing changes
After an agent session, review what was modified:
# Show all unstaged changes the agent made
m diff
# Show staged changes
m diff --staged
Slash commands (chat REPL)
| Command | Effect | |-------------|--------| | /help | Show available commands | | /exit, /quit | Leave the session | | /reset | Clear chat history | | /compact | Truncate history to last 4 exchanges | | /undo | Revert the most recent fs_write | | /config | Open interactive provider/model manager | | /spec | Show the agent's resolved spec | | /model | Switch provider/model mid-session | | /models | List available models, pick by number | | /save [name] | Save session snapshot — /save (timestamped) or /save fixing-auth (named) | | /sessions | List saved sessions | | /resume | Resume a saved session by id or number | | /themes | List available themes with descriptions | | /theme | Switch TUI theme |
Architecture
Hexagonal layout, ~8.8k LOC, 24 test files. No SDK dependencies for LLM clients.
cmd/m/ CLI entry, TUI, REPL, slash commands
internal/engine/ Session loop, tool dispatch, structured output
internal/llm/ Provider registry + 6 stdlib-only clients
internal/tools/ Built-in tool implementations
internal/mcp/ JSON-RPC stdio client, tool adapter
internal/config/ Frontmatter parsing, agent/MCP/skill schemas
internal/ports/ ConfigSource, Secrets, StateStore interfaces
internal/adapters/ Keychain (macOS/libsecret), file-backed stores
examples/agents/ 32 ready-to-use agents
examples/mcp/ 5 MCP server definitions
docs/ Static product site (EN + SR), GitHub Pages
The engine never sees provider-specific code — providers register themselves via init() + llm.Register(), and the engine only consumes a `Provider.Stream(ctx, req) →
- Discussions:
License
MIT. See [LICENSE](LICENSE).
[releases]: https://github.com/subzone/Agentctl/releases/latest
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: subzone
- Source: subzone/Agentctl
- License: MIT
- Homepage: https://subzone.github.io/Agentctl/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.