Crush — API Surface#

API types#

Crush exposes two distinct API surfaces: a CLI and an optional REST/HTTP API. There is no gRPC, no public library API, and no formal plugin interface — though MCP (Model Context Protocol) integration acts as a runtime extension mechanism.


CLI#

Framework#

Cobra (github.com/spf13/cobra) wrapped with charm.land/fang/v2 (Charmbracelet’s Cobra wrapper that adds Ctrl-C handling and colorprofile-aware output).

Command structure#

crush                           Interactive TUI mode (default command)
crush run [prompt...]           Non-interactive single-prompt execution
crush session                   Session management (alias: sessions, s)
  session list                  List all sessions (alias: ls)
  session show <id>             Show session details with message history
  session last                  Show most recent session
  session delete <id>           Delete a session
  session rename <id> <title>   Rename a session
crush server                    Start the background server daemon
crush login [platform]          Authenticate with a provider (alias: auth)
crush models [filter]           List available models from configured providers
crush stats                     Show usage statistics (opens HTML report)
crush projects                  List tracked project directories
crush dirs                      Print config/data directory paths
  dirs config                   Print only config directory
  dirs data                     Print only data directory
crush logs                      View crush log output (--follow for tail)
crush update-providers [path]   Update Catwalk / Hyper provider data
crush schema                    Generate JSON schema for config (hidden)

Flag patterns#

Global (persistent) flags — available on all subcommands:

FlagShortDescription
--cwd-cOverride working directory
--data-dir-DCustom data directory
--debug-dEnable debug logging
--host-HConnect to specific server socket/address

Root command (TUI) flags:

FlagShortDescription
--yolo-yAuto-accept all permissions (dangerous)
--session-sContinue session by ID
--continue-CContinue most recent session

run subcommand flags:

FlagShortDescription
--quiet-qHide spinner
--verbose-vShow log output inline
--model-mOverride LLM model (model or provider/model)
--small-modelOverride small/compact model
--session-sContinue session by ID
--continue-CContinue most recent session

session list/show/last/delete/rename flags: All session subcommands support --json for machine-readable output — explicitly designed for agent-to-agent use.

Notable design choices#

  • crush run accepts stdin piping (cat file | crush run "analyze this") — first-class scripting surface
  • --session/--continue are declared mutually exclusive via cobra.MarkFlagsMutuallyExclusive
  • --yolo is a root-level flag only (not on run), limiting the blast radius of auto-permission to intentional invocations
  • crush session subcommands include --json output mode for machine-readable results, anticipating agent-as-caller use cases

REST/HTTP API (client/server mode)#

Overview#

The REST API is used internally when CRUSH_CLIENT_SERVER=1 is set. The server daemon is auto-started by the client binary (see architecture result). The API is also the foundation for future IDE integrations (VS Code extension, etc.) and multi-client access.

  • Transport: stdlib net/http over a Unix socket (/tmp/crush-<uid>.sock) on Linux/macOS or a Windows named pipe. TCP is also supported (tcp://host:port).
  • Protocol: HTTP/1.1 and unencrypted HTTP/2 (both enabled via http.Protocols)
  • Router: stdlib http.ServeMux with Go 1.22+ pattern syntax (e.g., GET /v1/health, DELETE /v1/workspaces/{id})
  • Versioning: All routes are under /v1/
  • Documentation: Swagger UI served at /v1/docs/ via swaggo/http-swagger
  • Authentication: None — the Unix socket provides OS-level access control (only the owning user can connect); TCP mode relies on network-level controls

Middleware chain#

A single middleware is applied globally:

loggingHandler → http.ServeMux (route dispatch)

loggingHandler is a minimal inline implementation (no third-party middleware library) that logs method, path, remote addr, user agent, status code, and duration via slog.

Route catalog#

System endpoints#

MethodPathDescription
GET/v1/healthHealth check — returns 200 OK
GET/v1/versionServer version info (proto.VersionInfo)
GET/v1/configGlobal server configuration
POST/v1/controlServer control commands (e.g., {"command":"shutdown"})

Workspace management#

MethodPathDescription
GET/v1/workspacesList all workspaces
POST/v1/workspacesCreate workspace
GET/v1/workspaces/{id}Get workspace details
DELETE/v1/workspaces/{id}Delete workspace

Session management#

MethodPathDescription
GET/v1/workspaces/{id}/sessionsList sessions
POST/v1/workspaces/{id}/sessionsCreate session
GET/v1/workspaces/{id}/sessions/{sid}Get session
PUT/v1/workspaces/{id}/sessions/{sid}Update session
DELETE/v1/workspaces/{id}/sessions/{sid}Delete session
GET/v1/workspaces/{id}/sessions/{sid}/historySession history (file edits)
GET/v1/workspaces/{id}/sessions/{sid}/messagesAll messages in session
GET/v1/workspaces/{id}/sessions/{sid}/messages/userUser messages only
GET/v1/workspaces/{id}/messages/userAll user messages across workspace

Agent control#

MethodPathDescription
GET/v1/workspaces/{id}/agentGet agent status
POST/v1/workspaces/{id}/agentRun agent with prompt
POST/v1/workspaces/{id}/agent/initInitialize agent
POST/v1/workspaces/{id}/agent/updateUpdate agent (model/config)
GET/v1/workspaces/{id}/agent/sessions/{sid}Get agent session details
POST/v1/workspaces/{id}/agent/sessions/{sid}/cancelCancel running agent
GET/v1/workspaces/{id}/agent/sessions/{sid}/prompts/queuedGet queued prompts
GET/v1/workspaces/{id}/agent/sessions/{sid}/prompts/listList all prompts
POST/v1/workspaces/{id}/agent/sessions/{sid}/prompts/clearClear prompt queue
POST/v1/workspaces/{id}/agent/sessions/{sid}/summarizeSummarize session
GET/v1/workspaces/{id}/agent/default-small-modelGet default small model

Events (SSE streaming)#

MethodPathDescription
GET/v1/workspaces/{id}/eventsSSE event stream for workspace

The events stream carries typed payloads via pubsub.Payload envelope with a PayloadType discriminator. Event types published:

  • LSPEvent — LSP server state changes, diagnostic counts
  • MCPEvent — MCP connection state, tool/prompt/resource list changes
  • PermissionRequest — agent requests permission before a tool call
  • PermissionNotification — permission granted/denied result
  • Message — new or updated LLM message (streaming-friendly)
  • Session — session created/updated
  • File — file history entry (edit tracked)
  • AgentEvent — agent lifecycle notifications (started, finished, error)

Permissions#

MethodPathDescription
GET/v1/workspaces/{id}/permissions/skipGet skip-permission list
POST/v1/workspaces/{id}/permissions/skipAdd to skip-permission list
POST/v1/workspaces/{id}/permissions/grantGrant a pending permission request

File tracking#

MethodPathDescription
GET/v1/workspaces/{id}/sessions/{sid}/filetracker/filesFiles modified in session
POST/v1/workspaces/{id}/filetracker/readRecord file read
GET/v1/workspaces/{id}/filetracker/lastreadLast read file per path

Configuration management#

MethodPathDescription
GET/v1/workspaces/{id}/configGet workspace config
POST/v1/workspaces/{id}/config/setSet config key
POST/v1/workspaces/{id}/config/removeRemove config key
POST/v1/workspaces/{id}/config/modelChange active model
POST/v1/workspaces/{id}/config/compactConfigure compaction
POST/v1/workspaces/{id}/config/provider-keyUpdate provider API key
POST/v1/workspaces/{id}/config/import-copilotImport GitHub Copilot credentials
POST/v1/workspaces/{id}/config/refresh-oauthRefresh OAuth token

LSP management#

MethodPathDescription
GET/v1/workspaces/{id}/lspsList active LSP servers
GET/v1/workspaces/{id}/lsps/{lsp}/diagnosticsGet diagnostics from LSP
POST/v1/workspaces/{id}/lsps/startStart an LSP server
POST/v1/workspaces/{id}/lsps/stopStop all LSP servers

Workspace configuration#

MethodPathDescription
GET/v1/workspaces/{id}/providersList configured providers

Project initialization#

MethodPathDescription
GET/v1/workspaces/{id}/project/needs-initCheck if project needs init
POST/v1/workspaces/{id}/project/initInitialize project (generate CRUSH.md)
GET/v1/workspaces/{id}/project/init-promptGet init prompt

MCP management#

MethodPathDescription
GET/v1/workspaces/{id}/mcp/statesGet MCP server states
POST/v1/workspaces/{id}/mcp/refresh-toolsRefresh MCP tool list
POST/v1/workspaces/{id}/mcp/refresh-promptsRefresh MCP prompt list
POST/v1/workspaces/{id}/mcp/refresh-resourcesRefresh MCP resource list
POST/v1/workspaces/{id}/mcp/read-resourceRead an MCP resource
POST/v1/workspaces/{id}/mcp/get-promptFetch an MCP prompt
POST/v1/workspaces/{id}/mcp/docker/enableEnable Docker MCP server
POST/v1/workspaces/{id}/mcp/docker/disableDisable Docker MCP server

MCP — Extension / Plugin Mechanism#

While crush has no formal plugin system, MCP (Model Context Protocol) serves as the runtime extension point for adding tools, prompts, and resources to the agent.

  • Mechanism: JSON-RPC over stdio or HTTP, following the MCP specification. Crush connects to externally configured MCP servers at startup.
  • Extension points: External MCP servers can register additional tools (callable by the LLM), prompts (reusable instruction templates), and resources (file-like content the LLM can read).
  • Configuration: MCP servers are listed in crush.json under the mcp section with command + args or HTTP URL.
  • First-class support: The REST API exposes MCP management routes (/mcp/states, /mcp/refresh-*, /mcp/docker/*) and the TUI has MCP state display.
  • Docker integration: A dedicated Docker MCP server can be enabled/disabled via the API, suggesting first-party container tooling integration.

Library API#

Crush is not designed as a library. All packages reside under internal/ — the only public entry point is main.go. There are no exported packages for third-party import.

The Workspace interface (internal/workspace) is the natural seam for IDE integration, but it is explicitly internal. Future IDE clients would consume the REST API over the Unix socket rather than importing the Go package directly.


Notable API design observations#

  1. REST API mirrors the Workspace interface 1:1. Every method on the Workspace interface has a corresponding HTTP endpoint. The REST API is a faithful HTTP translation of the in-process Go interface — generated manually but mechanically consistent. This makes the client-server mode a thin HTTP wrapper rather than a separate design.

  2. SSE over HTTP/2 for real-time events. The GET /v1/workspaces/{id}/events endpoint is a Server-Sent Events stream. Using unencrypted HTTP/2 on Unix sockets means the single connection can multiplex SSE alongside REST calls without separate WebSocket infrastructure.

  3. No authentication. Security relies on Unix socket file permissions. This is idiomatic for local daemon patterns (Docker, containerd, systemd socket activation) but means TCP mode is explicitly for “advanced users” and not production-hardened.

  4. Swagger docs auto-generated. All handler functions carry @Summary, @Tags, and @Router annotations, and the OpenAPI spec is embedded via github.com/swaggo/http-swagger. This suggests the REST API is intended as a stable, documented interface for future tooling.

  5. --json flag pattern for agent-as-caller. The session subcommands all support --json output — an explicit acknowledgment that CLI commands will be called by other agents or automation scripts, not just humans.