Skip to content

Adapters

Adapters connect Recursive to agent CLI tools — they define how to spawn an agent process, feed it instructions, and capture its output. Each adapter wraps a specific CLI (Claude Code, Cursor, Codex, etc.) and translates Recursive’s session protocol into the CLI’s interface.

Build an adapter when you want Recursive to orchestrate an agent CLI that isn’t already supported. The built-in adapters cover:

  • Claude Code (claude) — Claude’s official CLI
  • Cursor (cursor-agent-cli) — Cursor’s agent mode
  • Codex (codex-cli) — OpenAI’s Codex CLI
  • Gemini (gemini-cli) — Google’s Gemini CLI
  • Process (process-cli) — Generic process adapter for any CLI

If your CLI isn’t in this list, you need a custom adapter.

An adapter is a TypeScript file that exports a class implementing the adapter interface:

my-adapter-plugin/
plugin.json
adapters/
my-agent.ts

The manifest declares the adapter directory:

{
"id": "my-agent",
"name": "My Agent Adapter",
"version": "1.0.0",
"adapters": "./adapters/"
}

Each adapter file exports a class with standard lifecycle methods:

export default class MyAgentAdapter {
static id = 'my-agent';
static label = 'My Agent';
static description = 'Runs tasks via the my-agent CLI.';
/** Check if the CLI is installed and accessible. */
static async isAvailable(): Promise<boolean> {
// Check if `my-agent` binary exists on PATH
}
/** Spawn the agent process for a session. */
async spawn(opts: SpawnOptions): Promise<SpawnResult> {
// Build the CLI command and arguments
// Set up environment variables (MCP server URL, session context)
// Spawn the child process
// Return process handle and metadata
}
/** Send a follow-up message to a running agent. */
async send(message: string): Promise<void> {
// Write to the agent's stdin or use its API
}
/** Terminate the agent process. */
async terminate(): Promise<void> {
// Kill the child process gracefully
}
}

The spawn method receives:

FieldTypeDescription
sessionIdstringThe Recursive session ID.
promptstringThe task/instruction for the agent.
modelstringRequested model (e.g., "claude-4-opus").
cwdstringWorking directory for the agent.
envobjectAdditional environment variables.
mcpServerUrlstringURL of the Recursive MCP server for this session.

Every adapter must pass the Recursive MCP server URL to the spawned agent. This is how the agent accesses Recursive’s tools (tasks, sessions, memory, etc.).

The standard approach is to configure the MCP server in the agent’s config format:

async spawn(opts) {
const mcpConfig = {
mcpServers: {
recursive: {
url: opts.mcpServerUrl,
transport: 'streamable-http',
},
},
};
// Write or inject this config into the agent's environment
}

For simple CLIs that accept a prompt on stdin and output on stdout, you can use the built-in Process adapter instead of writing a custom one:

{
"id": "my-tool",
"adapters": "./adapters/",
"settings": {
"defaults": {
"command": "my-tool",
"args": ["--mode", "agent"]
}
}
}

The Process adapter handles spawning, output capture, and lifecycle management for any CLI that follows a simple stdin/stdout pattern.

  1. Unit test availability: Call isAvailable() to verify the CLI is installed
  2. Integration test spawning: Use a test session to verify the adapter spawns correctly
  3. Verify MCP connectivity: Ensure the spawned agent can call Recursive tools
  4. Test termination: Verify the agent process shuts down cleanly