Origami Labs

Origami Coder

Documentation

Origami Coder is a coding agent. It runs against a model that you host, or against a cloud provider.

Two artifacts, not one

Origami Coder ships as two programs. They are built separately and installed separately. A change to one does not change the other.

ArtifactSourceWhat it doesInstalled as
Extensionpackages/vscode/The VS Code user interface: panes, cards, webviews, the dashboard.A .vsix file
Enginepackages/engine/The agent runtime: tools, sessions, prompts, model calls.A binary at ~/.origami/bin/origami.exe

The extension talks to the engine over the Agent Client Protocol (ACP). The engine also runs on its own, as a terminal program and as a headless server.

Surfaces

  • VS Code extension — the chat view, the dashboard and the Folds board. See VS Code.
  • Headless serverorigami serve and origami web. See Server.
  • Terminal UI — the origami binary with no command. See Terminal UI.

This documentation describes the code in the repository. A desktop application is not part of this build. There is no packages/desktop, and no package declares Tauri or Electron as a dependency.

What Origami Coder is built around

These parts define the product. Each one has its own page in this documentation.

  • Local models come first. The extension points at http://localhost:1234/v1 by default. The engine detects a self-hosted endpoint and gives it long timeouts.
  • A context meter. The extension counts real tokens per session and shows how full the model window is.
  • The /firstfold command. It turns an empty folder into a workspace with instructions, a wiki, commands and skills.
  • The wrap skill. /firstfold writes it. It closes a session: one handoff block plus one wiki page.
  • The Folds board. Four tools read and write a ticket board, and the extension shows it as an agent manager.
  • Messages between sessions. The list_agents and send_message tools let two Origami sessions on one machine talk.
  • Memory tools. remember writes durable notes; the /dream command reorganises them.
  • Charts and a browser. The chart tool draws in the chat. The browser tool drives the VS Code integrated browser.
  • Flock fallback. A profile gives subagents their own model, with an ordered list of fallbacks for when a server is unreachable.

Getting started

Install

Install the extension from the Visual Studio Code Marketplace. Building from source stays available for development.

Install from the Marketplace

The Marketplace is the main way to install Origami Coder. Search for Origami Coder in the VS Code Extensions view, or install by identifier: OrigamiLabs.origamicoder. The extension bundles the engine and its search tool for your platform, so one install gives you the whole product.

Origami Coder is pre-release. The Marketplace listing goes live with the first public build.

Build from source

The engine and the extension build independently. A source install needs both.

Requirements

  • Bun 1.3.14. The repository declares it as its package manager.
  • VS Code ^1.106.0 for the extension.

Build the engine

The engine build script writes a binary for the current platform. Use --single to build only that one target.

bun install
cd packages/engine
bun run script/build.ts --single

Other flags of the build script are --baseline, --skip-install, --sourcemaps and --skip-embed-web-ui.

The command name is origami. The package declares the launcher at bin/origami.

Build the extension

cd packages/vscode
npm run build      # node esbuild.js
npm run typecheck  # tsc for src and webview
npm run package    # vsce package --no-dependencies

npm run package writes a .vsix file. Install that file in VS Code. The extension identifier is OrigamiLabs.origamicoder.

Run the type check. The unit tests do not check types. Vitest removes types without checking them, so code that cannot compile can still have a green test run.

Where files are kept

PathContent
~/.origamiThe product home: bin/, sessions/, skills/, settings.toml, global plans and global memory.
<XDG config>/origamiThe global configuration directory. Without XDG_CONFIG_HOME this is ~/.config/origami.
<XDG data>/origamiData, including auth.json, log/ and repos/.
<XDG cache>/origamiCache, including downloaded binaries in bin/.
<XDG state>/origamiState.

The command origami debug paths prints these paths.

Remove the program

origami uninstall removes the program and its files. It accepts --keep-config, --keep-data, --dry-run and --force.

Reference

Configuration

One JSON file holds the engine configuration. The terminal UI keeps its own file.

File names

The engine reads origami.json and origami.jsonc. The global directory also accepts the older name config.json.

Project files are found by a walk up the directory tree from the working directory to the worktree root. The file closest to the working directory wins.

Order of merge

Later sources overwrite earlier sources.

  1. The global directory: config.json, then origami.json, then origami.jsonc.
  2. The file named by ORIGAMI_CONFIG.
  3. Project origami.jsonc and origami.json, walking up.
  4. Each .origami directory, and ORIGAMI_CONFIG_DIR if it is set.
  5. Inline JSON in ORIGAMI_CONFIG_CONTENT.
  6. The system-managed directory.

The system-managed directory is /Library/Application Support/origami on macOS, %ProgramData%\origami on Windows, and /etc/origami elsewhere.

Unknown keys are an error

The parser accepts JSONC with trailing commas. An unknown key at the top level stops the load with the message Unrecognized key(s).

The keys theme, keybinds and tui are removed from origami.json on load. They belong in tui.json.

Values from the environment and from files

Before the parse, the loader replaces two patterns in the text.

{env:NAME}
The value of the environment variable. An unset variable becomes an empty string.
{file:path}
The content of the file. ~/ is expanded. A relative path is read from the directory of the configuration file.

Top-level keys

KeyTypePurpose
$schemastringJSON schema reference for configuration validation.
shellstringDefault shell for the terminal and the bash tool.
logLevelDEBUG, INFO, WARN, ERRORLog level.
modelstringModel to use, in the format provider/model.
small_modelstringSmall model for tasks such as title generation.
providerobjectCustom provider configuration and model overrides.
disabled_providersstring[]Disable providers that load automatically.
enabled_providersstring[]When set, only these providers are enabled.
agentobjectAgent configuration. See Agents.
default_agentstringPrimary agent to use when none is given. Falls back to build.
subagent_depthintegerMaximum subagent nesting depth. Default 1.
commandobjectCommand definitions. See Commands.
skillsobjectExtra skill folders and URLs. See Skills.
permissionobject or stringTool permissions. See Permissions.
mcpobjectMCP server configuration. See MCP servers.
pluginarrayPlugins to load. See Plugins.
agentPluginsstring[]Directories that hold agent-plugins.org plugins.
instructionsstring[]Extra instruction files or patterns. Values from every source are joined, not replaced.
formatterboolean or objectEnable or configure formatters.
lspboolean or objectEnable or configure language servers. A custom server must declare extensions.
snapshotbooleanRecord filesystem snapshots. Default true.
watcherobjectFile watcher ignore patterns.
compactionobjectauto, prune, tail_turns, preserve_recent_tokens, reserved.
tool_outputobjectmax_lines (2000) and max_bytes (51200) before tool output is truncated to disk.
attachmentobjectImage limits: auto_resize, max_width, max_height, max_base64_bytes.
referencesobjectNamed git or local directory references.
flockobjectModel profile for subagents, with health fallback. See Models and providers.
serverobjectport, hostname, mdns, mdnsDomain, cors.
sharemanual, auto, disabledControl session sharing.
autoupdateboolean or "notify"Update behaviour.
usernamestringName shown in conversations. Defaults to the operating system user.
enterpriseobjectEnterprise URL.
experimentalobjectUnstable options. See below.

Deprecated keys

These keys still load. Use the replacement instead.

  • autoshare — use share.
  • reference — use references.
  • mode — use agent.
  • tools — use permission.
  • layout — has no effect.

Experimental options

experimental.batch_tool
Enable the batch tool.
experimental.primary_tools
Tools that only primary agents may use.
experimental.continue_loop_on_deny
Continue the agent loop when a tool call is denied.
experimental.mcp_timeout
Timeout in milliseconds for MCP requests.
experimental.openTelemetry
Enable OpenTelemetry spans for model calls.
experimental.tool_search
Deferred tool catalog. Sub-keys: enabled (default true), mcp (default true), defer, always. Only * works as a wildcard.
experimental.disable_paste_summary
Turn off the paste summary.
experimental.policies
Policy statements for supported resources, such as provider access.

Environment variables

A variable is true when its value is true or 1.

VariableEffect
ORIGAMI_CONFIGPath of one more configuration file.
ORIGAMI_CONFIG_CONTENTInline JSON configuration.
ORIGAMI_CONFIG_DIROne more configuration directory.
ORIGAMI_DISABLE_PROJECT_CONFIGIgnore project files and project .origami directories.
ORIGAMI_TUI_CONFIGPath of one more terminal UI configuration file.
ORIGAMI_PERMISSIONJSON merged over the permission block.
ORIGAMI_DISABLE_AUTOCOMPACTForce compaction.auto to false.
ORIGAMI_DISABLE_PRUNEForce compaction.prune to false.
ORIGAMI_DISABLE_AUTOUPDATETurn off automatic update.
ORIGAMI_DISABLE_MODELS_FETCHDo not fetch the model database.
ORIGAMI_DISABLE_MOUSETurn off mouse capture in the terminal UI.
ORIGAMI_PRINT_LOGSPrint logs to standard error.
ORIGAMI_PURERun without external plugins.
ORIGAMI_SERVER_USERNAMEBasic authentication user for the server.
ORIGAMI_SERVER_PASSWORDBasic authentication password for the server.
ORIGAMI_AUTH_CONTENTCredential store content, instead of auth.json.
ORIGAMI_EXPERIMENTALTurn on every experimental gate.

The command origami debug config prints the resolved configuration.

Usage

VS Code

The extension is the main surface. It holds the chat view, the dashboard and the Folds board.

Identity

  • Name: origamicoder. Publisher: OrigamiLabs. Display name: Origami Coder.
  • Required editor: VS Code ^1.106.0.
  • The extension starts on the onStartupFinished event.

Commands

CommandTitle
origami.initOrigami: Get Started
origami.toggleSidebarOrigami: Toggle Sidebar
origami.newSessionOrigami: New Session
origami.newChatOrigami: New Chat
origami.openChatOrigami: Open Chat
origami.openChatInEditorOrigami: Open Chat in Editor
origami.switchModelOrigami: Switch Model
origami.openHistoryOrigami: Recall Past Chat
origami.openAgentManagerOrigami: Folds (Agent Manager)
origami.openAgentProfileOrigami: View Agent Profile
origami.toggleThemeOrigami: Toggle Theme (Meadow/Quiet)
origami.resetSavedPermissionsOrigami: Reset saved permissions

origami.init shows the chat view and runs /firstfold. origami.openAgentManager opens the Folds board, which runs parallel agents in separate git worktrees.

Key bindings

CommandWindows and LinuxmacOS
origami.toggleSidebarctrl+shift+lcmd+shift+l
origami.newSessionctrl+shift+ncmd+shift+n
origami.switchModelctrl+shift+mcmd+shift+m
origami.openChatctrl+alt+ocmd+alt+o

Settings

origami.engineUrl
string · default http://localhost:1234/v1
Inference engine endpoint, an OpenAI-compatible /v1 base URL. It overrides the ORIGAMI_API_BASE environment variable. Point it elsewhere to use a remote engine.
origami.devEngineSource
string · default empty
Development only. Absolute path of a packages/engine source tree. When set, the extension runs the engine from source with Bun instead of the compiled binary.
origami.agentName
string · default empty
The name that other Origami sessions on this machine see for this window. An empty value uses the folder name. It takes effect when the engine next starts.
origami.experimentalCodeMode
boolean · default false
Replace the individual MCP tools with one execute tool that runs a confined JavaScript program.
origami.syncVsCodeTheme
ask, always, never · default ask
Switch the VS Code colour theme when the dashboard theme changes.

Workflow settings

Every workflow option is off by default.

SettingEffect
origami.workflow.enable_briefingSession-start briefing, as a file dump.
origami.workflow.enable_briefing_llmDistil that briefing through a model first. Needs the briefing.
origami.workflow.enable_decision_loopbackReplay recent policy decisions into each turn.
origami.workflow.enable_plan_auto_triggerEnter plan mode for create, refactor, multi and repo-wide tasks.
origami.workflow.enable_reconRun a reconnaissance phase before file work.
origami.workflow.enable_task_shapeExtract numbered sub-tasks before the first turn.
origami.workflow.enable_shape_llmAsk the model for a task shape when the rule finds none.
origami.workflow.enable_best_of_nBest-of-N plans with critic scoring.
origami.workflow.best_of_n_kCandidate count for a best-of-N wave. Default 3, range 2 to 5.
origami.workflow.enable_reflective_retryRetry after a failure-recovery rollback.
origami.workflow.enable_ask_user_questionGive the model the inverted ask_user_question tool.
origami.workflow.enable_reasoning_traceWrite reasoning-trace rows to SQLite.

The context meter

The extension counts the tokens of each turn and keeps a total per session. It records prefill (input), read (cache read), write (output), the turn count, the window occupancy and the window size.

The fill bar has three bands: 80 percent or more is high, 60 percent or more is middle, below that is low. A reported value of zero means "not known" and keeps the earlier value, because a local server often reports zero for the window size.

Chat commands in VS Code

The extension answers four slash commands itself. They never reach the engine.

/firstfold
Set up this workspace: scaffold and model. See First fold.
/spend
Show the cost of this chat and of this month.
/loop
Run a prompt again on a timer.
/compose
Help to write a good /loop.

Usage

First fold

/firstfold turns an empty folder into a workspace. It is a command of the VS Code extension.

What it writes

The wizard shows a live checklist while it works. Each step is paced. Existing files are skipped, never overwritten, so you can run it again safely.

  1. Scan the workspaceIt reads package.json scripts and marker files such as Cargo.toml, pyproject.toml, requirements.txt and go.mod to find the build, test and lint commands.
  2. Write AGENTS.mdHouse rules for the agent, plus a "Build and test" section from the scan.
  3. Create foldersprojects/, scripts/ and crons/.
  4. Seed the wikiwiki/pages/ and a wiki/index.md primer.
  5. Create HANDOFF.mdA rolling session log with an anchor line that marks where new blocks go.
  6. Seed commands and skills.origami/command/example.md and one .origami/skills/<name>/SKILL.md per default skill.
  7. Connect a modelA provider picker writes the provider block into the global configuration file.

Run /firstfold model to repeat only the model step.

Reload the window after a first fold. The engine reads the configuration and scans .origami/command and .origami/skills once, when it starts.

The default skills

These skills are written into .origami/skills/<name>/SKILL.md.

  • wrap, example-skill
  • grill-me, to-spec, to-tickets, triage, tdd, diagnosing-bugs, code-review, wayfinder, handoff

The wrap skill

/wrap closes a session. It is a skill file, not engine code. It becomes a slash command because the engine registers every skill as a command.

The skill does two linked jobs in one pass.

  1. Insert a block in HANDOFF.md, directly below the anchor line. The block holds a dated heading, a done: line, a next: line and a wiki: link.
  2. Write the depth into wiki/pages/<page-name>.md: one topic per page, kebab-case, flat, with tags frontmatter and at least one link to another page.

A workspace that never ran /firstfold has no wrap skill. Copy the file, or write your own.

Usage

Terminal UI

Run origami with no command to open the terminal interface.

Start it

origami                 # start in the current directory
origami ./my-project    # start in a directory
origami -c              # continue the last session
origami -m lmstudio/qwen3-coder

The terminal interface is a SolidJS application drawn by OpenTUI.

Its own configuration file

Terminal settings live in tui.json or tui.jsonc, not in origami.json. The search order is the global directory, then ORIGAMI_TUI_CONFIG, then project files walking up, then each .origami directory.

KeyPurpose
themeTheme name. See Themes.
keybindsKey binding overrides. See Keybinds.
leader_timeoutLeader key timeout in milliseconds. Default 2000.
plugin, plugin_enabledTerminal plugins and their on/off state.
attentionNotification and sound settings: enabled, notifications, sound, volume, sound_pack, sounds.
promptmax_height and max_width of the prompt box.
scroll_speed, scroll_accelerationScroll behaviour.
diff_styleauto or stacked.
mouseMouse capture. Default true.

Slash commands in the terminal

These commands belong to the terminal interface. They do not reach the engine.

CommandAction
/sessions, /new, /fork, /rename, /timelineManage sessions.
/models, /variants, /agents, /connectSwitch model, variant, agent, or connect a provider.
/mcpsTurn MCP servers on and off.
/themes, /help, /status, /debug, /exitApplication actions.
/compact (alias /summarize), /undo, /redoChange the transcript.
/share, /unshare, /copy, /exportShare and export.
/diff, /editor, /skills, /timestamps, /thinkingViews and panels.
/warp, /move, /workspaces, /orgChange directory, workspace or organisation.

The terminal autocomplete hides slash commands that come from skills. The VS Code palette shows them.

Side panel

The side panel holds a context readout, an MCP list, a language-server list, the todo list and the file list.

Usage

Command line

The binary is origami. With no command it opens the terminal interface.

Global options

--help, -h
Show help.
--version, -v
Show the version number.
--print-logs
Print logs to standard error.
--log-level
One of DEBUG, INFO, WARN, ERROR.
--pure
Run without external plugins.

origami completion writes a shell completion script.

Commands

CommandDescription
origami [project]Start the terminal interface.
origami run [message..]Run Origami with a message.
origami serveStart a headless server.
origami webStart the server and open the web interface.
origami attach <url>Attach to a running server.
origami acpStart the Agent Client Protocol server.
origami models [provider]List every available model.
origami providers (alias auth)Manage providers and credentials.
origami agentManage agents.
origami mcpManage MCP servers.
origami plugin <module> (alias plug)Install a plugin and update the configuration.
origami agent-pluginManage agent-plugins.org plugins.
origami sessionManage sessions.
origami export [sessionID]Export session data as JSON.
origami import <file>Import session data from a file or a URL.
origami statsShow token use and cost.
origami pr <number>Fetch and check out a GitHub pull request branch, then run Origami.
origami db [query]Open a SQLite shell, or run a query.
origami debugDiagnostic tools.
origami uninstallRemove the program and its files.

Options of the terminal command

--model, -m
Model to use, in the format provider/model.
--agent
Agent to use.
--prompt
Prompt to use.
--continue, -c
Continue the last session.
--session, -s
Session identifier to continue.
--fork
Fork the session when continuing.
--auto
Approve every permission that is not explicitly denied. This is dangerous.
--mini
Start the minimal interactive interface.
--no-replay
Do not replay the mini session history on resume and after a resize.
--replay-limit
Limit the visible mini replay to the newest N messages.

Options of run

--command
The command to run. The message supplies its arguments.
--format
default for formatted output, or json for raw JSON events.
--file, -f
File or files to attach to the message.
--title
Title for the session.
--variant
Model variant, for example a reasoning effort.
--thinking
Show thinking blocks.
--share
Share the session.
--attach
Attach to a running server.
--dir
Directory to run in. On a remote server this is the remote path.
--port
Port of the local server.
--username, -u / --password, -p
Basic authentication. They default to ORIGAMI_SERVER_USERNAME and ORIGAMI_SERVER_PASSWORD.
--interactive, -i
Run in direct interactive mode.
--model, -m / --agent / --continue, -c / --session, -s / --fork / --auto
The same meaning as in the terminal command.

Sub-commands

origami mcp add [name]
Add an MCP server. Options: --url, --env KEY=VALUE, --header KEY=VALUE.
origami mcp list
List MCP servers and their state. Also origami mcp auth, auth list, logout and debug <name>.
origami agent create
Create an agent. Options: --path, --description, --mode (all, primary, subagent), --permissions (alias --tools), --model.
origami agent list
List every available agent.
origami providers list / login [url] / logout [provider]
Show credentials, log in, log out. login accepts --provider and --method.
origami session list / delete <sessionID>
List sessions (--max-count, --format table|json) and delete one.
origami models
--verbose adds metadata such as cost. --refresh reloads the model database.
origami stats
--days, --tools, --models, --project.
origami db path
Print the database path. origami db [query] takes --format json|tsv.

Diagnostics

origami debug holds the diagnostic commands: config, paths, info, startup, skill, scrap, agent <name>, snapshot, file, rg, lsp and v2 (the built-in catalog and plugins).

Usage

Server

The engine runs headless. Other programs then drive it over HTTP.

Start a server

origami serve
origami serve --port 4096 --hostname 127.0.0.1
origami web

serve prints the address it listens on. web also opens the web interface.

Network options

These options belong to origami, acp, serve and web. They can also come from the server block of the configuration.

--port
number · default 0
Port to listen on. Zero means that the operating system chooses a free port.
--hostname
string · default 127.0.0.1
Hostname to listen on.
--mdns
boolean · default false
Enable mDNS service discovery. This changes the default hostname to 0.0.0.0.
--mdns-domain
string · default origami.local
Domain name for the mDNS service.
--cors
string array · default empty
More domains to allow for CORS.

Set a password. The server prints a warning when ORIGAMI_SERVER_PASSWORD is not set, because the server is then unsecured. --mdns binds to every interface.

Attach to a server

origami attach http://localhost:4096
origami run --attach http://localhost:4096 "list the open tickets"

The HTTP interface

The server is an Effect HTTP application. It publishes an OpenAPI document, and it accepts WebSocket connections.

The route groups are config, control, control-plane, event, experimental, file, global, instance, mcp, metadata, permission, project, project-copy, provider, pty, query, question, session, sync, tui and workspace.

A generated OpenAPI document is kept in the repository.

Configure

Models and providers

A model is named provider/model. A provider block describes where the model lives.

Choose a model

model
Model to use, in the format provider/model.
small_model
Small model for tasks such as title generation.

The name is split at the first slash only. A model identifier may therefore contain slashes, as in lmstudio/qwen/qwen3-coder-30b.

origami models lists every model as provider/model.

A provider block

{
  "provider": {
    "lmstudio": {
      "name": "LM Studio",
      "npm": "@ai-sdk/openai-compatible",
      "options": { "baseURL": "http://127.0.0.1:1234/v1" },
      "models": { "qwen3-coder-30b": { "name": "Qwen3 Coder 30B" } }
    }
  },
  "model": "lmstudio/qwen3-coder-30b"
}

The keys of a provider block are api, name, env, id, npm, whitelist, blacklist, options and models.

Provider options

options.apiKey
The credential for this provider.
options.baseURL
The endpoint of this provider.
options.timeout
Timeout in milliseconds for a whole request. false turns it off.
options.headerTimeout
Timeout in milliseconds to wait for the response headers. false turns it off.
options.chunkTimeout
Timeout in milliseconds between streamed chunks. The request stops when no chunk arrives in that time.
options.max_concurrent
Maximum number of generations in flight to this provider. Match the capacity of a self-hosted server, so that parallel subagents queue instead of starving it. Omit it for no limit.
options.setCacheKey
Enable the prompt cache key for this provider. Default false.
options.enterpriseUrl
GitHub Enterprise URL, for Copilot authentication.

Model overrides

Each entry of models may set id, name, family, release_date, attachment, reasoning, temperature, tool_call, interleaved, cost, limit, modalities, experimental, status, options, headers, variants and a nested provider.

limit holds context and output. modalities holds input and output lists over text, audio, image, video and pdf.

A model that the model database does not know keeps tool_call true and every other capability false. Set "tool_call": false for a model that cannot call tools.

Turn providers on and off

disabled_providers
Disable providers that load automatically.
enabled_providers
When set, only these providers are enabled.

Credentials

Credentials live in auth.json, in the data directory. The file is written with mode 0600. Three shapes are stored: oauth, api and wellknown.

Use origami providers login to add a credential and origami providers list to see what is stored. ORIGAMI_AUTH_CONTENT supplies the whole store from the environment instead.

Flock: a model for subagents

A Flock profile sets the model that subagent sessions use, and an ordered list of fallbacks.

{
  "flock": {
    "profile": "home",
    "profiles": {
      "home": {
        "description": "local first, cloud second",
        "subagents": {
          "use": "lmstudio/qwen3-coder-30b",
          "fallback": ["anthropic/claude-sonnet-4"]
        }
      }
    }
  }
}

An absent or null profile turns routing off. An unknown key inside a profile stops the load. Fallback happens on an authentication error, on HTTP 401, 403, 404, 408 and 429, and on any 5xx. Status 400 and 422 do not trigger it, because a malformed request fails the same way everywhere.

Configure

Local models

Origami Coder expects an OpenAI-compatible server on your own machine. This is the product's central design choice.

Connect a server

In VS Code, set origami.engineUrl. The default is http://localhost:1234/v1, which is an LM Studio server on the same machine. The setting overrides the ORIGAMI_API_BASE environment variable.

The connect picker offers LM Studio as "Local — runs on your own GPU (recommended)". It fills in the base URL http://127.0.0.1:1234/v1 and writes a provider block with the package @ai-sdk/openai-compatible.

Ollama uses the fixed endpoint http://localhost:11434/v1. The extension recognises an Ollama block by the provider identifier ollama, or by a loopback address on port 11434.

Any other OpenAI-compatible server works. Write the provider block by hand, as in Models and providers.

What counts as self-hosted

The engine reads the host name of the base URL. These count as self-hosted:

  • localhost, 0.0.0.0, ::1, and any name with no dot in it
  • names that end in .local, .lan or .ts.net
  • addresses in 127.*, 10.*, 192.168.*, 172.16.* to 172.31.*, and 100.64.* to 100.127.*

Longer timeouts for local hardware

A self-hosted endpoint gets a default chunk timeout and a default header timeout of 300000 milliseconds. A cloud endpoint gets neither. The reason is stated in the code: a large prefill on local hardware can run for minutes before the first token, and a stuck local stream has no server-side reaper.

Set options.chunkTimeout or options.headerTimeout in the provider block to change them.

The context window

A local server often does not report its window size. The extension probes for it in this order.

  1. The LM Studio endpoint /api/v0/models. It uses loaded_context_length, and only when the model state is loaded.
  2. The OpenAI-compatible endpoint /v1/models. It reads max_model_len, max_context_length or context_length.
  3. For Ollama, the native endpoint /api/show. It reads the architecture context length, a bare context_length, or a num_ctx parameter.

The maximum context length of a model is deliberately not used, because that value can be far larger than the memory of the machine.

Connecting a server saves the window too

Connecting a self-hosted server (the LM Studio or vLLM preset) writes the probed window into the saved model entry, not only into the display. This never overrides a window you set by hand, and a failed probe never blocks the connection — it just leaves the entry bare.

Control LM Studio

When LM Studio runs on the same machine, the extension can drive the lms command directly. It looks for the binary in ~/.lmstudio/bin. It loads a model with a chosen context length and unloads models. A remote LM Studio cannot be driven this way.

Two known problems of local servers

Thinking tags in the content
Some local servers put <think> markup on the content channel instead of the reasoning channel, sometimes with a closing tag and no opening tag. The engine scans for these tags and separates them.
Images sent to a text-only model
A local model usually has no entry in the model database, so the engine treats it as unable to see images. When a vision profile is configured and an image is present, it offers a vision_request tool instead of sending the image.

Match the server capacity

Set options.max_concurrent to the number of requests your server handles at once. Parallel subagents then queue instead of starving the server.

Configure

Agents

An agent is a named set of a prompt, a model and a permission list. A primary agent drives the session. A subagent does work for the task tool.

Built-in agents

NameModeDescription
buildprimaryThe default agent. It runs tools according to the configured permissions.
planprimaryPlan mode. It denies every edit tool, except files under .origami/plans/. It may delegate only to explore.
generalsubagentGeneral-purpose agent for research and multi-step tasks. It can run several units of work in parallel.
exploresubagentFast agent for exploring a codebase. It reads and searches only. Give it a thoroughness level: quick, medium, or very thorough.

Three more agents are internal and hidden: compaction, title and summary. They have every tool denied.

The default agent is build. Set default_agent to change it. The value must name a primary agent that is not hidden.

Shipped archetypes

The VS Code extension installs six ready-made agents into the global agent directory the first time you open the Folds board or the Collab Agents pane. Each is an ordinary markdown agent definition, so it works exactly like one you write yourself.

SlugModeCan editCan run shellNotes
architectall*.md onlynoDenies every tool by default, then re-allows reading, searching, the web and questions. Delegates only to scout.
askallnonoRead-only. Delegates only to scout.
debugallyesyesShips with no permission block of its own, so it has the same reach as build.
orchestratorallnonoAllows every tool except edit and bash. Delegates to any subagent.
scoutsubagentnonoRead-only. Not shown in the agent picker. A modified copy is reset on the next extension start, because the other archetypes trust it by name.
cartographerall.origami/map/* onlynoDelegates only to scout. Writes the repo architecture map.

Write your own

Put a markdown file at <config dir>/agent/<name>.md. The plural agents/ also works, and sub-folders become part of the name.

---
description: Reviews a diff and reports defects only.
mode: subagent
model: lmstudio/qwen3-coder-30b
temperature: 0.2
permission:
  edit: deny
  bash: ask
---

You review changes. Report defects. Do not fix them.

The body of the file is the prompt. Agents can also be written as JSON under the agent key of origami.json.

Frontmatter keys

KeyTypePurpose
descriptionstringWhen to use the agent. A subagent without one is only called by hand.
modesubagent, primary, allWhere the agent can be used. A file without this key defaults to all.
modelstringModel in the format provider/model.
variantstringDefault model variant. It applies only to the agent's own model.
temperature, top_pnumberSampling controls.
promptstringThe prompt. The markdown body usually supplies it.
permissionobjectTool permissions. See Permissions.
stepsintegerMaximum number of agent iterations before a text-only answer is forced.
hiddenbooleanHide the subagent from the @ menu. Default false.
disablebooleanRemove the agent, including a built-in one.
colorstringA hex colour, or one of primary, secondary, accent, success, warning, error, info.
optionsobjectProvider-specific values. Any unknown key is moved here.

The keys tools and maxSteps are deprecated. Use permission and steps. The key role is accepted and ignored.

Subagents

The task tool lists every agent whose mode is not primary and that the caller's task permission does not deny.

subagent_depth limits the nesting. The default is 1, so a subagent cannot start another subagent.

Create an agent file from the command line with origami agent create, and list agents with origami agent list.

Configure

Collab

A collab is a shared room. Several agents and one human read the same message log. Each agent keeps its own session, and the room keeps a task board and a cost ledger.

How it differs from a session and a subagent

An ordinary session is one agent and one human. A subagent is started by the task tool, it answers once, and it is then gone. A collab is durable: the message log, the roster, the board and the ledger are rows in the database, so the room survives a restart.

Each participant gets its own persistent child session. The session is created on the agent's first turn, not when it joins, so a roster entry that never speaks costs nothing.

By default, only one turn runs at a time in one collab, and turns are held in a queue. A room may opt into running several turns at once with concurrency: N (up to 4), but only when every member's own permissions deny every file-writing tool outright — a wide room may read and discuss, it may not build. A council-flavored room (see below) always dispatches wide, because its turns are sealed read-only regardless of the setting.

A collab is driven from the VS Code extension. There is no collab CLI command, no terminal UI screen and no HTTP route. The engine surface is a set of ACP methods, listed below.

Flavors: discuss and council

A collab has a flavor, set with collab_set_flavor: discuss, the default, or council. A room with no stored flavor is a discuss room.

In a council, one human question dispatches to every active member at once. Each member reads the room as it stood at the question, so no member sees a sibling's opinion before it answers. Once every member has settled, the lead — or the first member in roster order if there is no lead — reads every opinion and writes one synthesis for the room. Council turns are sealed read-only, so a council may run wide with nothing to configure.

A hop, in a council, is the whole round: the opinions and the synthesis together cost one hop, not one each.

Make an agent collab-capable

An agent can join a room only if its definition file sets collab: true. The key is not a known agent key, so it is moved into options, and the roster check reads it from there.

---
description: Reads code and reports what it found.
mode: subagent
model: lmstudio/qwen3-coder-30b
collab: true
vision: true
---

You are the scout. You read the repository and report facts.

The check fails closed. An agent without the key, or with frontmatter that does not parse, is refused with a message that names the file.

vision: true is a second, separate opt-in. It controls images only. See Images below.

The base prompt

Every collab agent gets a built-in base prompt above its own persona. The prompt states what the room is, what the tools do, and who routes work next. Live room state is added below the persona.

To replace the built-in text, write collab-agent-base.md in the global config folder. A missing, unreadable or empty file is not an override, and the built-in text is used.

The state block below the persona is rebuilt for every turn. It names the roster, the lead, the objective, the hops left and the first open tasks.

Run a collab

The composer in the VS Code chat view has nine slash commands for a room.

/rename
Retitle this collab.
/archive
Close this collab. It stays in History.
/invite
Add a collab agent to the roster.
/remove
Remove an agent from the roster.
/lead
Set the collab lead.
/objective
Set the standing goal of the room.
/cap
Set the loop breaker: a number, off, or default.
/context
Show the last prompt of an agent.
/stop
Interrupt the agents until you post again.

A line that is not one of these nine is posted to the room as a message.

The lead and addressing

One agent is the lead. An unaddressed human message goes to the lead alone. With no lead set, nobody is woken, and the post is answered with the notice no-lead.

The lead is kept on an active agent. An empty seat is filled by the first agent in join order. If the lead is removed, the next agent takes the seat. Roster order is join order, not alphabetical order.

To address named agents, write @slug in the composer. The composer parses the line and sends a structured list of slugs. Unknown slugs are dropped, and the engine checks the list against the active roster before it writes anything.

Routing reads the kind of a message and its structured list of slugs. It never reads the prose. An @name written inside a sentence is a reference, and it wakes nobody. An ordinary message from an agent also wakes nobody: agents route work with the tools below, not with text.

The rules are an ordered list, and the first rule that has an opinion decides. In order: never the author, a human message to the named agents, an unaddressed human message to the lead, answers and directed messages to nobody, finished and reopened board work back to the agent that owns it, and silence for everything else. A rule that throws an error ends the decision at "skip".

Tools inside a turn

Eight tools exist only inside a collab turn. They are added to the request when a collab turn is present, and never at any other time, so an ordinary chat sees none of them. They are part of the protocol, so a permission list that denies by default does not remove them.

ToolParametersEffect
askto, task, context, expectStops the caller's turn. The target runs a full turn, and the answer returns to the caller.
handoffto, task, contextPasses the work and ends the caller's turn. No answer returns.
donesummaryEnds the turn. The summary is optional, and silence is valid.
task_addtitleOpens a task that nobody owns.
task_claimtaskIdTakes ownership of a task.
task_donetaskId, resultRecords the result and wakes the agent that opened the task.
task_accepttaskIdCloses a task after a check.
task_reopentaskId, noteSends the task back to its owner with a reason.

A target is resolved against the active roster by slug first, then by display name. A leading @ is removed, and the match ignores letter case.

ask is refused, in this order, when the target is not on the roster, when the target is already waiting further up the same chain, when the chain is three deep, when the room has no hops left, and when the target session is busy. A refusal is returned to the one model that called the tool. The room does not see it.

The hop budget

A hop is one agent turn. One human message buys a fixed number of hops. When they are spent, the agents stop, and the room waits for a human.

Cap valueResult
not set (null)The engine default of 20 hops.
0The budget is off. The room runs until it is stopped.
a positive integerThat many hops for each human message.

The cap is stored for each collab as loop_breaker_cap. It must be null or an integer that is not negative. A new human post refills the budget. A stop spends all of it.

The budget is shared by reference along a chain of asks, so a deeper call cannot buy more hops. The agents are told how many wakes are left on each turn.

The task board

A task is the unit of accountability between agents. A task has one of four states: open, claimed, done and accepted. An ask opens a task by itself, and a human can add one by hand.

The board records the title, the owner, the agent that created it, the result, the note that reopened it, and the message that created it. A board move is a record. By itself it wakes nobody, except that finished work wakes the agent that asked for it, and reopened work wakes its owner.

A task title is cut to 80 characters, because the title is a label and the full brief is in the message.

Cost and tokens

One row is written for each completed turn, including a silent turn. A silent turn still spends tokens.

Each row holds the agent slug, the model as provider/model, the input tokens, the output tokens, the cost, and the agent that asked for the turn on a nested turn. Spend is summed from the step records of the turn.

The ledger returns a page of rows and a set of totals for each agent. The totals are summed in the database, so they cover the whole ledger and not only the page. The page holds 100 rows by default.

Images

Only a human can post an image. No agent tool accepts one. Images are stored in the message row as data: URLs, because the log is the record.

An image is refused if the message carries more than four images, if it is not a data: URL, or if it is larger than 2 MB. The check runs before anything is written.

An agent with vision: true receives the image. An agent without it receives a note that says how many images it cannot see, and the base prompt tells it to say so and to ask a participant that can see them. If the definition cannot be read, the agent is treated as unable to see.

What is stored

TableHolds
collabTitle, loop breaker cap, lead slug, objective, and the archive time.
collab_participantThe roster. Keyed by collab and agent slug. Holds the child session and the last log entry the agent has seen.
collab_messageThe append-only log. Holds the sequence number, the author, the kind, the text, the addressed slugs, the tool trace and the images.
collab_taskThe task board.
collab_turn_costThe cost ledger.

The sequence number is unique for each collab, so the same number cannot be used twice in one room. Every table refers to collab and is deleted with it. Removing an agent is a soft delete, and adding it again keeps its session and its position in the log.

The tables are created by three migrations: the first adds the collab, the roster and the log; the second adds the board, the ledger and six columns; the third adds the images column.

Which agent is mid-turn, and whether the loop breaker has tripped, are computed from the log. They are not stored, so a restart cannot leave a stale state behind.

Engine methods

The engine exposes collab over ACP as twenty-three extension methods. Each method that acts on one room needs a collabId.

MethodPurpose
collab_agentsList the agents that can join.
collab_listList the rooms.
collab_createCreate a room.
collab_postPost a human message, with optional images.
collab_previewShow which agents a draft message would wake, without posting it.
collab_stateRead the roster, the log, the board, the hops, the cost totals and the live activity.
collab_set_capSet the loop breaker cap.
collab_set_concurrencySet how many turns the room may run at once (1-4). Refused unless every member is read-only for files.
collab_set_flavorSet the room's flavor: discuss or council. See Flavors below.
collab_set_leadSet the lead. The agent must be on the roster.
collab_set_objectiveSet the standing goal.
collab_task_addAdd a board task.
collab_task_updateMove a task: claim, done, accept or reopen.
collab_reviewApprove or reject a task, with an optional note.
collab_ledgerRead the cost rows and the totals.
collab_stopStop the agents.
collab_stop_agentStop one named agent without stopping the whole room.
collab_redirectSend a correction to one named agent, outside the ordinary wake rules.
collab_archiveClose the room.
collab_unarchiveReopen a closed room.
collab_renameRetitle the room.
collab_add_participantAdd an agent to the roster.
collab_remove_participantRemove an agent from the roster.

There is no method that creates or edits an agent definition. A definition is a file, and the extension edits it directly.

A collab publishes no event. A client reads the room by calling collab_state again.

Limits

LimitValue
Default hop budget20 turns for each human message
Depth of a chain of asks3
Room messages put in a brief10
Tasks returned with the room state50
Open tasks shown to an agent8
Tool trace entries for each message20
Characters in one trace summary120
Images for each message4
Size of one image2 MB
Characters in a live activity line200
Characters in a live thought4000
Ledger rows for each page100

The roster size and the length of the log are not limited. There is no timeout and no rate limit. The hop budget is the only control on how long a room runs.

The number of steps in one turn comes from the steps key of the agent definition. See Agents. A turn that hits that cap is not posted to the room.

Configure

Folds board

The Folds board is a ticket kanban over git worktrees, in the VS Code extension. A ticket is a markdown file. Starting work on it provisions a worktree and a session.

Tickets

A ticket lives at <repo>\.origami\tickets\<id>.md, with an id of t- plus six base36 characters. The frontmatter holds scalars only. Acceptance criteria are - [ ] lines under an ## Acceptance heading, and an append-only ## Log records history. A status is one of triage, todo, pending, in_progress, done, merged or closed.

Engine tools

ToolPurpose
board_reposList the repositories the board knows about, with a ticket count for each state.
board_ticketsList the tickets of one repository, or read one ticket in full.
board_createCreate a ticket. One with acceptance criteria lands in Todo; one without lands in Triage.
board_updateClaim, comment, retitle, relabel, re-prioritise, or change the state of a ticket.

Reading never asks. Every mutation goes through the board permission key. A bare repo of . is refused outside a git repository, so a ticket cannot land at the drive root.

The repo registry

The extension writes a cross-repo registry at ~\.origami\repos.json, with an atomic write. The board tools, and the standalone board MCP bridge, resolve a repo name against this file.

Configure

Commands

A slash command is a prompt template with a name. Four come with the engine. You can add your own.

Built-in commands

/init
Guided AGENTS.md setup.
/review
Review changes: a commit, a branch or a pull request. It defaults to the uncommitted changes. It runs as a subtask.
/verify-plan
Audit the changes against the todo list of this session. It runs as a subtask.
/dream
Curate memory: reorganise the store from recent sessions, then approve, revise or disapprove. It runs inline.

The registry also holds one command per MCP prompt, and one command per skill.

Write your own

Put a markdown file at <config dir>/command/<name>.md. The plural commands/ also works. A sub-folder becomes part of the name, so command/git/sync.md is /git/sync.

---
description: Summarise recent git changes
agent: build
---

Summarise what changed in the last $ARGUMENTS commits.
Group the changes by area and name anything risky.

Frontmatter keys

description
Text shown in the command list.
agent
Agent that runs the command.
model
Model that runs the command.
variant
Model variant.
subtask
Run the command in a subagent instead of the current session.

The markdown body is the template. Commands can also be written as JSON under the command key of origami.json.

Arguments

  1. The argument text is split into words. Quoted groups stay together, and the quotes are removed.
  2. $1, $2 and so on take the words in order. The highest number in the template takes every remaining word. A missing position becomes an empty string.
  3. $ARGUMENTS takes the whole argument text, unsplit.
  4. A template with no $N and no $ARGUMENTS gets the argument text added at the end.
  5. Text inside !`...` is run as a shell command, and the output replaces it.

The model of a command is its own model, then the model of its agent, then the model of the session.

Commands that belong to one surface

Some commands are not engine commands. They work only in the client that owns them.

  • VS Code: /firstfold, /spend, /loop, /compose. See VS Code.
  • Terminal: /sessions, /models, /themes and the rest of the list in Terminal UI.

Configure

Skills

A skill is a markdown file of reusable knowledge. The model loads it when the task matches.

Where skills are found

  1. Every configuration directory: skill/**/SKILL.md and skills/**/SKILL.md. This covers .origami/skills/ in the project, ~/.origami/skills/, and the global configuration directory.
  2. External directories: .claude/skills/**/SKILL.md and .agents/skills/**/SKILL.md, both in your home directory and in the project.
  3. Paths listed in skills.paths. ~/ is expanded.
  4. Indexes listed in skills.urls. The files are downloaded into the cache directory.
  5. Skills supplied by an agent plugin.

Claude Code skills in ~/.claude/skills are not read by default. Set ORIGAMI_DISABLE_CLAUDE_CODE_SKILLS=false to read them. ORIGAMI_DISABLE_EXTERNAL_SKILLS turns off every external directory.

The file

---
name: tdd
category: workflow
description: Write the failing test first, then make it pass.
---

# Test first

Reproduce the defect in a test before you change the code...
name
required
The registry key. It is the name that the model uses, not the folder name. A file with no valid name is skipped.
description
optional
Shown to the model in the skill list. A skill with no description is left out of that list.
category
optional
A free grouping label. It is never checked against a list.

Everything after the frontmatter is the body. Two files with the same name produce a warning, and the last one wins.

How a skill runs

  • The model calls the skill tool with the skill name. The body then enters the conversation.
  • You type /<name>. Every skill is registered as a slash command, unless a command or an MCP prompt already owns that name.

The system prompt lists only the name and the description of each permitted skill. The body is read only through the skill tool.

Limit which skills an agent may use

Skills are filtered per agent by the skill permission key. There is no permission field inside the skill file.

{
  "agent": {
    "reviewer": {
      "permission": { "skill": { "*": "deny", "code-review": "allow" } }
    }
  }
}

The folder of a skill is added to the allowed external directories, so the agent can read the scripts/ and references/ beside it without a prompt.

origami debug skill lists every skill that the engine found.

Configure

Tools

A tool is a function that the model can call. Each one is subject to the permission rules.

Files and shell

ToolPurpose
readRead a file or a directory.
writeWrite a file.
editExact string replacement in a file.
apply_patchEdit files with a file-oriented diff format.
fileCopy, move, rename, delete, and create directories.
globFast file pattern matching.
grepFast content search with regular expressions.
bashRun a shell command, with an optional timeout.
processRead-only view of running processes and of listening TCP ports.
git_diffShow staged and unstaged changes.

For a GPT model, apply_patch replaces edit and write.

Work and delegation

ToolPurpose
taskStart a subagent for a complex, multi-step job.
todowriteKeep a task list for the session.
skillLoad a skill into the conversation.
questionAsk the user a question during a run. It is available in the application, CLI and ACP clients.
session_searchSearch the text of your own past sessions.
rememberWrite a durable fact, decision or gotcha to memory.
dreamThe memory-curation backend of the /dream command.

Web, charts and the browser

ToolPurpose
webfetchFetch the content of a URL.
websearchSearch the web with the search provider of the session.
chartDraw a bar, line or pie chart in the chat.
browserOpen and drive the VS Code integrated browser: navigate, screenshot, read, click, type. Other clients get an explanation instead.

Board and messages

ToolPurpose
board_reposList the repositories on the Folds board, with ticket counts per state.
board_ticketsRead the board of one repository, or one ticket in full.
board_createCreate a ticket. With acceptance criteria it lands in Todo; without them it lands in Triage.
board_updateClaim, comment, retitle, relabel, re-prioritise, or change the state of a ticket.
list_agentsList the other Origami sessions on this machine that you can message.
send_messageSend a short handoff to another session. Delivery does not block the sender.

Tools behind a flag

lsp
Language-server features. Needs ORIGAMI_EXPERIMENTAL_LSP_TOOL.
plan_exit
Leave plan mode. Needs ORIGAMI_EXPERIMENTAL_PLAN_MODE, in the CLI and ACP clients.
task_list, task_stop
List and cancel background subagents. Needs ORIGAMI_EXPERIMENTAL_BACKGROUND_SUBAGENTS.
execute
Code mode. One tool runs a confined JavaScript program that calls several MCP tools. Needs ORIGAMI_EXPERIMENTAL_CODE_MODE, or the VS Code setting origami.experimentalCodeMode.
tool_search
Search the catalog of deferred tools and load their schemas. It is controlled by experimental.tool_search.

Your own tools

Put a JavaScript or TypeScript file at <config dir>/tool/<name>.ts. The plural tools/ also works. Each exported object with args, description and execute becomes a tool. The default export takes the file name; another export takes <file>_<export>.

A plugin can add tools too, and can rewrite the description and the parameters of any tool. See Plugins.

Size of tool output

Output above tool_output.max_lines (2000) or tool_output.max_bytes (51200) is written to a file, and the model receives a shorter preview with the path.

Configure

Memory

Memory is a folder of markdown files the model reads with the read tool. One index file loads every turn; every other file loads only when the model asks for it.

The layout

~/.origami/memory/              global
<worktree>/.origami/memory/    project

MEMORY.md                       the index, loaded every turn
<topic>.md                     one topic, read on demand
inbox.md                        facts waiting for a home

MEMORY.md holds one line for each topic: a name and a short hook. The engine appends a footer telling the model to read a topic file with the read tool before it acts on a hook. A machine with only the older flat memory.md still loads that file; the two forms are never both active.

Write to memory

The remember tool appends a dated fact to a topic file, then updates that topic's line in the index. An existing hook line is never overwritten by a new fact. Topic files grow without a size limit; length only costs tokens once the model reads that file.

/dream

The /dream command curates the store. It reads recent sessions plus the current index and topics, then stages a full proposed replacement folder for you to approve, revise or disapprove. Approving backs up the live folder first, then writes the staged files one by one.

Memory graph

The VS Code sidebar and the Full editor tab both show memory as a force-directed graph of the topic files and their wikilinks, with a live filter on title, tags and path.

Configure

Permissions

Every tool call is checked against a rule list. A rule gives one of three answers.

The three answers

allow
Run the tool without a prompt.
ask
Ask the user first.
deny
Refuse the call.

When the user is asked, the possible replies are once, always and reject.

Write the rules

{
  "permission": {
    "bash": { "git status*": "allow", "*": "ask" },
    "edit": "allow",
    "webfetch": "ask",
    "external_directory": { "*": "ask" }
  }
}

A bare string is shorthand. "permission": "ask" means {"*": "ask"}.

The keys

These keys accept either an answer or a map of pattern to answer: read, edit, glob, grep, list, bash, task, external_directory, lsp, skill, plugin.

These keys accept an answer only: todowrite, question, webfetch, websearch, doom_loop.

Other keys are allowed. A plugin tool is addressed as plugin:<name>:<tool>.

Patterns

  • * matches any text. ? matches one character.
  • Backslashes become forward slashes before the match, in both the pattern and the value.
  • A pattern that ends with a space and a star also matches the bare command, so git status * matches git status.
  • The match ignores letter case on Windows only.
  • The last rule that matches wins. Key order in the file is preserved and is therefore meaningful.

The defaults

Before your rules are applied, the engine starts from this set.

RuleAnswer
*allow
doom_loopask
external_directoryask, except for whitelisted directories
question, plan_enter, plan_exitdeny, then re-allowed per agent
read of *.env and *.env.*ask. *.env.example stays allowed.

An agent adds its own rules on top. The plan agent denies every edit outside .origami/plans/, and allows delegation only to explore.

Approve everything

--auto approves every permission that is not explicitly denied. The command line describes it as dangerous. It works on the terminal command and on run. The setting is read live, so a change during a turn takes effect at once.

Saved answers

An answer of always is stored. In VS Code, run Origami: Reset saved permissions to clear the stored answers of the workspace.

From the environment

ORIGAMI_PERMISSION holds JSON that is merged over the permission block. Invalid JSON is skipped, with a warning.

Configure

MCP servers

A Model Context Protocol server adds tools and prompts. Origami Coder connects to local processes and to remote servers.

A local server

{
  "mcp": {
    "my-server": {
      "type": "local",
      "command": ["bun", "x", "my-mcp-server"],
      "cwd": "./tools",
      "environment": { "TOKEN": "{env:MY_TOKEN}" },
      "enabled": true,
      "timeout": 5000
    }
  }
}
command
array, required
The command and its arguments. It is a list, not one string.
cwd
Working directory. A relative path is read from the workspace directory.
environment
Environment variables for the process.
enabled
Start this server or not.
timeout
Timeout in milliseconds for requests. Default 5000.

A remote server

{
  "mcp": {
    "docs": {
      "type": "remote",
      "url": "https://example.com/mcp",
      "headers": { "Authorization": "Bearer {env:DOCS_TOKEN}" },
      "enabled": true
    }
  }
}
url
required
Address of the server.
headers
Headers sent with each request.
oauth
OAuth settings, or false to stop OAuth detection.
oauth.clientId, oauth.clientSecret, oauth.scope
Client credentials. Without a client identifier, dynamic client registration is tried.
oauth.callbackPort
Port of the local callback server. Default 19876.
oauth.redirectUri
Redirect address. Default http://127.0.0.1:19876/mcp/oauth/callback.

Manage servers

Use origami mcp add, origami mcp list, origami mcp auth, origami mcp logout and origami mcp debug <name>. In the terminal interface, /mcps turns servers on and off.

A plugin may also supply servers. Plugin servers are merged before the servers of the configuration file.

Protocol

The client targets the 2026-07-28 revision and negotiates with server/discover. A server that answers only the older initialize handshake is treated as legacy. The client identifies itself as origami.

Keep the tool list small

MCP tools are deferred by default. Each server then costs one catalog line until the model searches for it with tool_search. Change this with experimental.tool_search.

Code mode is the other option. One execute tool replaces the individual MCP tools, and the model writes a short program that calls several of them.

Configure

Themes

The terminal interface and the VS Code extension have separate theme systems.

Terminal themes

Set the theme key in tui.json, or press the theme key (<leader>t by default) to open the picker.

The built-in names are:

aura, ayu, carbonfox, catppuccin, catppuccin-frappe, catppuccin-macchiato, cobalt2, cursor, dracula, everforest, flexoki, github, gruvbox, kanagawa, lucent-orng, material, matrix, mercury, monokai, nightowl, nord, one-dark, origami, orng, osaka-jade, palenight, rosepine, solarized, synthwave84, tokyonight, vercel, vesper, zenburn.

The fallback theme is origami.

Your own theme

Put a JSON file at <config dir>/themes/<name>.json. This works in the global configuration directory and in each .origami directory.

Priority runs from low to high: built-in themes, plugin themes, your own files, then a theme generated from the terminal colours.

VS Code themes

The extension contributes five colour themes: Origami Meadow, Origami Harbour, Origami Ember, Origami Midnight and Origami Custom.

The command Origami: Toggle Theme steps through meadow, harbour, ember, midnight and custom. The setting origami.syncVsCodeTheme decides whether the editor theme follows the dashboard theme: ask, always or never.

Configure

Keybinds

The terminal interface uses a leader key. Overrides go in tui.json.

Change a binding

{
  "keybinds": {
    "session_new": "ctrl+t",
    "app_debug": "<leader>d",
    "messages_copy": "none"
  }
}

The value none or false removes a binding. A comma separates alternatives. <leader> stands for the leader key. An unknown binding name is dropped, and does not stop the load.

The leader key is ctrl+x. leader_timeout sets how long the leader waits, in milliseconds. The default is 2000.

Session and application

NameDefaultAction
app_exitctrl+c,ctrl+d,<leader>qExit the application.
command_listctrl+pList the available commands.
session_new<leader>nCreate a session.
session_list<leader>lList the sessions.
session_timeline<leader>gOpen the timeline.
session_renamectrl+rRename the session.
session_deletectrl+dDelete the session.
session_interruptescapeInterrupt the session.
session_backgroundctrl+bSend the session to the background.
session_compact<leader>cCompact the session.
session_export<leader>xExport the session.
session_quick_switch_1_9<leader>1<leader>9Switch session by number.
status_view<leader>sShow the status.
sidebar_toggle<leader>bShow or hide the side panel.
editor_open<leader>eOpen the external editor.
theme_list<leader>tSwitch the theme.
tips_toggle<leader>hShow or hide the tips.

Model and agent

NameDefaultAction
model_list<leader>mList the models.
model_provider_listctrl+aList the providers.
model_favorite_togglectrl+fMark a model as a favourite.
model_cycle_recentf2Step through the recent models.
agent_list<leader>aList the agents.
agent_cycletabStep to the next agent.
agent_cycle_reverseshift+tabStep to the previous agent.
variant_cyclectrl+tStep through the model variants.

Messages and the prompt

NameDefaultAction
input_submitreturnSend the prompt.
input_newlineshift+return,ctrl+return,alt+return,ctrl+jInsert a new line.
input_clearctrl+cClear the prompt.
messages_page_uppageup,ctrl+alt+bScroll up one page.
messages_page_downpagedown,ctrl+alt+fScroll down one page.
messages_firstctrl+g,homeGo to the first message.
messages_lastctrl+alt+g,endGo to the last message.
messages_copy<leader>yCopy a message.
messages_undo<leader>uUndo the previous message.
messages_redo<leader>rRedo.

Diff viewer

NameDefaultAction
diff_closeescape,qClose the viewer.
diff_toggleenter,spaceOpen or close an item.
diff_next_hunk / diff_previous_hunk] / [Move between change blocks.
diff_next_file / diff_previous_filen / pMove between files.
diff_toggle_file_treebShow or hide the file tree.
diff_help?Show the viewer help.

VS Code has its own bindings. See VS Code.

Develop

Plugins

A plugin adds tools, providers, authentication methods, and hooks around the turn.

Load a plugin

Two ways work.

  • Put a .ts or .js file in <config dir>/plugin/ or <config dir>/plugins/. It loads with no configuration entry.
  • Name it in the plugin array of the configuration. A relative path is read from the directory of the configuration file. Any other value is treated as an npm package name and installed.
{
  "plugin": [
    "./plugins/my-plugin.ts",
    ["some-npm-plugin", { "option": true }]
  ]
}

origami plugin <module> installs a plugin and writes the entry. It accepts --global and --force.

--pure or ORIGAMI_PURE starts the engine with no external plugins.

Plugins from agent-plugins.org are listed separately in agentPlugins, and managed with origami agent-plugin add and origami agent-plugin list.

Hooks

The package is @origami/plugin.

HookWhen it runs
configThe configuration is ready.
eventAn event happens.
disposeThe plugin stops.
toolDeclare new tools.
authAdd an authentication method for a provider.
providerAdd or change provider models.
chat.messageA new message arrives.
chat.paramsChange the parameters sent to the model.
chat.headersChange the request headers.
permission.askChange the answer of a permission check.
command.execute.beforeBefore a command runs.
tool.execute.beforeBefore a tool runs. It can change the arguments.
tool.execute.afterAfter a tool runs. It can change the title, output and metadata.
tool.definitionChange the description and parameters that the model sees.
shell.envChange the environment of a shell call.

Experimental hooks

experimental.chat.messages.transform
Rewrite the message list before the request.
experimental.chat.system.transform
Rewrite the system block.
experimental.provider.small_model
Choose the small model of a provider.
experimental.session.compacting
Run before compaction. It can add context, or replace the compaction prompt.
experimental.compaction.autocontinue
Decide whether a synthetic continue message follows compaction.
experimental.text.complete
Change a finished text part.

The package also exports @origami/plugin/tool and @origami/plugin/tui. Terminal plugins are declared in tui.json, under plugin and plugin_enabled.

Develop

SDK and HTTP API

The SDK package starts a server and talks to it from JavaScript.

The package

The package is @origami/sdk. Its entry points are ., ./client, ./server, ./v2, ./v2/client, ./v2/server and ./v2/types.

The main entry exports createOrigamiClient, createOrigamiServer, and createOrigami, which starts a server and returns both.

import { createOrigami } from "@origami/sdk"

const { client, server } = await createOrigami()

Types from the API document

The client types are generated from the OpenAPI document. The generated document is kept in the repository, and origami generate writes it.

Handlers

The @origami/server package holds the handler groups: agent, command, credential, event, fs, health, integration, location, message, model, permission, project-copy, provider, pty, question, reference, session and skill.

The editor protocol

origami acp starts an Agent Client Protocol server. The VS Code extension uses it. Use --cwd to set the working directory.

Help

Troubleshooting

Most reports come from one of these causes.

A change does not appear

Find out which artifact holds the change. A change under packages/vscode/ needs a new extension. A change under packages/engine/ needs a new engine binary. Rebuilding one does nothing for the other.

Check what went into the engine binary:

grep -a "someSymbolYouAdded" ~/.origami/bin/origami.exe

An old engine still serves the session

A deploy replaces the binary, but a window that is already open keeps the process that it started. The extension compares the modification time of the binary at start with the time on disk now, and reports a stale engine.

Start a new session, or reload the window.

Engine edits do not take effect

Set origami.devEngineSource to the path of a packages/engine source tree. The extension then runs the engine from source with Bun, and a window reload picks up the edits. With an empty or invalid value, the compiled binary is used and a reload changes nothing. The output channel of the extension logs which one started.

The model is unreachable

The banner has four states: ok, probing, offline-local and offline-remote. The local state means that the loopback LM Studio has no model loaded. Check that the server runs, that a model is loaded, and that origami.engineUrl ends in /v1.

The context meter shows nothing

A local server often reports zero for the window size. The meter treats zero as "not known" and keeps the last real value. The extension probes the server for the true window size.

A long local request stops

A self-hosted endpoint has a default chunk timeout and header timeout of 300000 milliseconds. Raise options.chunkTimeout and options.headerTimeout in the provider block, or set them to false to remove the limit on the whole request.

The configuration file is refused

An unknown key at the top level stops the load. The message names the key. Note that theme, keybinds and tui belong in tui.json.

Print what the engine really read:

origami debug config
origami debug paths

See the logs

origami --print-logs --log-level DEBUG

Turn behaviour off

ORIGAMI_DISABLE_AUTOCOMPACT
Stop automatic compaction.
ORIGAMI_DISABLE_PRUNE
Stop the pruning of old tool output.
ORIGAMI_DISABLE_MODELS_FETCH
Stop the model database download.
ORIGAMI_DISABLE_PROJECT_CONFIG
Ignore project configuration.
ORIGAMI_PURE
Start with no external plugins.

Legal

Attribution

Origami Coder began as a fork of OpenCode.

Upstream project

OpenCode is the upstream project. Origami Coder started as a fork of the OpenCode repository on GitHub.

License

OpenCode is licensed under the MIT License. Its copyright notice reads:

Copyright (c) 2025 opencode