Complete reference for the Abbyfile framework: options, subcommands, flags, and types.
All options are in pkg/agent/options.go.
Required. Sets the agent name. Used for the CLI binary name, memory directory (~/.abbyfile/<name>/), override path, and MCP server identity.
Required. Sets the semantic version. Surfaces via --version, --describe, and MCP handshake.
Sets a short description. Shows in --describe JSON, MCP server metadata, and the Cobra help text.
Required. Sets the embedded filesystem and the path within it for the system prompt. This is set automatically by abby build — you do not need to call it directly.
Registers tool definitions. Variadic -- accepts multiple definitions. Can be called multiple times; definitions accumulate.
agent.WithTools(
tools.CLI("date", "date", "Get the current date"),
myBuiltinTool(),
)Sets the timeout for tool execution. Default: 30 * time.Second. Applies to both CLI and builtin tools.
Enables or disables persistent memory. Default: false. When enabled, creates a FileStore at ~/.abbyfile/<name>/memory/ and registers four memory tools (memory_read, memory_write, memory_list, memory_delete).
Sets capacity limits for the memory store. Only meaningful when memory is enabled.
Sets the agent's model hint. This is informational metadata — the runtime (Claude Code, etc.) picks its own model. The value is surfaced in --describe JSON and as a "Model Preference" hint in MCP server instructions.
Enables lazy tool loading via the search_tools meta-tool. When enabled, the MCP server only registers search_tools and get_instructions initially; clients discover other tools by searching.
Overrides the default config.yaml location (~/.abbyfile/<name>/config.yaml). Primarily useful for testing.
Sets the structured logger. Default: slog.NewTextHandler(os.Stderr, nil). Logs go to stderr so they do not interfere with MCP protocol on stdout.
Usage:
<agent-name> [flags]
<agent-name> [command]
Flags:
--version Print version and exit
--describe Print agent manifest as JSON and exit
--custom-instructions Print the system prompt and exit
-h, --help Help for the agent
Execute a registered tool by name.
Usage:
<agent-name> run-tool <name> [flags]
Flags:
--input string Tool input as JSON object
Examples:
./my-agent run-tool date
./my-agent run-tool read_file --input '{"path": "go.mod"}'
./my-agent run-tool go_test --input '{"package": "./pkg/tools/..."}'Manage persistent memory. Only available when memory is enabled.
Usage:
<agent-name> memory [command]
Commands:
read <key> Read a value from memory
write <key> <value> Write a value to memory (overwrites existing)
append <key> <value> Append content to an existing memory key
list List all memory keys
delete <key> Delete a key from memory
Inspect and modify runtime configuration overrides stored at ~/.abbyfile/<name>/config.yaml.
Usage:
<agent-name> config [command]
Commands:
get [field] Show configuration (compiled defaults + overrides)
set <field> <value> Set a config override
reset <field> Remove an override, reverting to compiled default
path Print the config file path
Examples:
./my-agent config get # show all fields with source
./my-agent config get model # show just model
./my-agent config set model opus # set override
./my-agent config set tool_timeout 120s # set timeout override
./my-agent config reset model # revert to compiled default
./my-agent config path # ~/.abbyfile/my-agent/config.yamlOutput format for get:
model: opus (override)
tool_timeout: 30s (compiled)
Supported fields for set/reset: model, tool_timeout. Complex fields (memory_limits, command_policy) can be set by editing the YAML directly.
When reset removes the last field, the config file is deleted.
Start an MCP-over-stdio server.
Usage:
<agent-name> serve-mcp
No flags. The server runs until the stdin stream closes or the process is killed. Logs go to stderr.
Check that the agent is configured correctly.
Usage:
<agent-name> validate
Checks performed:
- Prompt: loads the system prompt (embedded or override)
- Tools: for CLI tools, verifies the command exists in PATH; for builtin tools, verifies the handler is non-nil
- Memory: if enabled, verifies the memory directory is writable
- Override: reports whether an override file is active
- Version: verifies the version string is set
Output format:
[PASS] Prompt: loaded (245 bytes)
[PASS] Tool "date": command "date" found at /bin/date
[PASS] Tool "read_file": builtin handler registered
[PASS] Memory: directory /Users/you/.abbyfile/my-agent/memory is writable
[INFO] Override: not active (using embedded prompt)
[PASS] Version: 0.1.0
----------------------------------------
Validation PASSED
{
"name": "string",
"version": "string",
"description": "string",
"model": "string",
"toolTimeout": "30s",
"tools": [
{
"name": "string",
"description": "string",
"builtin": false,
"inputSchema": { },
"annotations": {
"ReadOnlyHint": false,
"DestructiveHint": null,
"IdempotentHint": false,
"OpenWorldHint": null,
"Title": ""
}
}
],
"memory": true,
"memoryLimits": {
"maxKeys": 0,
"maxValueBytes": 0,
"maxTotalBytes": 0
}
}Notes:
modelis only present if set (compiled default or config override)toolTimeoutis only present if non-defaulttoolsincludes both user-registered tools and memory tools (if enabled)memoryLimitsis only present when memory is enabled and limits are setannotationsis only present when set on the tool definitionbuiltinistruefor builtin tools and memory tools,falsefor CLI tools
func CLI(name, command, description string) *DefinitionCreates a Definition for a CLI tool that runs command as a subprocess.
Generated input schema:
{
"type": "object",
"properties": {
"args": {
"type": "string",
"description": "Command-line arguments to pass to the tool"
}
}
}The returned Definition can be further configured:
def.Args = []string{...}-- set default argumentsdef.WithAnnotations(&tools.Annotations{...})-- set MCP hints
func BuiltinTool(name, description string, schema any, handler func(input map[string]any) (string, error)) *DefinitionCreates a Definition for a builtin tool that runs the handler function in-process.
Parameters:
name-- unique tool namedescription-- shown to the LLM for tool selectionschema-- JSON Schema asmap[string]any(ornilfor no input)handler-- function that receives parsed JSON input and returns a string result
type Definition struct {
Name string
Description string
InputSchema any
Annotations *Annotations
Builtin bool
Command string // CLI tools only
Args []string // CLI tools only, default arguments
Handler func(input map[string]any) (string, error) // builtin tools only
}Methods:
Sets MCP annotation hints. Returns the definition for chaining.
Validates input against the InputSchema. Checks required fields and property types. Returns nil if valid or if schema is nil.
type Annotations struct {
ReadOnlyHint bool // tool does not modify state
DestructiveHint *bool // nil = MCP default (true)
IdempotentHint bool // safe to call multiple times
OpenWorldHint *bool // nil = MCP default (true)
Title string // human-readable name
}Use tools.BoolPtr(b bool) *bool to set pointer fields:
DestructiveHint: tools.BoolPtr(false),
OpenWorldHint: tools.BoolPtr(false),func NewExecutor(timeout time.Duration, logger *slog.Logger) *ExecutorCreates an executor with the given timeout and logger. Zero timeout defaults to 30 seconds. Nil logger disables logging.
func (e *Executor) Run(ctx context.Context, def *Definition, input map[string]any) (string, error)Runs a tool. For CLI tools, executes the command as a subprocess. For builtin tools, calls the handler. Returns trimmed stdout (or stderr if stdout is empty) for CLI tools.
func NewRegistry() *Registryfunc (r *Registry) Register(def *Definition) error // add a tool (error if name empty or duplicate)
func (r *Registry) Get(name string) *Definition // get by name (nil if not found)
func (r *Registry) All() []*Definition // all registered toolstype Limits struct {
MaxKeys int `json:"maxKeys,omitempty"` // max number of keys (0 = unlimited)
MaxValueBytes int64 `json:"maxValueBytes,omitempty"` // max bytes per value (0 = unlimited)
MaxTotalBytes int64 `json:"maxTotalBytes,omitempty"` // max total bytes (0 = unlimited)
}Zero values mean unlimited. Pass the zero value memory.Limits{} for no limits.
func NewFileStore(agentName string, limits Limits) (*FileStore, error)Creates a file store at ~/.abbyfile/<agentName>/memory/. Creates the directory if it does not exist.
func NewFileStoreAt(dir string, limits Limits) (*FileStore, error)Creates a file store at a specific directory. Used for testing.
func (s *FileStore) Read(key string) (string, error)
func (s *FileStore) Write(key, content string) error
func (s *FileStore) Append(key, content string) error
func (s *FileStore) Delete(key string) error
func (s *FileStore) Keys() ([]string, error)Keys must not be empty or contain path separators. Each key is stored as <dir>/<key>.md.
func NewManager(store *FileStore) *ManagerWraps a FileStore with a sync.RWMutex for concurrent access.
func (m *Manager) Get(key string) (string, error)
func (m *Manager) Set(key, value string) error
func (m *Manager) Append(key, value string) error
func (m *Manager) Delete(key string) error
func (m *Manager) Keys() ([]string, error)
func (m *Manager) Tools() []*tools.Definition
func (m *Manager) FormatKeysAsContext() stringTools() returns four builtin tool definitions: memory_read, memory_write, memory_list, memory_delete.
FormatKeysAsContext() returns a string like "Available memory keys: notes, config" or empty string if no keys.
func NewLoader(agentName string, fs embed.FS, path string) *LoaderCreated automatically by generated binaries. The embed.FS is populated by abby build.
func (l *Loader) Load() (string, error) // load prompt (override or embedded)
func (l *Loader) IsOverridden() bool // true if override file exists
func (l *Loader) OverridePath() string // ~/.abbyfile/<name>/override.mdfunc NewBridge(cfg BridgeConfig) *Bridgetype BridgeConfig struct {
Name string
Version string
Description string
Model string // model hint, appended to instructions
Registry *tools.Registry
Executor *tools.Executor
Loader *prompt.Loader
Memory *memory.Manager // nil if memory disabled
Logger *slog.Logger // nil disables logging
LazyToolLoading bool // only register search_tools initially
}func (b *Bridge) Serve(ctx context.Context) error // stdio transport
func (b *Bridge) ServeTransport(ctx context.Context, transport gomcp.Transport) error // any transportUsage:
abby build [flags]
Flags:
-f, --file string Path to Abbyfile (default: auto-detect Abbyfile or abbyfile.yaml)
-o, --output string Output directory for binaries (default: "./build")
--agent string Build a single agent by name
--plugin Also generate a Claude Code plugin directory
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default: "auto")
Parses the Abbyfile, generates Go source from each agent's .md file, and compiles standalone binaries. Also generates/updates MCP config for the target runtime(s).
The --runtime flag controls which runtimes receive MCP config:
auto(default) — detects installed runtimes by checking for their global config directories, falls back to Claude Codeall— generates config for all supported runtimes (Claude Code, Codex, Gemini CLI)claude-code/codex/gemini— targets a specific runtime
| Runtime | Local Config | Global Config |
|---|---|---|
| Claude Code | .mcp.json |
~/.claude/mcp.json |
| Codex | .codex/config.toml |
~/.codex/config.toml |
| Gemini CLI | .gemini/settings.json |
~/.gemini/settings.json |
When --plugin is passed, each agent also gets a <name>.claude-plugin/ directory in the output folder containing the binary, an MCP config, and any declared skills. See Plugins guide.
Usage:
abby install [flags] <ref>...
Flags:
--all Install all agents from a repo (remote) or ./build/ (local)
-g, --global Install globally to /usr/local/bin
--model string Override the agent's model in ~/.abbyfile/<name>/config.yaml
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default: "auto")
Installs agent binaries and wires them into the MCP config for detected (or specified) runtimes.
Local install (from ./build/):
abby install my-agent
abby install -g my-agentRemote install (from GitHub Releases):
abby install github.com/owner/repo/agent
abby install github.com/owner/repo/agent@1.0.0Bulk install (multiple agents at once):
abby install --all github.com/owner/repo # all agents from a repo
abby install --all # all agents from ./build/
abby install github.com/o/r/a1 github.com/o/r/a2 # specific agents
abby install github.com/org1/r1/a1 github.com/org2/r2/a2 # cross-repoRemote --all discovers agents by scanning release tags (<agent>/v<version> format) and installs the latest version of each. Multiple positional arguments can reference agents from different repos.
Bulk installs use best-effort error handling: failures are reported but don't stop remaining installs. A summary is printed at the end.
The --model flag cannot be combined with --all or multiple agents (it is agent-specific).
Remote install downloads the binary for the current platform (<agent>-<GOOS>-<GOARCH>), verifies it with --describe, installs it, wires MCP, and tracks it in the registry. Set GITHUB_TOKEN for private repos.
Both local and remote installs are tracked in ~/.abbyfile/registry.json.
Usage:
abby publish [flags]
Flags:
-f, --file string Path to Abbyfile (default: auto-detect Abbyfile or abbyfile.yaml)
--agent string Publish a single agent by name
--dry-run Cross-compile only, skip GitHub Release creation
Cross-compiles agent binaries for 4 platforms (darwin/amd64, darwin/arm64, linux/amd64, linux/arm64) and creates a GitHub Release via the gh CLI.
Release tag format: <agent>/v<version>. Binary asset naming: <agent>-<os>-<arch>.
Requires the gh CLI to be installed and authenticated.
Usage:
abby list
Shows all installed agents from the registry (~/.abbyfile/registry.json). Displays name, version, source, scope, and path in a table.
Usage:
abby update [agent-name]
Checks GitHub Releases for newer versions of installed agents and downloads updates. Only agents installed from a remote source can be updated.
If no agent name is given, checks all remote-installed agents.
Usage:
abby uninstall <agent-name> [flags]
Flags:
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default: "auto")
Removes an installed agent: deletes the binary, removes the MCP entry from all detected (or specified) runtime configs, and removes the entry from the registry.
type Entry struct {
Name string `json:"name"`
Source string `json:"source"` // "local" or "github.com/owner/repo/agent"
Version string `json:"version"`
Path string `json:"path"` // absolute path to installed binary
Scope string `json:"scope"` // "local" or "global"
InstalledAt string `json:"installedAt"` // RFC3339 timestamp
}func DefaultPath() (string, error) // ~/.abbyfile/registry.json
func Load(path string) (*Registry, error) // load from disk (empty if not exists)
func (r *Registry) Save() error // atomic save (write temp + rename)
func (r *Registry) Set(e Entry) // add or update entry
func (r *Registry) Get(name string) (Entry, bool)
func (r *Registry) Remove(name string)
func (r *Registry) List() []Entrytype ReleaseRef struct {
Owner string // repository owner
Repo string // repository name
Agent string // agent name (defaults to repo name)
Version string // specific version or "" for latest
}func NewClient() *Client // reads GITHUB_TOKEN from env
func ParseRef(ref string) (ReleaseRef, error)
func IsRemoteRef(ref string) bool
func ResolveAssetName(agentName string) string // <name>-<GOOS>-<GOARCH>
func FindAsset(release *Release, agentName string) (*Asset, error)
func VersionFromTag(tag string) string
func CompareVersions(a, b string) (int, error) // -1, 0, or 1func (c *Client) LatestRelease(ctx context.Context, ref ReleaseRef) (*Release, error)
func (c *Client) GetRelease(ctx context.Context, ref ReleaseRef) (*Release, error)
func (c *Client) DownloadAsset(ctx context.Context, asset Asset, w io.Writer) errortype BuildConfig struct {
OutputDir string // directory for compiled binaries
ModuleDir string // local abbyfile module path (for replace directive)
TargetOS string // GOOS for cross-compilation (empty = native)
TargetArch string // GOARCH for cross-compilation (empty = native)
}When TargetOS and TargetArch are set, the binary name becomes <agent>-<os>-<arch> and CGO_ENABLED=0 is set for static cross-compilation.
type SkillDef struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Path string `yaml:"path"` // relative to agent .md file
}Declared in block 2 of agent .md files under skills:. Used by --plugin to generate skill files in the plugin directory. All three fields are required.
type GenerateConfig struct {
OutputDir string // parent directory (e.g., "build")
BinaryPath string // path to the compiled binary
}type SkillFile struct {
Name string
Description string
Content string // markdown body
}func Generate(def *definition.AgentDef, skills []SkillFile, cfg GenerateConfig) errorCreates a <outputDir>/<name>.claude-plugin/ directory containing:
.claude-plugin/plugin.json— name, version, description,"abbyfile": true.mcp.json—{ "mcpServers": { "<name>": { "command": "./<name>", "args": ["serve-mcp"] } } }<name>— copy of the compiled binary (executable)skills/<skill-name>/SKILL.md— for each skill, with frontmatter (name, description) + content