OpenWork Skills vs MCP Tools: Understanding the Distinction in different-ai/openwork

OpenWork skills are self-contained code artifacts that execute inside the desktop runtime, while MCP tools and plugins are remote JSON-RPC services accessed over HTTP.

The different-ai/openwork repository implements a dual architecture for extending AI agent capabilities. Understanding the distinction between OpenWork skills and MCP tools/plugins is essential for developers choosing between local automation and remote service integration. Both appear to agents as searchable capabilities, but they differ fundamentally in execution context, discovery mechanisms, and sharing models.

Core Architectural Differences

What Are OpenWork Skills?

An OpenWork skill is a self-contained piece of code—typically a Markdown file with front-matter—that implements a single, reusable capability. Skills live in the repository under the skills/ directory (e.g., dev/.warden/skills/) and execute inside the OpenWork desktop runtime. The agent sends requests to the desktop IPC layer, which runs the skill’s JavaScript or TypeScript code directly via the DesktopSkillExecutor.

Skills can be local (user-specific) or grant-native (shared across organizations without a separate MCP connection). The skill loader parses metadata through readLocalSkill, defined in [desktop-ipc.ts](https://github.com/different-ai/openwork/blob/dev/packages/types/src/desktop-ipc.ts#L179), registering each skill in the desktop catalog for discovery via search_capabilities.

What Are MCP Tools and Plugins?

An MCP tool is a service-level capability exposed over the Model-Control-Protocol (MCP)—a remote JSON-RPC endpoint accessed via HTTP/HTTPS. An MCP plugin bundles one or more tools together with optional UI components, OAuth handling, and marketplace metadata. These execute outside the desktop on remote servers (cloud-hosted MCPs, third-party SaaS, or mock servers).

The enterprise-mcp-client discovers tool catalogs through discoverConnectionRequirements and publishes them to the agent’s capability store. Unlike skills, MCP tools require a managed connection (URL and authentication) configured through OpenWork’s "MCP connections" UI.

Execution Context and Runtime

The execution path determines performance characteristics and security boundaries:

  • Skills → DesktopSkillExecutor → JavaScript runs in-process within the desktop sandbox
  • MCP Tools → MCPServer (JSON-RPC) → Remote HTTP request/response cycle

This distinction means skills have direct access to the local file system and OS APIs, while MCP tools operate over the network with controlled access boundaries.

Discovery and Registration Mechanisms

Skills and MCP tools follow different registration workflows:

Skills are declared by SKILL.md files containing metadata (name, description, inputs/outputs). The desktop parses these files and registers them locally, making them instantly searchable without network configuration.

MCP tools are described in a plugin manifest (plugin.json or marketplace entries) listing JSON-RPC schemas. When an admin adds an MCP connection, the enterprise client discovers the tool catalog and exposes it to agents. This process involves network handshakes and authentication validation before tools appear in search_capabilities.

Sharing Models and Access Control

The sharing architecture differs significantly between the two approaches:

  • Grant-native skills are versioned with the repository and can be shared across organizations without maintaining separate connections. Any user with the skill file locally can execute it immediately.
  • MCP tools are tied to MCP connections protected by OAuth or API keys. Access is controlled centrally by the MCP server and OpenWork’s connection management UI. While a plugin may expose tools to many users, the underlying connection credentials are managed separately from the tool definition.

Code Examples

Defining a Local Skill

Create a Markdown file in dev/.warden/skills/greet-user.md:

---
name: /greet-user
description: Returns a friendly greeting for the given name.
inputs:
  - name: userName
    type: string
outputs:
  - name: greeting
    type: string
---

export default async function run({ userName }) {
  return { greeting: `Hello, ${userName}! 👋` };
}

The desktop loads this via readLocalSkill and makes it searchable through search_capabilities without requiring network configuration.

Registering an MCP Tool

Define a plugin manifest (plugin.json) for remote services:

{
  "name": "Slack Integration",
  "version": "1.0.0",
  "tools": [
    {
      "name": "/slack/postMessage",
      "description": "Posts a message to a Slack channel.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "channel": { "type": "string" },
          "text":    { "type": "string" }
        },
        "required": ["channel", "text"]
      },
      "outputSchema": { "type": "object", "properties": { "ok": { "type": "boolean" } } }
    }
  ],
  "oauth": { "type": "authorization_code", "scopes": ["chat:write"] }
}

When an admin adds an MCP connection, the enterprise-mcp-client discovers the tool catalog and publishes /slack/postMessage to the agent’s capability store.

Agent Usage Patterns

Agents interact with both capability types through a unified API, but specify the execution context via the kind parameter:

// 1️⃣ Use a local skill
const greet = await callTool(agentToken, "execute_capability", {
  kind: "skill",
  name: "/greet-user",
  input: { userName: "Alex" }
});
console.log(greet.greeting);   // → "Hello, Alex! 👋"

// 2️⃣ Use a remote MCP tool
const posted = await callTool(agentToken, "execute_capability", {
  kind: "tool",
  name: "/slack/postMessage",
  input: { channel: "#general", text: "Hello from OpenWork!" }
});
console.log(posted.ok);        // → true (if the remote MCP succeeded)

Both calls route through search_capabilities and execute_capability, but the desktop differentiates between local skill execution and remote MCP JSON-RPC based on the kind field.

When to Use Each Approach

Choose OpenWork skills for:

  • Simple data transformations and UI helpers requiring direct file system access
  • Rapid prototyping that must run instantly without network dependencies
  • Operations needing sandboxed local process execution

Choose MCP tools/plugins for:

  • Enterprise services (Microsoft 365, ServiceNow, Slack) requiring stable, authenticated remote APIs
  • Heavy-weight operations you don’t want to ship with the desktop (large language model inference, database queries)
  • Marketplace-distributed capabilities requiring centralized access control

Summary

  • OpenWork skills are local code artifacts stored in the skills/ directory, executed in-process via DesktopSkillExecutor, and discovered through readLocalSkill in desktop-ipc.ts.
  • MCP tools/plugins are remote JSON-RPC services defined in plugin.json manifests, executed over HTTP via MCPServer, and discovered through discoverConnectionRequirements in the enterprise-mcp-client.
  • Skills excel at local automation with instant execution; MCP tools enable secure, shared access to enterprise services.
  • Both capability types appear in search_capabilities, but differ in authentication, sharing models, and runtime isolation.

Frequently Asked Questions

Can I convert a local skill into an MCP tool?

Yes, but it requires architectural migration. You would move the logic from a local JavaScript/TypeScript file in skills/ to a remote MCP server implementation, then expose it through a plugin.json manifest. The enterprise-mcp-mock-server provides a reference implementation for testing this transition.

How does authentication differ between skills and MCP tools?

Skills rely on the desktop’s local security sandbox and inherit permissions from the OpenWork runtime process. MCP tools use connection-level authentication managed through the "MCP connections" UI, supporting OAuth 2.0, API keys, or custom schemes defined in the plugin manifest. Remote authentication is handled entirely outside the desktop process.

Which approach offers better performance for high-frequency operations?

OpenWork skills generally offer lower latency for high-frequency operations because they execute in-process without network overhead. MCP tools incur HTTP request/response latency but can leverage remote compute resources for intensive operations that would otherwise block the desktop runtime.

Can agents distinguish between skill and MCP tool execution?

Agents specify the execution context explicitly through the kind parameter ("skill" or "tool") when calling execute_capability. While both appear in the unified search_capabilities catalog, the desktop routes skill calls through DesktopSkillExecutor and tool calls through the enterprise-mcp-client JSON-RPC layer, ensuring appropriate isolation and error handling for each execution model.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →