Best Practices for Using OpenWork: A Complete Guide to Agent-Centric Development
Use isolated dev profiles with pnpm dev:worktree, centralize MCP configuration in opencode.json, and enforce TypeScript strictness per AGENTS.md to build reliable AI workflows on the OpenWork platform.
OpenWork is an open-source, agent-centric platform developed by different-ai that enables teams to run AI workflows locally or in the cloud. Understanding its monorepo structure and architectural patterns ensures you maximize security, reproducibility, and collaboration when building skills and plugins.
Understanding the OpenWork Architecture
Before applying best practices, you must understand how the three core components interact: the Desktop App, OpenWork Den, and the Model-Capability Provider (MCP).
Desktop App and CDP Communication
The Desktop App is an Electron-based UI located in apps/desktop that runs workflows and stores local credentials. When you run pnpm dev, the app launches and binds to a free Chrome DevTools Protocol (CDP) port, printing a banner like cdp=http://127.0.0.1:9223. The client reads the OPENWORK_DEV_PROFILE environment variable to locate its profile directory, where JWT tokens from Den are cached.
OpenWork Den as the Control Plane
OpenWork Den serves as the backend control plane that manages organizations, model-provider quotas, and team permissions. It authenticates users via OAuth or native keychain and issues JWTs that the Desktop App uses for subsequent requests.
MCP and Agent Integration
The Model-Capability Provider (MCP) is a thin remote layer exposing OpenWork skills to any AI agent (Claude, Codex, Cursor). According to the source code in opencode.json, you register the MCP URL https://api.openworklabs.com/mcp/agent to make capabilities available via search_capabilities and execute_capability commands.
Local Development Best Practices
Isolating your development environment prevents credential clashes and CDP port conflicts when running multiple instances.
Use Worktree-Based Development
Always use pnpm dev:worktree when working on parallel branches. This command automatically sets OPENWORK_DEV_PROFILE=auto, creating an isolated profile directory that prevents state leakage between features.
# Create a new worktree for the feature branch
git worktree add ../openwork-feature feature-branch
cd ../openwork-feature
# Start the app with an auto-generated profile
OPENWORK_DEV_PROFILE=auto pnpm dev:worktree
Configure Mock Keychain for CI and Testing
For deterministic tests and CI pipelines, set OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1 in your environment or in warden.toml. This flag bypasses native OS keychain dialogs, making tests fast and non-interactive. Use the real keychain (0) only when manually debugging authentication flows.
Strict Package Management with pnpm
The monorepo defined in pnpm-workspace.yaml relies on pnpm for workspace hoisting and linking. Never invoke npm or yarn commands inside the repository, as this breaks lockfile consistency and workspace resolution.
Configuring the Model-Capability Provider
Centralizing MCP configuration prevents URL drift and simplifies updates across teams.
Single-Source MCP Registration
Register the OpenWork MCP exactly once per environment in opencode.json. Avoid embedding the MCP URL in multiple configuration files or environment variables.
{
"mcp": {
"openwork": {
"type": "remote",
"enabled": true,
"url": "https://api.openworklabs.com/mcp/agent",
"oauth": {}
}
}
}
Invoking Skills from External Agents
Once registered, agents can discover and execute OpenWork skills without knowing the underlying implementation details.
# Search for available capabilities
search_capabilities
# Execute a specific skill
execute_capability summarize-repo --path /path/to/project
Code Quality and Testing Standards
Maintaining strict type safety and comprehensive testing ensures skills run reliably in the Electron process or remotely via Den.
Follow AGENTS.md TypeScript Guidelines
The AGENTS.md file in the repository root defines mandatory coding conventions. Avoid any types, unnecessary type casts, or as assertions unless absolutely required. This policy prevents runtime type errors in shared skills that execute across different environments.
End-to-End Testing with Testkit
Write verification specs in evals/specs/**/*.test.ts using @openwork/testkit. Run these evaluations with the run-tests skill before opening pull requests to satisfy the "Agent-first verification" process.
pnpm exec openwork test evals/specs/auth-flow.test.ts
UI Consistency with shadcn/ui
Build interface components using the shadcn/ui Base UI kit located in @/components and style them with TailwindCSS. This ensures visual uniformity across the Desktop App and reduces duplication of common patterns.
Managing Teams and Permissions
Proper governance prevents accidental over-provisioning and enforces least-privilege access.
Den Governance and Quotas
Use the OpenWork Den UI to assign model-provider quotas and team permissions before sharing workflows. Define organizations and assign skills to specific teams rather than individual users when possible.
Publishing Skills to the Marketplace
When publishing new skills via the CLI, specify the organization and team to ensure proper access control.
pnpm workspace @openwork/skill-my-skill publish \
--org my-org \
--team dev-team
Summary
- Isolate development environments using
pnpm dev:worktreewithOPENWORK_DEV_PROFILE=autoto avoid credential conflicts and CDP port collisions. - Centralize MCP configuration in
opencode.jsonand register the URLhttps://api.openworklabs.com/mcp/agentonce per environment. - Enforce type safety by following the strict TypeScript guidelines in
AGENTS.mdand avoidinganytypes in skill code. - Use mock keychain (
OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1) for CI and testing, but real keychain for manual auth debugging. - Write end-to-end tests in
evals/specs/**/*.test.tsand run them with@openwork/testkitbefore submitting pull requests. - Manage permissions through the Den UI to enforce quotas and least-privilege access across teams.
Frequently Asked Questions
How do I run multiple OpenWork instances without port conflicts?
Use the pnpm dev:worktree command, which automatically generates isolated profiles via OPENWORK_DEV_PROFILE=auto. This creates separate directories for credentials and finds available CDP ports dynamically, preventing the cdp=http://127.0.0.1:9223 binding collisions that occur when running standard pnpm dev in multiple terminals.
Where should I store the MCP URL configuration?
Store the MCP URL exclusively in opencode.json at the repository root. The configuration should point to https://api.openworklabs.com/mcp/agent with type: "remote" and enabled: true. Centralizing this in opencode.json allows agents like Claude and Codex to discover capabilities via standard MCP commands without requiring additional environment variables.
What is the difference between local and remote skill execution?
Local execution runs skills within the Electron main process on the Desktop App, accessing local credentials stored in the profile directory. Remote execution routes requests through OpenWork Den, which handles authentication via JWT and manages model-provider quotas. Skills should be designed to handle both modes, as the execution context depends on the workflow configuration and network availability.
How do I disable the native keychain for automated testing?
Set the environment variable OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1 or define it in warden.toml. This replaces OS-level keychain access with a mock implementation, allowing tests to run non-interactively in CI pipelines. Only disable this flag (set to 0) when manually testing OAuth flows that require real credential storage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →