Jesse A. Green / notebook

goose Admin & Architecture Guide

Generated June 2026 from aaif-goose/goose at 2f99664

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide is the deep reference for administrators, platform engineers, and developers who deploy, operate, secure, extend, or embed goose — the open source on-machine AI agent. It covers the system architecture, the full configuration surface, security model, deployment topologies (including remote goosed and Docker), operations, and a source-level internals tour of the Rust workspace and TypeScript desktop app.

For end-user installation and usage, see the companion User Guide.


Table of Contents

  1. Executive Summary
  2. System Architecture
  3. Repository & Workspace Layout
  4. The Agent Engine (crates/goose)
  5. The goosed Server & Desktop App
  6. System Requirements
  7. Configuration Mastery
  8. Environment Variable Reference
  9. Security
  10. Deployment
  11. Operations
  12. Observability
  13. Developer Internals
  14. Embedding goose (SDKs)
  15. Testing Strategy
  16. Troubleshooting (Operational)
  17. Potential Improvements
  18. Quick Reference

1. Executive Summary

goose is a Rust-core, polyglot AI agent distributed as a CLI and a desktop application. Its job is to take a natural-language request, plan with an LLM, and execute real work through tools exposed by Model Context Protocol (MCP) extensions — running commands, editing files, calling APIs — while keeping the operator in control.

What an administrator needs to know up front:

Concern Summary
Language & license Rust (edition 2021, MSRV 1.91.1), TypeScript desktop; Apache-2.0. Workspace version 1.37.0.
Runtime model Local-first. The agent runs on the user's machine. No central server is required.
Two surfaces, one engine CLI binary (goose) and Desktop (Electron) both drive the same crates/goose engine. The Desktop spawns a local server, goosed, and talks to it over HTTP/WebSocket.
Model-agnostic 40+ LLM providers via a pluggable provider layer; nothing about the model is hard-coded.
Extensibility Capabilities come from MCP servers (bundled + third-party + custom).
Autonomy Autonomous by default — with the Developer extension goose runs commands and edits files. Governed by GOOSE_MODE, tool permissions, .gooseignore, and an extension allowlist.
Secrets System keyring by default; secrets.yaml fallback for headless/container environments.
Observability OpenTelemetry (traces/metrics/logs), optional Langfuse, opt-in PostHog telemetry.
Interop Implements Agent Client Protocol (ACP) as both server (editors drive goose) and client (goose delegates to Claude Code / Codex).

Important

The single most important operational fact: goose executes on the host as the invoking user, with that user's privileges, autonomously by default. Treat the autonomy mode, the extension allowlist, and .gooseignore as your primary control plane (see Security).


2. System Architecture

2.1 Component Model

goose has three logical components, regardless of interface:

  • Interface — collects input and renders output (Desktop app, CLI, TUI, or an ACP editor).
  • Agent — the core loop (in crates/goose) that orchestrates the model and tools.
  • Extensions — MCP servers exposing tools; bundled, third-party, or custom.
 ┌──────────────────────────────────────────────────────────────────────┐
 │                            INTERFACES                                  │
 │                                                                        │
 │  goose CLI        goose Desktop          goose TUI       ACP editors   │
 │  (goose-cli)      (ui/desktop, Electron) (ui/text)       (Zed/JetBrains)│
 │      │                  │  spawns                │  ACP        │ ACP   │
 │      │ in-proc          ▼  + HTTP/WS             │  stdio      ▼       │
 │      │            ┌───────────────┐              │      ┌────────────┐ │
 │      │            │   goosed       │◀─────────────┘      │ goose acp/ │ │
 │      │            │ (goose-server) │  HTTP+WS (X-Secret) │  serve     │ │
 │      │            └──────┬─────────┘                     └─────┬──────┘ │
 └──────┼───────────────────┼─────────────────────────────────────┼──────┘
        │                   │                                      │
        ▼                   ▼                                      ▼
 ┌──────────────────────────────────────────────────────────────────────┐
 │                       AGENT ENGINE  (crates/goose)                     │
 │                                                                        │
 │   Agent loop ── Providers ── Conversation/Context mgmt ── Sessions     │
 │   Recipes ── Scheduler ── Permissions ── Security ── Hooks ── Skills   │
 └───────────────┬───────────────────────────────────┬──────────────────┘
                 │ MCP (rmcp)                         │ Provider HTTP (reqwest/rustls)
                 ▼                                    ▼
 ┌──────────────────────────────┐        ┌──────────────────────────────┐
 │   EXTENSIONS (MCP servers)   │        │       LLM PROVIDERS           │
 │  bundled (goose-mcp):        │        │  Anthropic / OpenAI / Gemini  │
 │   developer, memory,         │        │  Bedrock / Databricks / Groq  │
 │   computercontroller, ...    │        │  Ollama / LM Studio (local)   │
 │  + any 3rd-party / custom    │        │  + 40 more                    │
 └──────────────────────────────┘        └──────────────────────────────┘

2.2 The Agent Loop

A single turn (implemented in crates/goose/src/agents):

  1. Request — user input enters via the interface.
  2. Provider chat — the agent sends the request plus the catalogue of available tools to the configured LLM provider.
  3. Tool call — the model may return a tool call (JSON). The model describes the action; goose executes it.
  4. Execute — the agent dispatches the call to the owning MCP extension and collects the result.
  5. Feed back — results return to the model; tool steps repeat as needed.
  6. Context revision — old/irrelevant content is dropped, verbose output summarized, to manage tokens and cost.
  7. Response — the model's final answer is rendered; the loop restarts on the next message.

Resilient error handling: invalid JSON, missing tools, and command failures are returned to the model as tool results (becoming "prompts" that let it self-correct) rather than aborting the session.

2.3 Key Protocols & Foundations

Concern Mechanism Crate/dep
Tool interop Model Context Protocol (MCP) rmcp 1.4
Editor/agent interop Agent Client Protocol (ACP) agent-client-protocol 0.11
HTTP server (goosed) Axum (HTTP/1, HTTP/2, WS) axum 0.8
Provider HTTP reqwest + Rustls (aws-lc-rs) reqwest 0.13, rustls 0.23
CLI parsing clap derive clap 4
Async runtime Tokio tokio 1.48
Local inference candle + llama.cpp (GGUF) candle-core 0.10, llama-cpp-2
Code intelligence tree-sitter (Go/Java/JS/TS/Py/Ruby/Rust/Swift/Kotlin) tree-sitter 0.26
Code Mode (JS exec) Vendored V8 vendor/v8 (patched)
Secret storage OS keyring keyring 3.6
Telemetry OpenTelemetry opentelemetry 0.32

3. Repository & Workspace Layout

The repository is a Cargo workspace (crates/*) plus separately-built TypeScript apps under ui/, a Docusaurus docs site, and supporting tooling.

3.1 Rust Crates (layered by responsibility)

Layer Crate Responsibility
Core engine crates/goose The agent: loop, providers, MCP client, recipes, sessions, scheduler, config, security, permissions, context management, local inference, ACP, gateways, skills, hooks. The heart of the system.
Interfaces crates/goose-cli The goose binary — clap CLI, interactive session UX, terminal integration, review, local-model management.
crates/goose-server goosed — the Axum HTTP/WebSocket server the Desktop talks to, and the ACP HTTP server.
Tools crates/goose-mcp Bundled MCP servers: Developer, Computer Controller, Memory, Tutorial, Auto Visualiser, and more.
SDK / embedding crates/goose-sdk Rust SDK for embedding goose (incl. UniFFI bindings for other languages).
crates/goose-sdk-types Shared SDK type definitions.
Support crates/goose-acp-macros Proc-macros for the ACP integration.
crates/goose-test, crates/goose-test-support Test harness, MCP test servers, fixtures.

Note

A *-macros/proc-macro crate (goose-acp-macros) plus a thin facade (goose-sdk over goose) is the classic Rust workspace shape: the macro crate enforces compile-time guarantees for the protocol layer, and the SDK re-exports the engine for embedders. Read each member's Cargo.toml for its exact description and target-specific dependencies.

3.2 Non-Crate Components

Path Stack Purpose
ui/desktop Electron + React + TypeScript The Desktop app. Thin shell that spawns goosed and renders the chat UI.
ui/text TypeScript (npm: @aaif/goose) The terminal UI (goose tui).
ui/sdk TypeScript Generated TS client for the goosed API.
documentation/ Docusaurus The docs site (the canonical user docs and extension catalog).
examples/ mixed Example extensions, plugins, MCP servers.
evals/ Python Benchmark/eval harnesses (harbor, open-model-gym).
services/ask-ai-bot TypeScript A Discord support bot.
oidc-proxy/ JavaScript OIDC proxy helper.
recipe-scanner/, workflow_recipes/ mixed Recipe tooling and CI workflow recipes.
scripts/ Python/shell Build, benchmark, and release tooling.
vendor/v8 vendored V8 engine for Code Mode JavaScript execution.

3.3 Build Tooling

  • Justfile — task runner (just generate-manpages, build helpers, etc.).
  • Dockerfile, BUILDING_DOCKER.md, BUILDING_LINUX.md — container & Linux builds.
  • CUSTOM_DISTROS.md — building custom/branded goose distributions.
  • flake.nix — Nix dev environment.
  • rust-toolchain.toml — pins the Rust toolchain (MSRV 1.91.1).

4. The Agent Engine (crates/goose)

crates/goose/src is the system's core. Key modules (an operator/extender's map):

Module Responsibility
agents/ The agent loop, tool dispatch, platform extensions, subagent execution
providers/ LLM provider implementations (one per provider) + declarative/ JSON model catalogs + local_inference/ (llama.cpp/GGUF)
config/ Config loading, paths, provider config, signup flows (OpenRouter/Tetrate/NanoGPT)
recipe/ Recipe parsing, templating, building, deeplinks
session/ Session lifecycle, persistence, import/export formats
scheduler.rs, scheduler_trait.rs Built-in cron scheduler for recipes
context_mgmt/, conversation/ Token management, context revision, compaction
permission/ Tool permission levels and decisions
security/ Prompt-injection detection, package malware scanning
acp/ Agent Client Protocol server + transport
gateway/ Platform gateways (e.g. Telegram)
skills/, plugins/, hooks/ Skills, git-backed plugins, lifecycle hooks
oauth/ OAuth flows for providers and MCP servers
mcp_utils.rs, subprocess.rs MCP client helpers; subprocess management for stdio extensions
model.rs, token_counter.rs Model abstraction, context limits, token counting
otel/, tracing/, posthog.rs, logging.rs Observability and telemetry
doctor.rs, checks/ goose doctor health checks

4.1 The Extension/Tool Contract

Extensions implement a Rust Extension trait (for bundled extensions) or speak MCP over stdio/Streamable HTTP (for external ones). The trait:

#[async_trait]
pub trait Extension: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn instructions(&self) -> &str;
    fn tools(&self) -> &[Tool];
    async fn status(&self) -> AnyhowResult<HashMap<String, Value>>;
    async fn call_tool(&self, tool_name: &str,
                       parameters: HashMap<String, Value>) -> ToolResult<Value>;
}

Each tool is async, takes a JSON Value, and returns a ToolResult<Value>. Errors come in two flavors: ErrorData (tool-execution errors that are surfaced back to the model as prompts) and anyhow::Error (general extension errors). This split is deliberate — tool errors become part of the conversation so the model can recover.

Tip

When building a bundled extension, return specific ErrorData messages — they become prompts the model reads. Vague errors waste a turn; precise ones ("file not found at /x; did you mean /y?") let the model self-correct immediately.


5. The goosed Server & Desktop App

5.1 What goosed Is

goosed (built from crates/goose-server) is an Axum HTTP + WebSocket server that exposes the agent engine as an API. The Desktop app spawns goosed as a local subprocess and drives it over HTTP/WebSocket. goosed is also what goose serve runs for ACP-over-HTTP.

5.2 The goosed API Surface

Routes live in crates/goose-server/src/routes/. They are not a public, unauthenticated API — every request requires the shared secret in the X-Secret-Key header (see below). Route groups:

Route module Purpose
agent.rs Create/configure agents, run the loop
reply.rs, session.rs, session_events.rs Send messages; manage sessions; stream events (SSE)
recipe.rs, recipe_utils.rs Recipe execution and utilities
schedule.rs Scheduled-job management
config_management.rs, setup.rs Read/write config; first-run setup
status.rs, features.rs Health/status; feature flags
prompts.rs, sampling.rs Prompt templates; MCP sampling
local_inference.rs Local GGUF model management
gateway.rs, tunnel.rs Gateways; remote tunneling
dictation.rs Voice dictation
action_required.rs Approval/elicitation prompts
mcp_app_proxy.rs, mcp_ui_proxy.rs Proxies for MCP Apps / MCP UI
telemetry.rs Telemetry endpoints

5.3 Securing goosed

Every client request must carry the shared secret:

Variable Purpose Default
GOOSE_HOST Interface to bind. 127.0.0.1 = local only; 0.0.0.0 = network-reachable 127.0.0.1
GOOSE_PORT TCP port 3000
GOOSE_TLS Enable TLS with a self-signed cert (required for remote Desktop connections) true
GOOSE_SERVER__SECRET_KEY Shared secret required in the X-Secret-Key header on all requests random (auto-generated)
# A network-reachable goosed over TLS with a fixed secret
export GOOSE_HOST=0.0.0.0
export GOOSE_PORT=3000
export GOOSE_TLS=true
export GOOSE_SERVER__SECRET_KEY='a-long-random-secret'
goosed agent

Caution

Binding goosed to 0.0.0.0 exposes an agent that can execute commands on the host to the network. Always keep TLS on, set a strong GOOSE_SERVER__SECRET_KEY, and restrict access at the network layer (firewall/VPN). On startup with TLS, goosed prints GOOSED_CERT_FINGERPRINT=...; clients need it to verify the self-signed cert. See Remote goose Server.

5.4 The Desktop App

ui/desktop is an Electron + React (TypeScript) app. It:

  • Locates and spawns the goosed binary (GOOSED_BINARY, GOOSE_EXTERNAL_BACKEND, GOOSE_PORT).
  • Talks to goosed over the local HTTP/WS API.
  • Handles desktop concerns: auto-update (autoUpdater.ts, githubUpdater.ts), proxy settings (HTTP_PROXY/HTTPS_PROXY/NO_PROXY), deep links (goose://), localization, and platform shims (Windows winShims.ts).
  • Shares all core config with the CLI via the same config.yaml and keyring, so settings made in one surface apply to the other.

6. System Requirements

Requirement Detail
OS macOS, Linux (Debian/Ubuntu DEB provided), Windows 10/11 (native via Git Bash/MSYS2/PowerShell, or WSL)
An LLM A provider API key, a subscription (ChatGPT/Copilot/Tetrate), or a local model. Tool-calling support is required for full functionality.
Package runners (for external extensions) Node.js (npx) and/or uv (uvx); optionally jbang (Java/Kotlin, Linux/macOS only), Docker
Network Outbound HTTPS to your provider (unless fully local). Proxy-aware.
Disk Modest for goose itself; local GGUF models can be large
Build-from-source Rust toolchain pinned by rust-toolchain.toml (MSRV 1.91.1), plus Node for the desktop/TUI

Note

goose stores data per-platform: macOS ~/Library/Application Support/Block/goose/, Linux ~/.local/share/goose/, Windows %APPDATA%\Block\goose\. Config lives in ~/.config/goose/ (macOS/Linux) or %APPDATA%\Block\goose\config\ (Windows). Override the root with GOOSE_PATH_ROOT.


7. Configuration Mastery

7.1 Configuration Files

File Purpose
config.yaml Provider, model, extensions, and general settings
permission.yaml Tool permission levels (managed via goose configure)
secrets.yaml API keys/secrets (only when file-based storage is in use)
permissions/tool_permissions.json Runtime permission decisions (auto-managed)
prompts/ Customized prompt templates
custom_providers/*.json Custom provider definitions

Locations: ~/.config/goose/ (macOS/Linux) or %APPDATA%\Block\goose\config\ (Windows).

7.2 Configuration Precedence

1. Environment variables   (highest priority)
2. config.yaml settings
3. Built-in defaults       (lowest priority)

7.3 A Complete config.yaml

# --- Model Configuration ---
GOOSE_PROVIDER: "anthropic"
GOOSE_MODEL: "claude-4.5-sonnet"
GOOSE_TEMPERATURE: 0.7

# --- Planning (optional separate model) ---
GOOSE_PLANNER_PROVIDER: "openai"
GOOSE_PLANNER_MODEL: "gpt-4"

# --- Tool / autonomy behavior ---
GOOSE_MODE: "smart_approve"        # auto | approve | smart_approve | chat
GOOSE_TOOLSHIM: true
GOOSE_CLI_MIN_PRIORITY: 0.2

# --- Recipes ---
GOOSE_RECIPE_GITHUB_REPO: "aaif-goose/goose-recipes"

# --- Extension command search path ---
GOOSE_SEARCH_PATHS:
  - "/usr/local/bin"
  - "~/custom/tools"
  - "/opt/homebrew/bin"

# --- Security ---
SECURITY_PROMPT_ENABLED: true

# --- Observability ---
otel_exporter_otlp_endpoint: "http://localhost:4318"
otel_exporter_otlp_timeout: 20000

# --- Custom slash commands that run recipes ---
slash_commands:
  - command: "run-tests"
    recipe_path: "/path/to/recipe.yaml"

# --- Extensions ---
extensions:
  developer:
    bundled: true
    enabled: true
    name: developer
    timeout: 300
    type: builtin
  memory:
    bundled: true
    enabled: true
    name: memory
    timeout: 300
    type: builtin
  github:
    name: GitHub
    type: stdio
    cmd: npx
    args: [-y @modelcontextprotocol/server-github]
    enabled: true
    timeout: 300
    envs: { "GITHUB_PERSONAL_ACCESS_TOKEN": "<TOKEN>" }
    available_tools: []      # empty = all tools; or restrict to specific tool names

7.4 Global Settings (root of config.yaml)

Setting Values Default Required
GOOSE_PROVIDER provider name — Yes
GOOSE_MODEL model name — Yes
GOOSE_TEMPERATURE 0.0–1.0 model-specific No
GOOSE_MAX_TOKENS positive int model-specific No
GOOSE_MODE auto/approve/chat/smart_approve auto* No
GOOSE_MAX_TURNS int 1000 No
GOOSE_PLANNER_PROVIDER / GOOSE_PLANNER_MODEL provider/model falls back to main No
GOOSE_TOOLSHIM / GOOSE_TOOLSHIM_OLLAMA_MODEL bool / model false / system No
GOOSE_CLI_MIN_PRIORITY 0.0–1.0 0.0 No
GOOSE_CLI_THEME light/dark/ansi dark No
GOOSE_CLI_SHOW_COST bool false No
GOOSE_ALLOWLIST URL — No
GOOSE_RECIPE_GITHUB_REPO org/repo — No
GOOSE_AUTO_COMPACT_THRESHOLD 0.0–1.0 0.8 No
SECURITY_PROMPT_ENABLED bool false No
SECURITY_PROMPT_THRESHOLD 0.01–1.0 0.8 No
GOOSE_TELEMETRY_ENABLED bool false No

* The default mode is smart_approve at runtime; config.yaml documents auto as the file default. Set it explicitly to avoid ambiguity.

7.5 Extension Configuration Schema

extensions:
  <name>:
    bundled: true|false        # included with goose
    display_name: "Name"       # human-readable (optional)
    enabled: true|false        # active?
    name: "<name>"             # internal name
    timeout: 300               # per-tool-call timeout (seconds)
    type: "builtin"|"stdio"|"streamable_http"
    available_tools: []        # [] = all tools; or a whitelist of tool names

    # stdio extensions only:
    cmd: "command"
    args: ["arg1", "arg2"]
    description: "text"
    env_keys: []
    envs: {}

Tip

Tool filtering via available_tools is an under-used token optimization: load only the tools you need from a big extension to cut prompt overhead. Empty means all tools.

7.6 Verifying Configuration

goose info -v          # all active settings and current values
goose info --check     # test the provider connection
goose doctor           # end-to-end health check

Note

Direct edits to config files usually require restarting goose for existing sessions. Provider credential changes made through Desktop Settings refresh the provider inventory without a restart, but currently-active chat sessions keep the provider instance they started with.


8. Environment Variable Reference

Environment variables override config.yaml. Grouped by function.

8.1 Model & Provider

Variable Purpose Default
GOOSE_PROVIDER / GOOSE_MODEL Provider / model must configure
GOOSE_FAST_MODEL Model for auxiliary calls (tool-selection, classification, titles) provider default
GOOSE_TEMPERATURE / GOOSE_MAX_TOKENS Temperature / response cap model default
GOOSE_PROVIDER__TYPE / __HOST / __API_KEY Provider implementation / endpoint / key derived/none
GOOSE_PREDEFINED_MODELS JSON array defining custom models (name, provider, context_limit, request_params) —
GOOSE_CONTEXT_LIMIT / GOOSE_INPUT_LIMIT / GOOSE_PLANNER_CONTEXT_LIMIT Context-window overrides (main / ollama num_ctx / planner) model default
CLAUDE_THINKING_TYPE / CLAUDE_THINKING_BUDGET Claude reasoning mode / token budget (Anthropic, Databricks) adaptive (4.6+) / 16000
GEMINI3_THINKING_LEVEL Gemini 3 thinking level (low/high) low
GOOSE_PLANNER_PROVIDER / GOOSE_PLANNER_MODEL Planning-mode provider/model falls back to main
BEDROCK_* / DATABRICKS_* retries Provider retry tuning (max retries, intervals, backoff) per-provider

8.2 Session & Context

Variable Purpose Default
GOOSE_CONTEXT_STRATEGY On context overflow: summarize/truncate/clear/prompt prompt (interactive), summarize (headless)
GOOSE_MAX_TURNS Max turns without user input 1000
GOOSE_GATEWAY_MAX_TURNS Turn cap for gateway sessions only falls back to GOOSE_MAX_TURNS, then 5
GOOSE_SUBAGENT_MAX_TURNS Max turns per subagent 25
GOOSE_MAX_BACKGROUND_TASKS Concurrent subagents 5
GOOSE_AUTO_COMPACT_THRESHOLD Auto-summarize at this context fraction (0 disables) 0.8
GOOSE_TOOL_CALL_CUTOFF Tool calls kept in full before summarizing older ones 10
CONTEXT_FILE_NAMES Custom hint/context filenames (JSON array) [".goosehints"]
GOOSE_DISABLE_SESSION_NAMING Skip AI session naming false
GOOSE_DISABLE_TOOL_CALL_SUMMARY Skip per-tool AI title false
GOOSE_PROMPT_EDITOR External editor for composing prompts unset
GOOSE_CLI_THEME / _LIGHT_THEME / _DARK_THEME CLI markdown + syntax themes dark / GitHub / zenburn
GOOSE_CLI_SHOW_THINKING / GOOSE_CLI_SHOW_COST Show reasoning / cost in CLI off
GOOSE_MAX_CODE_BLOCK_LINES / GOOSE_TRUNCATED_SHOW_LINES / GOOSE_NO_CODE_TRUNCATION CLI code-block truncation controls 50 / 20 / off
GOOSE_MOIM_MESSAGE_TEXT / GOOSE_MOIM_MESSAGE_FILE Inject persistent text into working memory every turn (≤64 KB file) unset

8.3 Tools & Execution

Variable Purpose Default
GOOSE_MODE Tool execution behavior smart_approve
GOOSE_TOOLSHIM / GOOSE_TOOLSHIM_OLLAMA_MODEL Tool-call interpretation for non-tool-calling models false
GOOSE_CLI_MIN_PRIORITY Tool output verbosity (0.0–1.0) 0.0
GOOSE_DEBUG Full tool params, no truncation false
GOOSE_SEARCH_PATHS Extra dirs prepended to PATH for extension commands (JSON array) system PATH
GOOSE_MAX_TOOL_RESPONSE_SIZE Char cap before a tool response is spilled to a temp file 200000
GOOSE_SHELL Shell for Developer extension commands /bin/bash (Unix), cmd (Windows)
GOOSE_EDITOR_API_KEY / _HOST / _MODEL Enhanced code editing model (all three required) none

8.4 Security & Privacy

Variable Purpose Default
GOOSE_ALLOWLIST URL listing allowed extensions unset
GOOSE_DISABLE_KEYRING Force file-based secret storage (set to any value) unset (keyring on)
SECURITY_PROMPT_ENABLED / SECURITY_PROMPT_THRESHOLD Prompt-injection detection / sensitivity false / 0.8
SECURITY_PROMPT_CLASSIFIER_ENABLED / _ENDPOINT / _TOKEN ML-based injection detection false
GOOSE_TELEMETRY_ENABLED Anonymous usage data collection false
GOOSE_SANDBOX macOS Desktop sandbox (sandbox-exec) false

8.5 Network, Server & OAuth

Variable Purpose Default
HTTP_PROXY / HTTPS_PROXY / NO_PROXY Proxy config (HTTPS wins over HTTP) none
GOOSE_OAUTH_CALLBACK_PORT Fixed OAuth callback port (for IdPs requiring exact redirect_uri) random
GOOSE_HOST / GOOSE_PORT / GOOSE_TLS / GOOSE_SERVER__SECRET_KEY goosed bind/port/TLS/secret 127.0.0.1 / 3000 / true / random

8.6 Observability

Variable Purpose
OTEL_EXPORTER_OTLP_ENDPOINT Base OTLP endpoint (/v1/traces, etc.)
OTEL_EXPORTER_OTLP_{SIGNAL}_ENDPOINT Per-signal endpoint override
OTEL_{SIGNAL}_EXPORTER otlp/console/none per signal
OTEL_SDK_DISABLED Disable all OTel export
LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY / LANGFUSE_URL Langfuse integration

8.7 Recipes & Internal

Variable Purpose
GOOSE_RECIPE_PATH Extra recipe directories (OS path-separated)
GOOSE_RECIPE_GITHUB_REPO GitHub recipe repo (owner/repo)
GOOSE_RECIPE_RETRY_TIMEOUT_SECONDS / _ON_FAILURE_TIMEOUT_SECONDS Recipe command timeouts
GOOSE_PATH_ROOT Override root for all config/data/state
GOOSE_VERSION Pin CLI version (CI/CD reproducibility)
GOOSE_TERMINAL / AGENT / AGENT_SESSION_ID Set by goose so shells/tools/extensions can detect agent execution and isolate work by session

Important

Enterprise rollout: For consistent governance, pre-set provider endpoints (GOOSE_PROVIDER__HOST), proxy variables, GOOSE_ALLOWLIST, and security toggles via your configuration management, and prefer the keyring or env vars over committing secrets to secrets.yaml.


9. Security

goose's threat model is unusual: it is an agent that executes arbitrary actions on the host as the user, directed by an LLM that may be influenced by untrusted content (web pages, file contents, tool output). The controls below form the defense.

9.1 The Autonomy Control Plane

Control What it limits How
GOOSE_MODE Whether/when goose executes tools chat (no execution) → approve (ask every time) → smart_approve (ask on risky) → auto (full)
Tool permissions Per-tool allow/deny permission.yaml via goose configure; runtime decisions in permissions/tool_permissions.json
.gooseignore Files/paths goose may touch Glob patterns, like .gitignore
Extension allowlist Which extensions may load GOOSE_ALLOWLIST URL
Recipe trust Running unfamiliar recipes Desktop "New Recipe Warning" — review then Trust and Execute

Caution

Default mode is smart_approve, not read-only. For shared, CI, or high-privilege hosts, set GOOSE_MODE=approve or chat and scope .gooseignore to keep goose away from secrets, infra config, and credential stores.

9.2 Extension Malware Scanning

Locally-executed external extensions installed via uvx (PyPI) or npx (NPM) are checked against the OSV malware database before activation. A hit is blocked:

Blocked malicious package: package-name@1.0.0 (npm). OSV MAL advisories: MAL-2024-1234

If the OSV service is unreachable, extensions still install (fail-open) — so the allowlist remains your hard control. Only install extensions from trusted sources.

9.3 Prompt-Injection Detection

goose can scan for prompt-injection attempts (malicious instructions hidden in content goose reads):

export SECURITY_PROMPT_ENABLED=true
export SECURITY_PROMPT_THRESHOLD=0.9             # stricter
# Optional ML-based classifier:
export SECURITY_PROMPT_CLASSIFIER_ENABLED=true
export SECURITY_PROMPT_CLASSIFIER_ENDPOINT="https://your-endpoint/classify"
export SECURITY_PROMPT_CLASSIFIER_TOKEN="..."

9.4 Secret Storage

  • Default: OS keyring (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux) via the keyring crate.
  • Fallback: secrets.yaml (plaintext) when no keyring is available (headless, containers, CI) or when disabled with GOOSE_DISABLE_KEYRING.
GOOSE_DISABLE_KEYRING=1 goose configure

Warning

secrets.yaml stores keys in plaintext. In CI/containers prefer injecting provider keys as environment variables and answering No to "save to keyring," rather than persisting secrets.yaml.

9.5 macOS Desktop Sandbox

The Desktop app supports an optional macOS sandbox using Apple's sandbox-exec to restrict file access, network connections, and process execution:

export GOOSE_SANDBOX=true

9.6 goosed Network Exposure

See §5.3. The combination that matters: TLS on + strong GOOSE_SERVER__SECRET_KEY + network-layer restriction whenever GOOSE_HOST is not 127.0.0.1.

9.7 Reporting

Security issues are handled per SECURITY.md in the repository. Do not file public issues for vulnerabilities.


10. Deployment

10.1 Desktop Deployment

Distribute the platform build (macOS app, Linux DEB, Windows package) or via package managers (brew install --cask block-goose). The Desktop self-updates; ENABLE_DEV_UPDATES/GOOSE_VERSION control update channels for testing.

10.2 CLI Deployment (incl. CI/CD)

curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash

For reproducible, non-interactive installs (CI/CD), pin the version to avoid 404s when the stable tag lacks assets:

export GOOSE_VERSION=1.37.0

A headless CI run:

export GOOSE_PROVIDER=anthropic GOOSE_MODEL=claude-sonnet-4-5
export ANTHROPIC_API_KEY=...           # via secret store, not secrets.yaml
export GOOSE_DISABLE_KEYRING=1
export GOOSE_MODE=auto
goose run --no-session --recipe ci-check.yaml --output-format json

10.3 Remote goosed Server

Run goosed on a remote/more-powerful host and connect the Desktop to it:

# On the remote host
export GOOSE_HOST=0.0.0.0 GOOSE_PORT=3000 GOOSE_TLS=true
export GOOSE_SERVER__SECRET_KEY='a-long-random-secret'
goosed agent
# Note the printed GOOSED_CERT_FINGERPRINT=... — the client needs it

The Desktop then connects with the host, port, secret, and cert fingerprint. Restrict access with a firewall/VPN.

10.4 Docker / DevContainers

goose can run inside containers, and can run extensions inside a container via --container <id> (for devcontainer workflows). See BUILDING_DOCKER.md and the in-repo Dockerfile. In containers, the keyring is typically unavailable — set GOOSE_DISABLE_KEYRING=1 and inject keys via env vars.

10.5 Custom Distributions

CUSTOM_DISTROS.md documents building branded/customized goose builds — useful for enterprises that need to bake in proxy config, an allowlist, custom shims for airgapped networks, or a pre-pinned provider.

10.6 Linux Packaging & Manpages

Distribution packagers can generate Unix manpages from the CLI definitions:

just generate-manpages    # ROFF output in target/man/ (goose.1, goose-session.1, ...)

Install them to /usr/share/man/man1/ for offline man goose. See BUILDING_LINUX.md.


11. Operations

11.1 Health & Diagnostics

goose doctor              # full health check
goose info -v             # active config
goose info --check        # provider connectivity
goose session diagnostics --name <session> -o diag.zip   # support bundle

11.2 Logs & Data Locations

Platform Config Data/sessions Logs
macOS ~/.config/goose ~/Library/Application Support/goose ~/.config/goose
Linux ~/.config/goose/ ~/.local/share/goose/ ~/.local/state/goose/
Windows %APPDATA%\Block\goose\ %APPDATA%\Block\goose\ %LOCALAPPDATA%\Block\goose\

11.3 Scheduled Jobs

The built-in scheduler runs recipes on cron (no external service):

goose schedule add --schedule-id nightly --cron "0 2 * * *" --recipe-source ~/recipes/maint.yaml
goose schedule list
goose schedule run-now --schedule-id nightly
goose schedule remove --schedule-id nightly

11.4 Backup & Migration

Back up ~/.config/goose/ (config + recipes + prompts) and the data directory (sessions). Secrets live in the OS keyring (or secrets.yaml if file-based). Use GOOSE_PATH_ROOT to relocate or isolate an entire environment.

11.5 Uninstall / Reset

Stop all goose processes, delete the "goose" credential from the keychain/credential manager, then remove the data/config/state directories for your platform (see Known Issues → Uninstall).


12. Observability

goose emits OpenTelemetry signals (traces, metrics, logs) to any OTLP-compatible collector, has a Langfuse integration, and an opt-in PostHog telemetry channel.

# Export everything to a local collector
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"

# Traces only; console debug; sample 10% in prod
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"
export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
export OTEL_TRACES_SAMPLER_ARG="0.1"

Or in config.yaml:

otel_exporter_otlp_endpoint: "http://localhost:4318"
otel_exporter_otlp_timeout: 20000

Built-in metrics include session counters, durations, token usage, and recipe runs (emitted as monotonic_counter.goose.* tracing events). Anonymous product telemetry is off by default (GOOSE_TELEMETRY_ENABLED=false).

Tip

For per-session LLM tracing (prompts, tool calls, costs), use the Langfuse integration (LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY) — the most operator-friendly view of what the agent actually did.


13. Developer Internals

13.1 Architecture Layers (recap, for extenders)

goose-cli / ui/desktop / ui/text / ACP editors      ← interfaces
            │
crates/goose-server (goosed, Axum)                  ← API surface (Desktop/ACP-HTTP)
            │
crates/goose                                         ← engine (loop, providers, MCP, recipes,
            │                                          sessions, scheduler, security, permissions)
            ├── MCP (rmcp) → goose-mcp + 3rd-party    ← tools
            └── provider HTTP → LLM providers          ← models
crates/goose-sdk(+types), goose-acp-macros           ← embedding & protocol support

13.2 Provider Layer

Providers live in crates/goose/src/providers/, one module per provider, plus:

  • declarative/*.json — model catalogs (e.g. groq.json, novita.json, routstr.json) listing model names and context limits. This is where the "supported models per provider" data lives.
  • local_inference/ — GGUF inference via llama-cpp-2 (with a llamacpp/ backend) and candle.
  • formats/, canonical/ — request/response formatting and a canonical message representation that normalizes across providers.

To add a provider, implement the provider trait, add a declarative model catalog if applicable, and register it. Prompt caching for Claude is applied automatically for Anthropic/Bedrock/Databricks/OpenRouter/LiteLLM.

13.3 Recipes & Scheduler

  • recipe/ parses and templates recipe YAML (Jinja-style includes, parameters, sub-recipes) and builds deeplinks (recipe_deeplink.rs).
  • scheduler.rs + scheduler_trait.rs implement the embedded cron scheduler (no external broker).

13.4 Context Management

context_mgmt/ and conversation/ implement the context-revision strategy: token counting (token_counter.rs), automatic compaction (GOOSE_AUTO_COMPACT_THRESHOLD), tool-output summarization (GOOSE_TOOL_CALL_CUTOFF), and find-and-replace-over-rewrite editing. This is the cost-control core.

13.5 Code Mode & V8

The Code Mode platform extension executes JavaScript for tool discovery/calling. It relies on a vendored V8 (vendor/v8, pinned via [patch.crates-io]) — a notable build dependency. Known interaction bug: MCP Apps may fail to render when Code Execution is enabled (#9598).

13.6 Contributing

See CONTRIBUTING.md, CONTRIBUTING_RECIPES.md, AGENTS.md (agent-oriented contribution guidance), GOVERNANCE.md, MAINTAINERS.md, and RELEASE.md/RELEASE_CHECKLIST.md. The project moved to the AAIF organization (aaif-goose/goose); authorship is AAIF <[email removed]>, license Apache-2.0.


14. Embedding goose (SDKs)

Two SDK surfaces let you embed goose:

  • Rust SDK — crates/goose-sdk (types in crates/goose-sdk-types), including UniFFI bindings (examples/uniffi) so the agent can be driven from other languages.
  • TypeScript SDK — ui/sdk, a generated client (src/generated/) for the goosed HTTP API. This is what custom front-ends or integrations target.

Embedders typically run goosed (or link the engine) and drive sessions/recipes through these clients, supplying provider config and extensions programmatically.


15. Testing Strategy

Layer Where
Unit & integration (Rust) Per-crate tests/ and #[cfg(test)] modules
MCP/agent harness crates/goose-test, crates/goose-test-support (test MCP servers, ACP fixtures, recorded provider responses under scenario_tests/recordings/<provider>)
Desktop (TS) ui/desktop/tests/ (unit, integration, Playwright e2e)
Evals/benchmarks evals/ (harbor, open-model-gym) — measures model/agent performance on task suites
Self-test goose-self-test.yaml — a recipe that exercises goose end-to-end
Lint/deps clippy.toml, deny.toml (cargo-deny), cargo-machete (the vendor/v8 workspace member exists partly to satisfy it)

Extensions should be tested at three levels: unit tests per tool, integration tests for extension behavior, and property tests for tool invariants.


16. Troubleshooting (Operational)

16.1 Keyring Unavailable (containers / headless / CI)

Symptom: Failed to access keyring / org.freedesktop.secrets was not provided. Cause: No desktop keyring (Secret Service over DBus) in the environment. Fix: Force file storage or use env vars:

GOOSE_DISABLE_KEYRING=1 goose configure

goose may auto-fall-back to secrets.yaml for the current process; new sessions retry the keyring. Force file storage to make it persistent.

16.2 Airgapped / Restricted Networks

Symptom: Extensions fail with hermit:fatal or "Could not run extension command." Cause: goose's packaged npx/uvx shims try to download runtimes via Hermit, which restricted networks block. Fix: Create alternatively-named runners (not npx/uvx/jbang) so goose passes them through unchanged, and reference those in config:

ln -s /usr/local/bin/uvx /usr/local/bin/runuv
ln -s /usr/local/bin/npx /usr/local/bin/runnpx
extensions:
  example:
    cmd: runuv          # bypasses goose's shim
    args: [mcp-server-example]

For deeper constraints (TLS interception, proxies), build a custom distribution (CUSTOM_DISTROS.md) with the right shims/config baked in.

16.3 Clean Uninstall / Reset

Stop all goose processes, delete the "goose" keychain/credential, then:

# macOS
rm -rf ~/.config/goose ~/Library/Application\ Support/goose
# Linux
rm -rf ~/.local/share/goose/ ~/.local/state/goose/ ~/.config/goose/
# Windows (cmd)
rmdir /s /q "%APPDATA%\Block\goose"
rmdir /s /q "%LOCALAPPDATA%\Block\goose"

16.4 Corporate Proxy

export HTTPS_PROXY="http://proxy.company.com:8080"
export NO_PROXY="localhost,127.0.0.1,.internal"

Restart goose. Env vars take precedence over OS proxy settings.

16.5 OAuth Behind a Strict IdP

If your identity provider requires an exact redirect_uri (no wildcard ports), pin the callback port:

export GOOSE_OAUTH_CALLBACK_PORT=8080

Register http://127.0.0.1:8080/oauth_callback (MCP OAuth) or http://localhost:8080 (Databricks OAuth).

16.6 Node.js Extensions Fail on Windows

goose expects Node at C:\Program Files\nodejs\. If installed elsewhere, symlink it (Admin PowerShell): mklink /D "C:\Program Files\nodejs" "D:\Program Files\nodejs".

16.7 Known Bugs (from the issue tracker)

Issue Status Note
MCP Apps fail to render when Code Execution extension enabled (#9598) Open Disable Code Mode when using MCP Apps
Desktop ignores GOOSE_MODEL from config.yaml (#9451) Closed Set model via Settings
shell tool returns empty stdout/stderr on Windows in ACP stdio mode (#9582) Open Affects ACP subprocess launches
Empty "New Chat" sessions created on reconnection when goosed unreachable (#9608) Open Ensure goosed reachable
Tool request/response timestamp ordering breaks Claude API message order (#9461) Open Provider-specific ordering issue

17. Potential Improvements

Observations for maintainers and operators planning hardening or contributions:

  • Default mode clarity. config.yaml documents GOOSE_MODE default as auto while runtime default is smart_approve. Aligning the documented and effective defaults would reduce operator surprise on high-privilege hosts.
  • secrets.yaml plaintext. File-based fallback stores secrets unencrypted. An at-rest encryption option (or first-class env-injection mode) would help container/CI deployments that can't use a keyring.
  • Fail-open malware scan. If OSV is unreachable, extension installs proceed. Environments with a strict posture should treat the allowlist as the authoritative control and consider a fail-closed option.
  • goosed exposure footguns. Binding to 0.0.0.0 exposes a command-executing agent; a startup warning when GOOSE_HOST != 127.0.0.1 without a strong secret would reduce risk.
  • Code Mode / MCP Apps interaction (#9598). A documented, enforced mutual exclusion (or a fix) would remove a sharp edge.
  • Windows ACP shell stdout (#9582). Empty stdout/stderr under ACP stdio is a correctness gap for Windows automation.
  • Tree-sitter breadth. Code intelligence covers 10 languages; extending the grammar set would broaden Code Mode/analysis coverage.

18. Quick Reference

18.1 Operator Commands

goose doctor                 # health check
goose info -v                # full config
goose info --check           # provider connectivity
goosed agent                 # run the server (Desktop backend / remote)
goose serve --port 3284      # ACP over HTTP/WS
goose schedule list          # scheduled jobs
just generate-manpages       # packager manpages

18.2 Critical Security Settings

Setting Hardened value
GOOSE_MODE approve or chat on shared/CI/high-privilege hosts
GOOSE_ALLOWLIST URL of approved extensions
.gooseignore exclude secrets, infra config, credential stores
GOOSE_SERVER__SECRET_KEY strong random; required if GOOSE_HOST != 127.0.0.1
GOOSE_TLS true for any non-local goosed
SECURITY_PROMPT_ENABLED true when reading untrusted content
GOOSE_DISABLE_KEYRING 1 in containers (+ env-var keys, avoid secrets.yaml)

18.3 Workspace Crate Map

Crate Role
goose Agent engine (core)
goose-cli goose binary / CLI
goose-server goosed HTTP/WS + ACP-HTTP server
goose-mcp Bundled MCP extensions
goose-sdk / goose-sdk-types Embedding SDK
goose-acp-macros ACP proc-macros
goose-test / goose-test-support Test harness & fixtures

18.4 Facts Sheet

Fact Value
Workspace version 1.37.0
Rust edition / MSRV 2021 / 1.91.1
License Apache-2.0
MCP library rmcp 1.4
ACP library agent-client-protocol 0.11
Server framework Axum 0.8 (goosed)
Default goosed bind/port 127.0.0.1:3000, TLS on
Default ACP HTTP port (goose serve) 3284
Default GOOSE_MODE smart_approve
Default GOOSE_MAX_TURNS 1000
Bundled MCP servers developer, computercontroller, memory, tutorial, autovisualiser