# How Session Transfer Works Between Claude Code and Codex

> Learn how session transfer works between Claude Code and Codex. Migrate Claude Code transcripts to Codex threads using the codex transfer command.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-16

---

**The `codex transfer` command migrates Claude Code session transcripts (`.jsonl` files) into new Codex threads by validating the source path, sending a migration request to the Codex app-server, and returning a resumable thread ID.**

The openai/codex-plugin-cc repository enables seamless migration of conversation history from Claude Code to Codex through a structured session transfer protocol. This feature converts Claude's `.jsonl` transcript format into Codex-compatible threads, preserving visible turn history while allowing users to resume work in the Codex CLI.

## The Session Transfer Pipeline

The transfer process follows a six-step pipeline orchestrated across three core modules. When a user executes `codex transfer --source <path>`, the companion script processes the Claude transcript through validation, import, and formatting stages.

### Step 1: Path Resolution and Security Validation

In `plugins/codex/scripts/lib/claude-session-transfer.mjs` (lines 20-44), the `resolveClaudeSessionPath()` function performs security-critical path validation:

- Expands `~` and relative path segments to absolute paths
- Verifies the file extension is `.jsonl`
- Ensures the resolved path lives within `$HOME/.claude/projects` to prevent directory traversal attacks

### Step 2: Importing the Session into Codex

The `importExternalAgentSession()` function in `plugins/codex/scripts/lib/codex.mjs` (lines 58-70) handles the actual migration:

- Validates that the Codex CLI is installed locally
- Constructs a migration request containing the transcript path
- Dispatches to `requestExternalAgentSessionImport()` to communicate with the Codex app-server

### Step 3: Thread ID Extraction and Error Handling

After the app-server processes the import, the code in `plugins/codex/scripts/lib/codex.mjs` (lines 80-88):

- Extracts the new thread ID using `importedThreadIdForSource()`
- If extraction fails, raises detailed errors including stderr from Codex to diagnose version compatibility issues

### Step 4: Result Formatting and User Output

The `executeTransfer()` function in `plugins/codex/scripts/codex-companion.mjs` (lines 25-38) packages the results:

- Constructs the resume command: `codex resume <thread-id>`
- Wraps the thread ID, source path, and command into a payload
- `renderTransferResult()` (lines 16-22) generates the console output showing the Codex session ID and resume instructions

## End-to-End Execution Flow

1. User invokes: `codex transfer --source ~/myproject/session.jsonl`
2. Command dispatcher routes to `executeTransfer()`
3. `resolveClaudeSessionPath()` validates the transcript location
4. `importExternalAgentSession()` sends the migration request to the Codex app-server
5. App-server creates a new thread and returns the thread ID
6. CLI displays the transfer confirmation with resume instructions

## Implementation Examples

### Programmatic Transfer

```javascript
import { resolveClaudeSessionPath } from "./plugins/codex/scripts/lib/claude-session-transfer.mjs";
import { importExternalAgentSession } from "./plugins/codex/scripts/lib/codex.mjs";

async function transferClaudeSession(cwd, source) {
  // Step 1 – Resolve & validate the transcript path
  const transcriptPath = resolveClaudeSessionPath(cwd, { source });

  // Step 2 – Ask Codex to import the transcript
  const { threadId } = await importExternalAgentSession(cwd, {
    sourcePath: transcriptPath,
    onProgress: (msg, state) => console.log(`[${state}] ${msg}`)
  });

  return {
    threadId,
    resumeCommand: `codex resume ${threadId}`
  };
}

```

### CLI Usage

```bash
codex transfer --source ~/myproject/session.jsonl

```

Behind the scenes, this invokes `executeTransfer()` in `plugins/codex/scripts/codex-companion.mjs` with the provided source path.

## Error Handling and Progress Reporting

Throughout the pipeline, `emitProgress()` reports status updates like "Importing Claude session" and "Claude session imported". When the RPC method `externalAgentSessionImport` is missing (indicating an outdated Codex version), the error message includes actionable hints to update the Codex CLI.

## Summary

- The session transfer between Claude Code and Codex operates through a four-step validation and import pipeline
- `resolveClaudeSessionPath()` enforces security by restricting access to `$HOME/.claude/projects`
- `importExternalAgentSession()` communicates with the Codex app-server via RPC to create new threads
- The transfer preserves visible turn history and generates a `codex resume <thread-id>` command for continuity
- Comprehensive error handling includes version compatibility checks and detailed stderr reporting

## Frequently Asked Questions

### What file format does Claude Code use for session transcripts?

Claude Code stores session history as `.jsonl` (JSON Lines) files within the `$HOME/.claude/projects` directory. The transfer tool specifically requires this extension and location to ensure compatibility and security.

### Can I transfer sessions from outside the Claude projects directory?

No. The `resolveClaudeSessionPath()` function explicitly validates that the source path resides within `$HOME/.claude/projects`. This prevents directory traversal attacks and ensures the plugin only accesses legitimate Claude session files.

### What happens if my Codex CLI is outdated?

If the Codex CLI lacks the `externalAgentSessionImport` RPC method, the import operation fails with a detailed error message. The error includes stderr output from Codex and suggests updating to the latest version to enable session transfer functionality.

### Does the transfer delete the original Claude session?

No, the session transfer creates a copy of the conversation history in Codex. The original `.jsonl` transcript remains intact in the Claude projects directory, allowing you to reference or re-import the session if needed.