# How OpenWork MCP Gateway search_capabilities and execute_capability Work

> Explore how OpenWork MCP gateway's search_capabilities and execute_capability tools empower agents to query skills and invoke actions via the /mcp/agent endpoint using JWT tokens.

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

---

**The OpenWork MCP gateway exposes two JSON-RPC tools—`search_capabilities` for querying the capability catalog and `execute_capability` for invoking specific skills—that agents access via the `/mcp/agent` endpoint using short-lived JWT tokens.**

The different-ai/openwork repository implements a Model Control Plane (MCP) gateway in the `ee/apps/den-api` server, enabling AI agents to programmatically discover and execute capabilities. The gateway's `search_capabilities` and `execute_capability` tools provide authenticated, permission-scoped access to skills, apps, and integrations stored in the underlying database, with request validation handled by Zod schemas defined in the shared types package.

## Understanding the OpenWork MCP Gateway Architecture

The MCP gateway operates as a stateless JSON-RPC server that brokers interactions between AI agents and the OpenWork capability ecosystem. Agents interact with two primary tools exposed through the `/mcp/agent` endpoint:

- **search_capabilities** – Queries the capability catalog using full-text search with optional filters for type (e.g., `"skills"`, `"apps"`) and result limits.
- **execute_capability** – Invokes a specific capability by its `scriptPath` identifier, executing the underlying implementation with provided arguments.

Both tools require a valid MCP token (JWT) in the `Authorization: Bearer` header. The gateway validates the token, checks organization-level permissions, and routes requests to the appropriate service layer in `ee/apps/den-api`.

## How search_capabilities Works

### Request Flow and Validation

When an agent calls `search_capabilities`, the gateway first validates the request payload against the Zod schema defined in [`packages/types/src/den/mcp-connection-action.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/mcp-connection-action.ts). The schema enforces parameters including `query` (string), `limit` (number, optional), and `type` (string, optional).

The validated request flows to `CapabilityService.search` in [`ee/apps/den-api/src/services/capability.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability.ts). This service constructs a full-text database query against the `Capability` table, applying filters that respect the calling identity's organizational access grants. The service returns paginated results containing metadata fields: `id`, `name`, `description`, and `scriptPath`.

### Implementation Example

```typescript
// Agent-side invocation pattern from evals/specs/workflows.e2e.test.ts
const searchResult = await callAgentTool(
  den.ref.apiUrl,
  adminMcpToken,
  "search_capabilities",
  { 
    query: "list workers", 
    limit: 20, 
    type: "skills" 
  }
);

const matches = searchResult.payload.matches;
// Returns: [{ id: "...", name: "List Workers", scriptPath: "openwork-cloud/skills/list-workers", ... }]

```

The gateway returns matches as an array of capability descriptors, allowing agents to programmatically select appropriate tools for subsequent execution.

## How execute_capability Works

### Execution Flow

The `execute_capability` tool transforms a capability identifier into an actual function invocation. The gateway accepts a `scriptPath` string (obtained from `search_capabilities`) and an `input` object containing capability-specific arguments.

The route handler in [`ee/apps/den-api/src/routes/mcp.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/routes/mcp.ts) delegates to the execution layer. The system first validates that the caller's organization has permission to access the requested `scriptPath`, then loads the capability implementation. For concrete execution logic, the gateway utilizes [`ee/apps/den-api/src/services/capability-executor.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability-executor.ts), which resolves the script reference and forwards the invocation to the underlying runtime.

### Security and Error Handling

The gateway enforces strict access control before execution. If the `scriptPath` does not exist or the caller lacks permission, the gateway returns a JSON-RPC error object with appropriate error codes. Successful invocations stream the execution result back to the agent as the JSON-RPC response payload.

```typescript
// Executing a discovered capability
const execResult = await callAgentTool(
  den.ref.apiUrl,
  adminMcpToken,
  "execute_capability",
  {
    scriptPath: "openwork-cloud/skills/list-workers",
    input: { filter: "active", maxResults: 100 }
  }
);

console.log(execResult.payload); // Execution output from the capability

```

## End-to-End Usage Pattern

Agents typically chain these tools to discover and act upon capabilities dynamically. The following pattern from [`evals/runner/journeys/mcp.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/journeys/mcp.ts) demonstrates the complete workflow:

```typescript
// 1. Discover capabilities
const skillSearch = await callAgentTool(
  den.ref.apiUrl,
  adminMcpToken,
  "search_capabilities",
  { query: "create skill", limit: 5 }
);

const targetSkill = skillSearch.payload.matches.find(
  m => m.name.includes("create_skill")
);

// 2. Execute selected capability
if (targetSkill) {
  const createResult = await callAgentTool(
    den.ref.apiUrl,
    adminMcpToken,
    "execute_capability",
    { 
      scriptPath: targetSkill.scriptPath, 
      input: { name: "data-processor", description: "Process CSV files" } 
    }
  );
  return createResult.payload;
}

```

This pattern enables agents to operate within the OpenWork ecosystem without hardcoding capability endpoints, adapting dynamically to available tools.

## Key Source Files and Architecture

The MCP gateway implementation spans several critical files in the different-ai/openwork repository:

- **[`ee/apps/den-api/src/routes/mcp.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/routes/mcp.ts)** – Gateway entry point that registers JSON-RPC tools and dispatches `search_capabilities` and `execute_capability` calls.
- **[`packages/types/src/den/mcp-connection-action.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/mcp-connection-action.ts)** – Zod schema definitions for request validation, including the `retry: "search_capabilities"` type discriminator.
- **[`ee/apps/den-api/src/services/capability.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability.ts)** – Service layer implementing `CapabilityService.search` for catalog queries with permission filtering.
- **[`ee/apps/den-api/src/services/capability-executor.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability-executor.ts)** – Execution engine that resolves `scriptPath` references and invokes capability implementations.
- **[`evals/specs/workflows.e2e.test.ts`](https://github.com/different-ai/openwork/blob/main/evals/specs/workflows.e2e.test.ts)** – End-to-end test specifications demonstrating tool invocation patterns.
- **[`evals/runner/journeys/mcp.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/journeys/mcp.ts)** – Journey runner utilities for orchestrating tool calls in test scenarios.

## Summary

- **search_capabilities** enables agents to query the OpenWork capability catalog with full-text search, returning metadata including `scriptPath` identifiers scoped to the caller's organizational permissions.
- **execute_capability** invokes specific capabilities by `scriptPath`, executing the underlying implementation after validating access rights and streaming results back to the agent.
- Both tools are exposed through the stateless `/mcp/agent` JSON-RPC endpoint in the `den-api` server, utilizing Zod schemas for input validation.
- The gateway delegates search operations to `CapabilityService` in [`ee/apps/den-api/src/services/capability.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability.ts) and execution to the service layer in [`ee/apps/den-api/src/services/capability-executor.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability-executor.ts).

## Frequently Asked Questions

### What is the difference between search_capabilities and execute_capability in OpenWork?

**search_capabilities** is a read-only catalog query tool that returns metadata about available capabilities, while **execute_capability** is an action tool that invokes the actual implementation of a specific capability using its `scriptPath` identifier. Agents use search to discover what actions they can perform, then execute to run them.

### How does the OpenWork MCP gateway authenticate tool requests?

The gateway requires a short-lived **MCP token** (JWT) passed in the `Authorization: Bearer` header. According to the source code in `ee/apps/den-api`, the gateway validates this token and extracts organizational claims to enforce permission checks before processing `search_capabilities` or `execute_capability` calls.

### What data structure does search_capabilities return?

The tool returns a JSON-RPC payload containing a `matches` array, where each element includes fields such as `id`, `name`, `description`, and `scriptPath`. These descriptors originate from the `Capability` table via `CapabilityService.search` and are filtered based on the caller's organizational access rights.

### Where is the capability execution logic implemented?

The execution logic resides in [`ee/apps/den-api/src/services/capability-executor.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/services/capability-executor.ts), which is called by the gateway route handler after permission validation. This service resolves the `scriptPath` provided in the `execute_capability` request and forwards the invocation to the appropriate runtime environment or remote integration.