JackyJacky

Jacky integrates with OpenCode through three complementary mechanisms:

  1. Reaction plugin — A small JS plugin forwards OpenCode's lifecycle events to Jacky; Jacky reacts with emotions and speech automatically.
  2. MCP tool server — OpenCode can call Jacky tools (speak, notify, emote, run routines, and more) via the Model Context Protocol.
  3. Managed instructions — A marker block in a Jacky-managed file tells OpenCode about Jacky's capabilities.

All three are set up with a single command: jacky opencode install.

Note

OpenCode has no settings.json-style hook system like Claude Code — reactions are delivered through a plugin file instead. See Claude Code Integration if you're connecting that agent too; both integrations run side by side with independent reaction settings.


Quick Start

# 1. Launch the Jacky desktop app
jacky
 
# 2. One-command setup
jacky opencode install
 
# 3. Restart Jacky to activate the WebSocket + MCP servers

That's it. OpenCode will now trigger Jacky reactions automatically, and can call Jacky tools via MCP.

Warning

Restart required: After running jacky opencode install, restart the Jacky desktop app so the WebSocket and MCP servers start with the new configuration.


Reaction Plugin

How It Works

OpenCode delivers most lifecycle events through a generic event hook (rather than one hook per event type), plus a few named hooks for chat messages and tool calls. Jacky's plugin listens to both and reacts in real time on your desktop:

OpenCode EventJacky's ReactionWhat It Means
chat.message🤔 ThinkingYou sent a message to OpenCode
tool.execute.before / tool.execute.after🔧 WorkingOpenCode is executing a tool
permission.updated / permission.asked⚠️ AlertingOpenCode needs your approval to run something
question.asked⚠️ AlertingOpenCode is waiting on you to pick an option
session.idle😊 HappySession finished without errors
session.error😢 HurtSomething went wrong
Note

By default OpenCode auto-approves tool calls, so permission.updated rarely fires unless you configure approval prompts (e.g. "permission": {"bash": "ask"} in your opencode.json). The question.asked event — OpenCode's built-in "ask the user a question" tool — is treated the same way, since it's also a "waiting on you" moment.

Event Priority

OpenCode sometimes fires multiple events within milliseconds of each other — for example, session.error immediately followed by session.idle. Jacky resolves this with an event priority window: a lower-priority event won't overwrite a higher-priority reaction that just landed. From highest to lowest priority: task failed, permission/notification, task finished, working, prompt submitted.

Throttling

To avoid overwhelming you with reactions during rapid agent activity, Jacky applies the same smart cooldowns used for Claude Code:

Cooldown TypeDurationDescription
Reaction10 secondsSame reaction won't re-trigger within 10s
Speech20 secondsSame speech category won't fire within 20s
Permission3 secondsPermission/question events fire more frequently

Claude Code and OpenCode use separate throttle state, so activity in one agent never suppresses reactions from the other.


MCP Tool Server

Jacky runs the same Model Context Protocol server used for Claude Code — a streamable HTTP transport bound to 127.0.0.1 (localhost only). Install adds it to OpenCode's config as a "remote" MCP entry.

Available MCP Tools

Once connected, OpenCode can call these Jacky tools:

ToolDescription
jacky_saySpeak text aloud with voice and show a speech bubble
jacky_notifyShow a system tray notification (no voice)
jacky_emoteChange Jacky's animation/emotion state
jacky_react_toHave Jacky react to text with an AI-generated response
jacky_askSend text through Jacky's full agent pipeline
jacky_run_routineRun a Jacky routine by ID with optional variables
jacky_set_timerCreate a countdown timer
jacky_set_alarmCreate an alarm clock
jacky_statusGet Jacky's current status (state, LLM, TTS, version)
jacky_move_toWalk Jacky to absolute screen coordinates (pixels)
jacky_moveWalk Jacky a relative distance in pixels (left/right/up/down/top/bottom)

Authentication

Jacky's MCP server requires a Bearer token — auto-generated once and stored securely in your OS keyring. jacky opencode install reads that token and writes it into the MCP entry's headers:

{
  "mcp": {
    "jacky": {
      "type": "remote",
      "url": "http://127.0.0.1:9877/mcp",
      "enabled": true,
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}
Warning

If you regenerate the MCP token in Jacky's Settings → Integrations → MCP Server tab, the token written into opencode.json becomes stale and OpenCode will report that Jacky needs authentication. Re-run jacky opencode install to sync the new token.

Security

  • The server is bound to localhost only (127.0.0.1) — not accessible from other machines
  • Bearer token authentication (stored securely in your OS keyring)
  • Allowed actions are configurable — you choose which tools external agents can use
  • Error messages are sanitized before reaching the AI agent (no file paths, tokens, or tracebacks leaked)

Managed Instructions

When you run jacky opencode install, Jacky writes a managed instructions file (jacky.md) next to your OpenCode config and adds its path to the instructions array so OpenCode reads it automatically:

<!-- BEGIN JACKY:MANAGED -->
## Jacky Desktop Pet Integration
 
Jacky is a desktop pet that reacts to your coding activity in real time.
When you use OpenCode, Jacky will automatically emote and react to
lifecycle events (thinking, working, success, errors).
 
To control Jacky programmatically, use the `jacky` CLI:
 
- `jacky say "text"` — make Jacky say something
- `jacky emote happy` — set Jacky's emotion
- `jacky status` — check if Jacky is running
 
This integration is managed by `jacky opencode`. Do not edit the marker block.
Run `jacky opencode uninstall` to remove.
<!-- END JACKY:MANAGED -->

If jacky.md already has content of your own, Jacky only touches the marker block — everything else in the file is left untouched, and uninstalling deletes the file only if the managed block was the only content.


Configuration Scope

By default, jacky opencode install configures OpenCode globally:

ScopeConfig directoryNotes
Global (default)~/.config/opencode/Same path on Windows, macOS, and Linux — OpenCode does not use %APPDATA%
Project./.opencode/Pass --project to target the current project instead
# Project-level install (writes to ./.opencode/ in the current directory)
jacky opencode install --project
 
# Skip installing the reaction plugin (MCP tools only)
jacky opencode install --no-plugin
Note

The config directory can be overridden with the OPENCODE_CONFIG_DIR or XDG_CONFIG_HOME environment variables, matching OpenCode's own resolution order.


CLI Commands

jacky opencode install [--project] [--no-plugin]

One-command setup. Performs all of the following automatically:

StepWhat it does
Enable serversActivates the WebSocket and MCP servers in Jacky's configuration
Grant permissionsEnables the necessary permissions for external control
Write MCP entryAdds a mcp.jacky remote entry (with auth headers) to OpenCode's config
Write instructionsCreates jacky.md with a managed block and references it in instructions
Install pluginCopies the reaction plugin into OpenCode's plugins/ directory (skip with --no-plugin)

jacky opencode uninstall [--project]

Removes everything: the mcp.jacky entry, the instructions reference and file (or just the managed block, if you added your own content), and the plugin file.

jacky opencode --doctor [--project]

Health check that verifies:

  • OpenCode's config file exists and the mcp.jacky entry is present and correct (including the auth header)
  • The managed instructions file exists and is referenced
  • The reaction plugin file is installed
  • Jacky desktop app is running
  • jacky CLI is on your PATH
  • Configuration has the necessary servers enabled and permissions granted

Full CLI Command Reference


Troubleshooting

Jacky doesn't react to OpenCode events

  1. Run jacky opencode --doctor — check for any issues
  2. Verify Jacky desktop app is running: jacky status
  3. Restart Jacky after running jacky opencode install
  4. Confirm the plugin file exists under your OpenCode config's plugins/ directory

OpenCode reports "jacky needs authentication"

The MCP token in opencode.json no longer matches the one Jacky's server expects — most likely because the token was regenerated in Settings. Run jacky opencode install again to sync it.

MCP tools not available in OpenCode

  1. Run jacky opencode --doctor
  2. Verify the mcp.jacky entry is present in your opencode.json and has an Authorization header
  3. Restart Jacky after enabling the MCP server
  4. Verify the MCP server is running on the expected port (http://127.0.0.1:9877/mcp)

Jacky seems quiet during rapid activity

This is likely throttling — Jacky intentionally limits reaction frequency to avoid spam. Throttle state is persisted locally (separately from Claude Code's) and resets automatically over time. You can delete OpenCode's throttle file to reset all cooldowns immediately.

Wrong config directory

OpenCode always uses ~/.config/opencode/ — never %APPDATA%, even on Windows. If you manually edited a config file elsewhere, OpenCode won't read it; run jacky opencode --doctor to confirm which file Jacky is managing.