Sugar integrates with OpenCode to provide MCP-based communication between Sugar's autonomous task queue and OpenCode sessions.
The OpenCode integration enables:
- MCP servers - Task management and memory access directly in OpenCode
- Memory injection - Automatically inject relevant context into OpenCode sessions
- Learning capture - Capture learnings from OpenCode sessions back to Sugar memory
# One-command setup - configures OpenCode automatically
sugar opencode setup
# Restart OpenCode to load the new MCP servers
# Verify setup
sugar opencode statusThe setup command:
- Finds your OpenCode config file (
~/.config/opencode/opencode.jsonor.opencode/opencode.json) - Adds
sugar-tasksandsugar-memoryMCP servers - Preserves your existing configuration
After setup, OpenCode will have access to Sugar's tools:
sugar_add_task- Add tasks to the queuesugar_list_tasks- View queued taskssugar_remember- Store memoriessugar_recall- Search memories
export OPENCODE_SERVER_URL="http://localhost:4096" # Default
export OPENCODE_API_KEY="your-api-key" # Optional
export OPENCODE_TIMEOUT="30.0" # Seconds
export SUGAR_OPENCODE_ENABLED="true" # Enable/disableAdd to .sugar/config.yaml:
integrations:
opencode:
enabled: true
server_url: "http://localhost:4096"
api_key: null # Optional
timeout: 30.0
# Auto-injection settings
auto_inject: true
inject_memory_types:
- decision
- preference
- error_pattern
memory_limit: 5
# Notification settings
notify_on_completion: true
notify_on_failure: true
# Sync interval for event polling
sync_interval: 5.0Automatically configure OpenCode to use Sugar's MCP servers.
sugar opencode setup [options]
Options:
--yes, -y Skip confirmation prompts
--dry-run Show what would be changed without modifying files
--config PATH Path to OpenCode config file (auto-detected if not specified)
--no-memory Don't add the memory MCP server
--no-tasks Don't add the tasks MCP serverExamples:
# Interactive setup (recommended)
sugar opencode setup
# Non-interactive for scripts/CI
sugar opencode setup --yes
# Preview changes without applying
sugar opencode setup --dry-run
# Only add task management (no memory)
sugar opencode setup --no-memoryThe command searches for OpenCode config in this order:
OPENCODE_CONFIGenvironment variableOPENCODE_CONFIG_DIRenvironment variable.opencode/opencode.json(project-local)~/.config/opencode/opencode.json(user config)
Check OpenCode integration status and configuration.
sugar opencode statusOutput:
OpenCode Integration Status
Enabled: Yes
aiohttp: Installed
Server URL: http://localhost:4096
Auto-inject: Yes
Test connection to the OpenCode HTTP server (if enabled).
sugar opencode testSend a notification to the OpenCode TUI.
sugar opencode notify "message" [options]
Options:
--level LEVEL Notification level: info, success, warning, error (default: info)Examples:
# Info notification
sugar opencode notify "Build started"
# Success notification
sugar opencode notify "All tests passed" --level success
# Error notification
sugar opencode notify "Deployment failed" --level errorWhen Sugar runs tasks autonomously, it automatically notifies OpenCode:
| Event | Notification |
|---|---|
| Task started | Info: "Task Started: {id}" |
| Task completed | Success: "Task Completed: {id}" with execution time |
| Task failed | Error: "Task Failed: {id}" with error message |
These notifications appear in the OpenCode TUI, keeping you informed of Sugar's progress.
# In .sugar/config.yaml
integrations:
opencode:
notify_on_completion: false
notify_on_failure: falseSugar can inject relevant memories into OpenCode sessions to provide context.
- When an OpenCode session starts, Sugar searches for relevant memories
- Memories matching configured types are formatted as markdown
- Context is injected as a system message in the session
By default, Sugar injects:
- Decisions - Architecture and implementation choices
- Preferences - Coding style and conventions
- Error patterns - Known bugs and fixes
## Sugar Context (from memory)
### Previous Decisions
- Using PostgreSQL for main database
- JWT with RS256 for authentication tokens
### Coding Preferences
- Always use async/await, never callbacks
- Prefer early returns over nested if statements
### Known Error Patterns
- Login loop caused by missing return statement in auth handlerintegrations:
opencode:
auto_inject: true
inject_memory_types:
- decision
- preference
- error_pattern
- research # Add research notes
memory_limit: 10 # More memories per typeSugar can capture learnings from OpenCode sessions and store them as memories.
The LearningCapture class detects:
- Decisions made during coding ("I decided to...", "Let's use...")
- Errors encountered and their fixes
- Preferences expressed ("Always...", "Never...", "Prefer...")
When enabled, Sugar monitors OpenCode sessions and extracts learnings:
from sugar.integrations.opencode import LearningCapture, OpenCodeConfig
config = OpenCodeConfig.from_env()
capture = LearningCapture(config)
# Process a session message
learnings = await capture.extract_learnings(message_content)
for learning in learnings:
print(f"Detected {learning.type}: {learning.content}")The main client for communicating with OpenCode.
from sugar.integrations.opencode import OpenCodeClient, OpenCodeConfig
config = OpenCodeConfig(
server_url="http://localhost:4096",
timeout=30.0,
)
async with OpenCodeClient(config) as client:
# Check connectivity
is_healthy = await client.health_check()
# List sessions
sessions = await client.list_sessions()
# Inject context
await client.inject_context(
session_id="abc123",
context="Remember to use async/await",
role="system",
)
# Send notification
from sugar.integrations.opencode import NotificationLevel
await client.notify(
title="Build Complete",
message="All 47 tests passed",
level=NotificationLevel.SUCCESS,
)Handles automatic memory injection into sessions.
from sugar.integrations.opencode import ContextInjector, OpenCodeConfig
config = OpenCodeConfig.from_env()
injector = ContextInjector(config)
# Inject relevant memories into a session
success = await injector.inject_for_session(session_id="abc123")For simple one-off operations:
from sugar.integrations.opencode import (
notify_task_started,
notify_task_completed,
notify_task_failed,
)
# Fire-and-forget notifications (non-blocking)
notify_task_started("task-123", "Fix login bug")
notify_task_completed("task-123", "Fix login bug", execution_time=45.2)
notify_task_failed("task-123", "Fix login bug", "Test assertion failed")Install the OpenCode dependencies:
pipx inject sugarai aiohttp
# Or
pip install 'sugarai[opencode]'OpenCode server isn't running or is on a different port:
# Check OpenCode is running
curl http://localhost:4096/health
# Check configured URL
sugar opencode statusThe client must be used as an async context manager:
# Wrong
client = OpenCodeClient()
await client.health_check() # RuntimeError!
# Correct
async with OpenCodeClient() as client:
await client.health_check()- Check OpenCode TUI is running and visible
- Verify connectivity:
sugar opencode status - Test with:
sugar opencode test - Check notification settings in config
- Ensure memories exist:
sugar memories - Check injection is enabled in config
- Verify memory types match configured
inject_memory_types - Check OpenCode session is active
┌─────────────┐ HTTP/SSE ┌─────────────┐
│ Sugar │◄─────────────────►│ OpenCode │
│ │ │ Server │
│ ┌─────────┐ │ │ │
│ │ Notifier│─┼──notifications───►│ ┌───────┐ │
│ └─────────┘ │ │ │ TUI │ │
│ │ │ └───────┘ │
│ ┌─────────┐ │ │ │
│ │Injector │─┼──context─────────►│ ┌───────┐ │
│ └─────────┘ │ │ │Session│ │
│ │ │ └───────┘ │
│ ┌─────────┐ │ │ │
│ │ Capture │◄┼──events───────────│ │
│ └─────────┘ │ │ │
└─────────────┘ └─────────────┘
| Feature | Claude Code | OpenCode |
|---|---|---|
| Integration method | MCP Server | HTTP API |
| Memory access | Full (MCP tools) | Injection-based |
| Notifications | N/A | TUI notifications |
| Event subscription | N/A | SSE streaming |
| Session management | Automatic | Manual/API |
Both integrations can be used simultaneously - Sugar detects which clients are available.