# Session Export

> Convert AI coding CLI sessions between Codex, Claude Code, Pi, OpenCode, Devin, and Factory. SDK, CLI, MCP chat recall, and trace export for fine-tuning.

- **Type:** MCP server
- **Install:** `agentstack add mcp-vibheksoni-session-export`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [vibheksoni](https://agentstack.voostack.com/s/vibheksoni)
- **Installs:** 0
- **Category:** [Search](https://agentstack.voostack.com/c/search)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [vibheksoni](https://github.com/vibheksoni)
- **Source:** https://github.com/vibheksoni/session-export

## Install

```sh
agentstack add mcp-vibheksoni-session-export
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# UniSessions

UniSessions is an SDK-first AI CLI session converter for moving sessions between Codex, Claude Code, Pi, OpenCode, Devin, Factory, and Windsurf Cascade, with trace export for HuggingFace and fine-tuning, plus an MCP chat recall server built on top.

```
                                                                   
 ▄▄▄  ▄▄            ▄▄▄▄▄                                         
█▀██  ██           ██▀▀▀▀█▄                                       
  ██  ██  ▄     ▀▀ ▀██▄  ▄▀                   ▀▀       ▄          
  ██  ██  ████▄ ██   ▀██▄▄  ▄█▀█▄ ▄██▀█ ▄██▀█ ██ ▄███▄ ████▄ ▄██▀█
  ██  ██  ██ ██ ██ ▄   ▀██▄ ██▄█▀ ▀███▄ ▀███▄ ██ ██ ██ ██ ██ ▀███▄
  ▀█████▄▄██ ▀█▄██ ▀██████▀▄▀█▄▄▄█▄▄██▀█▄▄██▀▄██▄▀███▀▄██ ▀██▄▄██▀

```

**Convert one AI CLI session format into another across Codex, Pi, OpenCode, Claude Code, Devin, Factory, and Windsurf Cascade.**

I use a lot of AI coding CLIs Codex Claude Code Pi OpenCode Devin Factory Windsurf and wanted to move a session from one tool into another without losing the useful conversation history

[](https://pypi.org/project/unisessions/)
[](https://www.python.org/)
[]()
[-purple)]()
[]()
[]()
[]()
[]()
[](https://github.com/vibheksoni/session-export/stargazers)

---

## Table of Contents

- [Why I built this](#why-i-built-this)
- [Quick Start](#quick-start)
- [Supported AI coding agents](#supported-ai-coding-agents)
- [All 42 conversion directions](#all-42-conversion-directions)
- [How to list sessions](#how-to-list-sessions)
- [How to convert sessions](#how-to-convert-sessions)
- [How to export traces](#how-to-export-traces)
- [How to handle conflicts](#how-to-handle-conflicts)
- [How to bulk export](#how-to-bulk-export)
- [How to use custom paths](#how-to-use-custom-paths)
- [MCP server for agent chat recall](#mcp-server-for-agent-chat-recall)
- [SDK usage](#sdk-usage)
- [Architecture](#architecture)
- [Default session paths](#default-session-paths)
- [Data fidelity](#data-fidelity)
- [Performance](#performance)
- [FAQ](#faq)
- [Contributing](#contributing)
- [Development](#development)
- [License](#license)

## Why I built this

I looked for a tool that could convert one AI CLI session into another AI CLI session format and found nothing so I built one

I also wanted my agent to remember things from my other sessions like if I solved a bug in one project I wanted to tell it hey in that other session I fixed this by doing X and it would go check and learn from it instead of me explaining the same thing again

So this does two things

- Moves your sessions between Codex Pi OpenCode Claude Code Devin Factory and Windsurf Cascade in any direction all 42 combinations
- Exports sessions as traces in HuggingFace STS OpenAI fine-tuning or ShareGPT format for Hub upload or model training
- Lets your agent search through all your old chat history across all projects and providers so it can recall what you did before and learn from it

Then I wanted the project to not be locked into a CLI or MCP its an SDK first so you can use it for other projects to do cool stuff like build a GUI for it or whatever you want the CLI and MCP server are just built on top of the SDK

## Quick Start

Install from PyPI:

```powershell
pip install unisessions
python -m unisessions list codex
python -m unisessions list pi
python -m unisessions list opencode
python -m unisessions list claude
python -m unisessions list devin
python -m unisessions list factory
python -m unisessions list windsurf
```

Or clone the repo:

```powershell
git clone https://github.com/vibheksoni/session-export.git
cd session-export
pip install -e .
python -m unisessions list codex
```

Convert a single session (dry-run first, then write):

```powershell
python -m unisessions codex-to-pi 
python -m unisessions codex-to-pi  --write
python -m unisessions claude-to-pi  --write
python -m unisessions devin-to-pi  --write
python -m unisessions factory-to-pi  --write
python -m unisessions windsurf-to-pi  --write
```

Export a session as a HuggingFace trace:

```powershell
python -m unisessions to-trace codex  --format sts --write -o trace.jsonl
```

Bulk export all Codex sessions to Pi:

```powershell
python -m unisessions codex-to-pi-all --write --workers 8
```

Search across all sessions via MCP:

```powershell
python -m unisessions.mcp_server
```

## Supported AI coding agents

| Agent | Store | Session Format | Session IDs |
|---|---|---|---|
| [OpenAI Codex](https://github.com/openai/codex) | `codex` | JSONL rollout files under date tree | UUID v7 |
| [Pi](https://github.com/earendil-works/pi-coding-agent) | `pi` | JSONL append-only tree entries in cwd-encoded dirs | UUID v7 |
| [OpenCode](https://github.com/sst/opencode) | `opencode` | Official export/import JSON | `ses_` prefixed |
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | `claude` | JSONL transcript files in cwd-sanitized dirs | UUID v4 |
| [Devin](https://windsurf.com/devin) (Windsurf CLI) | `devin` | ATIF transcript JSON + SQLite metadata | slug names |
| [Factory](https://factory.ai) (Droid) | `factory` | JSONL transcript files with session headers | UUID v4 |
| [Windsurf](https://windsurf.com) (Cascade) | `windsurf` | AES-256-GCM encrypted protobuf trajectory files | UUID v4 |

## All 42 conversion directions

| From \ To | Pi | Codex | OpenCode | Claude | Devin | Factory | Windsurf |
|---|---|---|---|---|---|---|---|
| **Codex** | `codex-to-pi` | -- | `codex-to-opencode` | `codex-to-claude` | `codex-to-devin` | `codex-to-factory` | `codex-to-windsurf` |
| **Pi** | -- | `pi-to-codex` | `pi-to-opencode` | `pi-to-claude` | `pi-to-devin` | `pi-to-factory` | `pi-to-windsurf` |
| **OpenCode** | `opencode-to-pi` | `opencode-to-codex` | -- | `opencode-to-claude` | `opencode-to-devin` | `opencode-to-factory` | `opencode-to-windsurf` |
| **Claude** | `claude-to-pi` | `claude-to-codex` | `claude-to-opencode` | -- | `claude-to-devin` | `claude-to-factory` | `claude-to-windsurf` |
| **Devin** | `devin-to-pi` | `devin-to-codex` | `devin-to-opencode` | `devin-to-claude` | -- | `devin-to-factory` | `devin-to-windsurf` |
| **Factory** | `factory-to-pi` | `factory-to-codex` | `factory-to-opencode` | `factory-to-claude` | `factory-to-devin` | -- | `factory-to-windsurf` |
| **Windsurf** | `windsurf-to-pi` | `windsurf-to-codex` | `windsurf-to-opencode` | `windsurf-to-claude` | `windsurf-to-devin` | `windsurf-to-factory` | -- |

## How to list sessions

```powershell
python -m unisessions list codex
python -m unisessions list pi
python -m unisessions list opencode
python -m unisessions list claude
python -m unisessions list devin
python -m unisessions list factory
python -m unisessions list windsurf
```

## How to convert sessions

All commands default to dry-run. Add `--write` to produce output.

```powershell
python -m unisessions codex-to-pi  --write
python -m unisessions pi-to-codex  --write
python -m unisessions codex-to-opencode  --write
python -m unisessions pi-to-opencode  --write
python -m unisessions opencode-to-codex  --write
python -m unisessions opencode-to-pi  --write
python -m unisessions claude-to-pi  --write
python -m unisessions pi-to-claude  --write
python -m unisessions claude-to-codex  --write
python -m unisessions codex-to-claude  --write
python -m unisessions claude-to-opencode  --write
python -m unisessions opencode-to-claude  --write
python -m unisessions devin-to-pi  --write
python -m unisessions pi-to-devin  --write
python -m unisessions devin-to-codex  --write
python -m unisessions codex-to-devin  --write
python -m unisessions devin-to-opencode  --write
python -m unisessions opencode-to-devin  --write
python -m unisessions devin-to-claude  --write
python -m unisessions claude-to-devin  --write
python -m unisessions factory-to-pi  --write
python -m unisessions pi-to-factory  --write
python -m unisessions factory-to-codex  --write
python -m unisessions codex-to-factory  --write
python -m unisessions factory-to-opencode  --write
python -m unisessions opencode-to-factory  --write
python -m unisessions factory-to-claude  --write
python -m unisessions claude-to-factory  --write
python -m unisessions factory-to-devin  --write
python -m unisessions devin-to-factory  --write
python -m unisessions windsurf-to-pi  --write
python -m unisessions pi-to-windsurf  --write
python -m unisessions windsurf-to-codex  --write
python -m unisessions codex-to-windsurf  --write
python -m unisessions windsurf-to-opencode  --write
python -m unisessions opencode-to-windsurf  --write
python -m unisessions windsurf-to-claude  --write
python -m unisessions claude-to-windsurf  --write
python -m unisessions windsurf-to-devin  --write
python -m unisessions devin-to-windsurf  --write
python -m unisessions windsurf-to-factory  --write
python -m unisessions factory-to-windsurf  --write
```

## How to export traces

Export any session as a trace file for HuggingFace Hub upload, model fine-tuning, or training data preparation. Three formats are supported:

| Format | Use case |
|---|---|
| `sts` | HuggingFace Hub trace viewer (Session Trace Simple Format) |
| `openai` | OpenAI / Azure fine-tuning JSONL format |
| `sharegpt` | ShareGPT format for LLaMA-Factory, Axolotl, torchtune |

```powershell
# HuggingFace STS format (default) -- print to stdout
python -m unisessions to-trace codex  --format sts

# OpenAI fine-tuning format -- write to file
python -m unisessions to-trace pi  --format openai --write -o train.jsonl

# ShareGPT format from Devin session
python -m unisessions to-trace devin  --format sharegpt --write -o traces.jsonl
```

Upload to HuggingFace Hub:

```powershell
pip install huggingface-cli
hf upload your-username/your-dataset trace.jsonl
```

The Hub auto-detects the trace format and renders it in the trace viewer. See the [trace export docs](docs/traces.md) for SDK usage and format details.

## How to handle conflicts

When a destination file already exists use `--on-conflict` to control behavior:

| Mode | Behavior |
|---|---|
| `skip` (default) | Skip if destination exists |
| `overwrite` | Replace existing destination with new content |
| `fork` | Generate a new UUID session ID, preserve old file untouched |
| `update` | Skip if unchanged, overwrite if source changed (fast head-meta + line count check) |

```powershell
python -m unisessions codex-to-pi  --write --on-conflict fork
python -m unisessions codex-to-pi  --write --on-conflict update
```

## How to bulk export

Export all Codex sessions to one or more targets in parallel:

```powershell
python -m unisessions codex-to-pi-all --write --workers 8
python -m unisessions export-all --write --targets pi opencode claude devin factory windsurf --workers 8
```

## How to use custom paths

Use system defaults by omitting path flags. For backups or staging:

```powershell
python -m unisessions --codex-session-dir C:\path\to\sessions list codex
python -m unisessions --pi-session-dir C:\path\to\pi\sessions list pi
python -m unisessions --opencode-session-dir C:\path\to\opencode\exports list opencode
python -m unisessions --claude-session-dir C:\path\to\claude\projects list claude
python -m unisessions --devin-session-dir C:\path\to\devin\transcripts list devin
python -m unisessions --factory-session-dir C:\path\to\factory\sessions list factory
python -m unisessions --windsurf-session-dir C:\path\to\windsurf\cascade list windsurf
```

OpenCode output files use the official import/export JSON shape. Load them with
`opencode import `.

## MCP server for agent chat recall

UniSessions ships a [FastMCP](https://github.com/jlowin/fastmcp) server that
exposes a SQLite FTS5 full-text search index over parsed session chat history.
AI agents can use it to recall past conversations, find what was discussed, and
search across all providers.

### Setup

```powershell
python -m unisessions.mcp_server
```

### MCP client configuration

```json
{
  "mcpServers": {
    "unisessions": {
      "command": "unisessions-mcp",
      "args": [],
      "env": {
        "UNISESSIONS_SEARCH_INDEX": "C:\\Users\\you\\AppData\\Local\\unisessions\\search.sqlite"
      }
    }
  }
}
```

### HTTP transports for app-managed servers

```powershell
unisessions-mcp --transport streamable-http --host 127.0.0.1 --port 8765 --path /mcp
unisessions-mcp --transport http --host 127.0.0.1 --port 8765
unisessions-mcp --transport sse --host 127.0.0.1 --port 8765
```

Environment knobs: `UNISESSIONS_MCP_TRANSPORT`, `UNISESSIONS_MCP_HOST`,
`UNISESSIONS_MCP_PORT`, `UNISESSIONS_MCP_PATH`, `UNISESSIONS_MCP_LOG_LEVEL`,
`UNISESSIONS_MCP_SHOW_BANNER`, `UNISESSIONS_SEARCH_INDEX`.

### MCP tools

| Tool | Description |
|---|---|
| `list_chats` | List sessions globally or filtered by provider and project path |
| `index_status` | Report indexed, missing, stale, deleted, and refresh-size counts |
| `refresh_chats_index` | Parse sessions into SQLite FTS5 index for fast recall |
| `search_chats` | Full-text search with literal, regex, all-keywords, and any-keywords modes |
| `search_sessions` | Find which sessions match a topic, with match counts and top snippets |

`search_chats` returns a structured response with `search_metadata` (total_matches, deduplicated, sessions_searched, messages_searched, truncated) and a `results` array ranked by relevance score. Duplicate messages across compaction cycles are collapsed to a single hit with a `duplicate_count` field.

`search_chats` supports provider (`codex`, `pi`, `opencode`, `claude`, `devin`, `factory`, `windsurf`), cwd,
session_id, role (`user`, `assistant`), message type (`message`, `compaction`,
`contextual`), `exclude_keywords` to filter out false positives, `max_per_session`
(default 5) to prevent one session from flooding results, date range (`after`,
`before`), and stale-index policy (`refresh`, `skip`, `error`).

Search runs over parsed `TextMessage` rows, not raw JSON files, so semantic
filters like `roles=["user"]` stay correct. Tool calls and tool outputs are
excluded to keep recall focused on chat text. An internal raw-match cap of 200
prevents timeouts on massive sessions.

**Performance**: warm indexed search ~35-40ms on a 20-session corpus. Cold
index refresh ~39-49s (I/O-bound). Call `index_status` first, then
`refresh_chats_index`, then use `search_chats` with `stale_policy="skip"` for
fast interactive recall.

## SDK usage

Build your own application on top of `session_sdk` without the CLI:

```python
from session_sdk import (
    CodexStore, PiStore, PiDcpStore, FactoryStore, WindsurfStore,
    CodexToPiConverter, SessionIdFactory, WindowsDefaults,
)

defaults = WindowsDefaults()
codex = CodexStore(defaults.codex_home)
pi = PiStore(defaults.pi_agent_home)
dcp = PiDcpStore(defaults.pi_dcp_home)

converter = CodexToPiConverter(codex, pi, dcp, SessionIdFactory())
plan = converter.plan("your-session-id-here")

print(f"Source:      {plan.source.path}")
print(f"Destination: {plan.destination}")
print(f"Records:     {len(plan.records)}")

converter.write(plan, overwrite=False)
```

### Trace export API

```python
from session_sdk import (
    CodexStore, WindowsDefaults,
    MessageExtractor, build_trace,
)
from session_sdk.jsonl import _dumps

defaults = WindowsDefaults()
store = CodexStore(defaults.codex_home)
session = store.load("session-id")
messages = MessageExtractor().from_codex(session)

# Build HuggingFace STS-format trace
records = build_trace("sts", session, messages)

# Write to JSONL
with open("trace.jsonl", "wb") as f:
    for record in records:
        f.write(_dumps(record))
        f.write(b"\n")
```

### Search API

```python
from session_sdk import (
    CodexStore, PiStore, OpenCodeStore, ClaudeStore, DevinStore, FactoryStore, WindsurfStore,
    SessionSearchEngine, WindowsDefaults,
)

defaults = WindowsDefaults()
engine = SessionSearchEngine(
    CodexStore(defaults.codex_home),
    PiStore(defaults.pi_agent_home),
    OpenCodeStore(defaults.opencode_data_home),
    claude=ClaudeStore(defaults.claude_home),
    devin=DevinStore(defaults.devin_home),
    factory=F

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [vibheksoni](https://github.com/vibheksoni)
- **Source:** [vibheksoni/session-export](https://github.com/vibheksoni/session-export)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-vibheksoni-session-export
- Seller: https://agentstack.voostack.com/s/vibheksoni
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
