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

> Understand the core distinction between OpenWork skills and MCP tools. Discover how OpenWork skills execute locally while MCP tools operate as remote JSON-RPC services.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: comparison
- Published: 2026-08-06

---

**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/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/dev/.warden/skills/greet-user.md):

```markdown
---
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`](https://github.com/different-ai/openwork/blob/main/plugin.json)) for remote services:

```json
{
  "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](https://github.com/different-ai/openwork/blob/dev/packages/enterprise-mcp-client/README.md)** 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:

```typescript
// 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`](https://github.com/different-ai/openwork/blob/main/desktop-ipc.ts).
- **MCP tools/plugins** are remote JSON-RPC services defined in [`plugin.json`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/plugin.json) manifest. The **[enterprise-mcp-mock-server](https://github.com/different-ai/openwork/blob/dev/packages/enterprise-mcp-mock-server/README.md)** 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.