# How Claude Code Tools Are Mapped to Droid, Cursor, and Other Platform Formats

> Discover how the Compound Engineering Plugin maps Claude Code tools to Droid, Cursor, and other formats. Learn about tool name maps and content transformers for seamless integration.

- Repository: [Every/compound-engineering-plugin](https://github.com/everyinc/compound-engineering-plugin)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The Compound Engineering Plugin converts Claude Code plugins into Droid, Cursor, Codex, and OpenCode formats using explicit tool-name maps and content transformers that rewrite commands, agents, and references for each target platform.**

The `EveryInc/compound-engineering-plugin` repository provides a CLI tool that bridges Claude Code's plugin ecosystem with other AI engineering platforms. When you run `bunx @every-env/compound-plugin install --to <target>`, the tool applies specific mapping logic defined in TypeScript converter files to translate tool invocations, task calls, and agent references into platform-specific syntax.

## Factory Droid Tool Mapping

Factory Droid requires explicit tool name translation because it uses PascalCase tool names and maintains a strict whitelist of valid capabilities.

### The CLAUDE_TO_DROID_TOOLS Map

In [`src/converters/claude-to-droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-droid.ts), the `CLAUDE_TO_DROID_TOOLS` record defines the direct mapping from Claude's lowercase tool names to Droid's PascalCase equivalents:

```typescript
const CLAUDE_TO_DROID_TOOLS: Record<string, string> = {
  read: "Read",
  write: "Create",
  edit: "Edit",
  multiedit: "Edit",
  bash: "Execute",
  grep: "Grep",
  glob: "Glob",
  list: "LS",
  ls: "LS",
  webfetch: "FetchUrl",
  websearch: "WebSearch",
  task: "Task",
  todowrite: "TodoWrite",
  todoread: "TodoWrite",
  question: "AskUser",
};

```

### Validating Tools with VALID_DROID_TOOLS

Droid only accepts tools defined in the `VALID_DROID_TOOLS` Set. The converter filters mapped tools against this whitelist before emitting them in the final bundle:

```typescript
const VALID_DROID_TOOLS = new Set([
  "Read", "LS", "Grep", "Glob", "Create", "Edit", "ApplyPatch",
  "Execute", "WebSearch", "FetchUrl", "TodoWrite", "Task", "AskUser",
]);

```

### How mapAgentTools Applies the Mapping

The `mapAgentTools` function scans an agent's name, description, and body for any mentioned Claude tools (case-insensitive), maps them to Droid equivalents, and returns the filtered, sorted list:

```typescript
function mapAgentTools(agent: ClaudeAgent): string[] | undefined {
  const bodyLower = `${agent.name} ${agent.description ?? ""} ${agent.body}`.toLowerCase();
  const mentionedTools = new Set<string>();
  for (const [claudeTool, droidTool] of Object.entries(CLAUDE_TO_DROID_TOOLS)) {
    if (bodyLower.includes(claudeTool)) {
      mentionedTools.add(droidTool);
    }
  }
  if (mentionedTools.size === 0) return undefined;
  return [...mentionedTools].filter(t => VALID_DROID_TOOLS.has(t)).sort();
}

```

The resulting array is written into the agent's front-matter as `tools: [...]` by the `convertAgent` function.

## Cursor Content Transformation

Unlike Droid, Cursor does not use a fixed tool registry. Instead, it requires semantic rewriting of content to match Cursor's rule syntax and command structure.

### Rewriting Task Calls and Slash Commands

In [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts), the `transformContentForCursor` function uses regex patterns to rewrite Claude-specific syntax:

```typescript
// Task calls become "Use the <skill> skill to: <args>"
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm;
result = result.replace(taskPattern, (_,
    prefix, agentName, args) => {
  const skillName = normalizeName(agentName);
  return `${prefix}Use the ${skillName} skill to: ${args.trim()}`;
});

// Slash commands flatten namespace (e.g., /workflows:plan → /plan)
const slashCommandPattern = /(?<![:\w])\/([a-z][a-z0-9_:-]*?)(?=[\s,."')\]}`]|$)/gi;

```

### Path and Agent Reference Updates

The transformer also handles path rewriting and agent references:

- **Path rewrite**: `~/.claude/` directories become `~/.cursor/`
- **Agent references**: `@agent-X` patterns become `the <agent> rule`

The transformed content is then written to `.cursor/rules/<name>.md` by the Cursor target writer.

## Codex and OpenCode Canonical Mapping

Codex and OpenCode share a canonical tool map but apply different content transformations based on their respective syntax requirements.

### The Shared TOOL_MAP

Both converters import or define the same `TOOL_MAP` in [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts) (and referenced in [`src/converters/claude-to-codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-codex.ts)):

```typescript
const TOOL_MAP: Record<string, string> = {
  bash: "bash",
  read: "read",
  write: "write",
  edit: "edit",
  grep: "grep",
  glob: "glob",
  list: "list",
  webfetch: "webfetch",
  skill: "skill",
  patch: "patch",
  task: "task",
  question: "question",
  todowrite: "todowrite",
  todoread: "todoread",
};

```

The `parseToolSpec` function normalizes Claude tool strings (with optional path patterns) into canonical names using this map.

### Codex-Specific Content Transformations

In [`src/converters/claude-to-codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-codex.ts), the `transformContentForCodex` function applies platform-specific syntax:

```typescript
// Task calls become "Use the $skill skill to: ..."
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm;
result = result.replace(taskPattern, (_,
    prefix, agentName, args) => {
  const skillName = normalizeName(agentName);
  return `${prefix}Use the $${skillName} skill to: ${args.trim()}`;
});

// Slash commands become /prompts:<normalized>
const slashCommandPattern = /(?<![:\w])\/([a-z][a-z0-9_:-]*?)(?=[\s,."')\]}`]|$)/gi;
result = result.replace(slashCommandPattern, (_, commandName) => {
  const normalizedName = normalizeName(commandName);
  return `/prompts:${normalizedName}`;
});

```

Agent references (`@agent-X`) are transformed into `$skill skill` syntax.

### OpenCode Permission Generation

OpenCode uses the same `TOOL_MAP` and `parseToolSpec` logic, but instead of generating skill files, it builds a permission matrix for the [`opencode.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/opencode.json) configuration.

When a Claude command specifies `allowedTools`, each tool string is parsed to extract the canonical tool name and optional path pattern. The `applyPermissions` function then generates the appropriate permission entries:

- Tools without patterns are enabled globally
- Tools with patterns (e.g., `write(/tmp/*)`) are restricted to those specific paths

This configuration is written to [`opencode.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/opencode.json) under the `"permission"` key.

## Summary

- **Factory Droid** uses an explicit name map (`CLAUDE_TO_DROID_TOOLS`) in [`src/converters/claude-to-droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-droid.ts) to convert lowercase Claude tools to PascalCase Droid equivalents, filtered against `VALID_DROID_TOOLS`.
- **Cursor** relies on content transformation via `transformContentForCursor` in [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts) to rewrite task calls, slash commands, paths, and agent references without a fixed tool registry.
- **Codex** shares the canonical `TOOL_MAP` with OpenCode in [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts), applying `transformContentForCodex` in [`src/converters/claude-to-codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-codex.ts) to generate `$skill` syntax and `/prompts:` commands.
- **OpenCode** uses the same `TOOL_MAP` and `parseToolSpec` logic to build permission matrices in [`opencode.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/opencode.json) rather than transforming content for skill files.

## Frequently Asked Questions

### How does the Compound Engineering Plugin handle tool name case sensitivity?

The plugin normalizes tool names to lowercase before looking them up in mapping dictionaries. In [`src/converters/claude-to-droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-droid.ts), the `mapAgentTools` function converts the agent body to lowercase before checking against `CLAUDE_TO_DROID_TOOLS` keys. Similarly, `parseToolSpec` in [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts) normalizes input strings to lowercase before consulting the `TOOL_MAP`.

### Can I customize the tool mappings for a specific target platform?

Currently, the tool mappings are hardcoded in the converter TypeScript files. To customize mappings for Factory Droid, you would need to modify the `CLAUDE_TO_DROID_TOOLS` record in [`src/converters/claude-to-droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-droid.ts). For Codex and OpenCode, the `TOOL_MAP` in [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts) serves as the shared source of truth. The CLI does not currently support external configuration files for custom mappings.

### What happens if a Claude tool is not present in the target platform's mapping?

For Factory Droid, tools not found in `CLAUDE_TO_DROID_TOOLS` are simply not added to the agent's tool list, and tools not in `VALID_DROID_TOOLS` are filtered out during the `mapAgentTools` execution. For Cursor, which lacks a fixed tool registry, unrecognized tools pass through the content transformer without modification. For Codex and OpenCode, tools not in `TOOL_MAP` return `null` from `parseToolSpec` and are typically omitted from permission generation or skill transformation.

### How are agent references like @agent-name handled across different platforms?

Each platform converter applies specific regex transformations to handle `@agent-name` references. In [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts), the transformer converts `@agent-X` patterns into `the <agent> rule` syntax. In [`src/converters/claude-to-codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-codex.ts), the same pattern becomes `$<agent> skill` to match Codex's `$skill` syntax. OpenCode does not typically transform agent references in content, instead using the canonical tool names for permission scoping.