Skip to main content
Glama
cr4i50n
by cr4i50n
README.md
# continue-chat-export

Sanitize [Continue](https://continue.dev) session transcript exports and rewrite them as readable **Obsidian chat** Markdown.

| | |
|---|---|
| **Input** | Continue `*_session.md` exports (quoted or header form) |
| **Output** | `*.chat.md` on disk (`## User` / `## Assistant`, answers + **always-visible Sources**) |
| **MCP** | Tools return **paths + counts only** — never transcript body text |
| **License** | [MIT](LICENSE) (permissive; fork, modify, redistribute) |
| **Deps** | Python ≥ 3.11, [`mcp`](https://pypi.org/project/mcp/) |

Standalone package.
---

## Privacy contract

1. Processing is **local disk → disk**.
2. MCP tool **results** contain only metadata: paths, byte counts, null/ANSI counts, turn counts, source counts, error type strings.
3. Transcript **body is never** included in tool return values (so this server does not feed chat text back into the model context).
4. Other tools (generic filesystem MCPs, editor “@file”) can still read `*.chat.md` if pointed at them — this server does not offer a read/summarize tool.

---

## Features

- Strip embedded **NUL** bytes (e.g. UTF-16-LE blobs such as Windows `*.ini` in a transcript).
- Strip **ANSI** escape sequences from shell tool output.
- Collapse consecutive Continue assistant fragments into **one assistant turn** per user message.
- Web/search dumps (`Title:` / `URL:` / `Highlights:`) → always-visible `### Sources` blockquotes.
- Optional `<details>` for **non-web** tool dumps only (`--collapse-tools`).

### Example output shape

```markdown
---
type: continue-chat
source: "export_session.md"
exported: "1/1/2026, 12:00:00 PM"
sanitized: true
user_turns: 15
assistant_turns: 15
sources: 54
---

# Continue session transcript

## User

…

---

## Assistant

### Answer

…

### Sources

> **Page title**
> https://example.com/page
>
> Highlight / snippet text…

---
```

---

## Install

### From a clone (development / local MCP)

```bash
git clone https://github.com/<you>/continue-chat-export.git
cd continue-chat-export

uv venv .venv
uv pip install -e ".[dev]"

# or: python3 -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
```

| Script | Role |
|--------|------|
| `continue-chat-export` | CLI formatter |
| `continue-chat-export-mcp` | MCP server (stdio) |

```bash
.venv/bin/continue-chat-export --help
.venv/bin/pytest -q
```

### From PyPI (if/when published)

```bash
pip install continue-chat-export
```

---

## CLI

```bash
continue-chat-export path/to/export_session.md
continue-chat-export path/to/export_session.md -o path/to/out.chat.md
continue-chat-export a.md b.md c.md
continue-chat-export path/to/export_session.md --in-place
continue-chat-export path/to/export_session.md --include-narration
continue-chat-export path/to/export_session.md --collapse-tools
continue-chat-export path/to/export_session.md --max-tool-chars 8000
continue-chat-export path/to/export_session.md --inspect --json
```

Default sidecar output: `INPUT.chat.md`. CLI prints paths + counts only (or `--json` stats), never the chat body.

---

## Integrate with Continue

Official docs: [MCP in Continue](https://docs.continue.dev/customize/deep-dives/mcp).

### 1. Install this package

```bash
cd /path/to/continue-chat-export
uv venv .venv && uv pip install -e .
```

Entrypoint:

```text
/path/to/continue-chat-export/.venv/bin/continue-chat-export-mcp
```

### 2. Add `mcpServers` entry

In `~/.continue/config.yaml`:

```yaml
mcpServers:
  - name: continue-chat-export
    command: /path/to/continue-chat-export/.venv/bin/continue-chat-export-mcp
    args: []
    env:
      PATH: /usr/bin:/usr/local/bin:/bin
```

No API keys required.

#### Portable `uv run` variant

```yaml
mcpServers:
  - name: continue-chat-export
    command: uv
    args:
      - run
      - --directory
      - /path/to/continue-chat-export
      - continue-chat-export-mcp
    env:
      PATH: /usr/bin:/usr/local/bin:/bin
```

This is **Python**, not npm — do not use `npx` for this server.

### 3. Reload MCP

Restart Continue / reload the window and confirm tools are listed.

### 4. Agent mode usage

MCP tools run in **agent mode** only. Pass filesystem paths; do not paste transcript text.

- `format_continue_export` — `input_path="/path/to/vault/export_session.md"`
- `format_continue_export_batch` — `root="/path/to/vault"`, `glob="**/*_session.md"`
- `inspect_continue_export` — `input_path="/path/to/vault/export_session.md"`
- `list_session_exports` — `root="/path/to/vault"`

Results are stats only (`ok`, `output_path`, `user_turns`, `sources`, …). Open `output_path` in Obsidian yourself.

### 5. Workspace config (optional)

Same YAML may live in a workspace Continue config / `.continue/mcpServers/` (see Continue docs).

### 6. VSCodium

Same as VS Code once Continue is installed.

---

## MCP tools reference

All tools return **metadata only**.

| Tool | Purpose |
|------|---------|
| `format_continue_export` | One file → `*.chat.md` |
| `format_continue_export_batch` | Many files via `paths` or `root`+`glob` |
| `inspect_continue_export` | Size, nulls, turn counts (no write) |
| `list_session_exports` | List exports under a directory |

Default output: `<stem>.chat.md` beside the input.

---

## GitHub / publishing

```text
continue-chat-export/
  README.md
  LICENSE                 # MIT
  pyproject.toml
  .gitignore
  src/continue_chat_export/
  tests/
```

### Before you push

1. Docs use `/path/to/...` placeholders only (no personal home directories).
2. Do **not** commit `.venv/`, secrets, or real session transcripts.
3. Run `pytest -q`.
4. Optional PyPI publish (`hatchling` is configured).

### `.gitignore` (sessions)

Ignores `*_session.md`, `*.session.md`, `*.chat.md`, `*.bak_nulls`, `*.bak_continue_export`, plus `.venv/` and build caches. Keep `tests/fixtures/` (synthetic only).

### Consumer blurb

```markdown
## Install as Continue MCP

1. Clone and `uv pip install -e .`
2. Point Continue `mcpServers` at `/path/to/continue-chat-export/.venv/bin/continue-chat-export-mcp`
3. Agent mode → `format_continue_export` with a filesystem path
```

### Optional CI

```yaml
name: test
on: [push, pull_request]
jobs:
  pytest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
      - run: uv venv && uv pip install -e ".[dev]" && uv run pytest -q
```

---

## Development

```bash
uv pip install -e ".[dev]"
uv run pytest -q
```

| Module | Role |
|--------|------|
| `sanitize.py` | NUL / UTF-16-LE / ANSI |
| `parse.py` | Headers → turns |
| `sources.py` | Search hits → blockquotes |
| `format_chat.py` | Render + disk I/O |
| `cli.py` | CLI |
| `server.py` | FastMCP stdio |

---

## Limitations

- Heuristic classification; export quality bounds recovery.
- No native Continue UI reconstruction.
- Deterministic local formatting only (no LLM).

---

## License

[MIT](LICENSE) — free to use, fork, modify, and redistribute, including commercially, with license notice retained.