Agents + portagenty
portaconv exists so you (or an agent) can move conversation context around. This page covers what you can do with it (four patterns) and how agents call it (CLI or MCP).
Four things you can do
Section titled “Four things you can do”/compact recovery/compact, lost the detail, want it back. Dump the pre-compact session and paste the full version into the current chat.list_conversations + get_conversation, picks the relevant prior session, and prepends it to its own context. No human copy-paste.Jump to a pattern below for copy-pasteable commands, or keep reading for how to wire portaconv into an agent in the first place.
Two ways an agent reaches portaconv
Section titled “Two ways an agent reaches portaconv”Agent runs pconv list / pconv dump <id> through its shell-execution tool. No extra wiring. Works in Claude Code, opencode, Aider, terminal-bound agents.
Start pconv mcp serve from the agent’s mcp.json. Two typed tools + a URI-templated resource. Agent calls them like any other MCP server.
CLI path
Section titled “CLI path”# Discover sessions belonging to the current workspacepconv list --workspace-toml auto --format json
# Dump a specific session for context recovery, with path rewritingpconv dump <session-id> --rewrite wsl-to-win
# Pipe to a recovery doc and commit itpconv dump <session-id> > docs/agent-context/2026-04-20-recovery.mdgit add docs/agent-context/ && git commit -m "capture recovery context"MCP path
Section titled “MCP path”Add to ~/.claude/mcp.json (or a project-local .mcp.json):
{ "mcpServers": { "portaconv": { "command": "pconv", "args": ["mcp", "serve"] } }}opencode uses a similar config shape. See its docs for the exact
path — the command + args pair is portable.
Exposed tools:
list_conversations {
// Scope
workspace_toml?: string // path, or "auto" to walk up from cwd
min_messages?: integer // default 1
show_duplicates?: boolean // default false — collapse WSL/Win dups
// Filter / sort / slice
since?: string // "2d" / "6h" / "30m" / "4w" / "2026-04-01" / RFC3339
grep?: string // case-insensitive substring on title+cwd (NOT content)
sort?: "updated" | "started" | "msgs" | "title" | "id"
reverse?: boolean
limit?: integer // 0 = no cap
}
→ JSON-serialized SessionMeta[] (in content[0].text)
get_conversation {
// Target — pick ONE
id?: string // session UUID, OR
latest?: boolean // resolve "most recent in scope"
workspace_toml?: string // scope for latest
// Backing-file override (conflicts with workspace_toml).
// Escape hatch for picking a specific duplicate by path.
file?: string // load this exact JSONL; id/latest pick session within
// Output shape
format?: "markdown" | "json" // default markdown
rewrite?: "wsl-to-win" | "win-to-wsl" | "strip"
include_thinking?: boolean // default false
full_results?: boolean // default false — results truncated at 600 chars
tail?: integer // keep last N messages; drop count in extensions.truncated
}
→ rendered body (in content[0].text)Exposed resource: one URI template convos://conversation/{id}.
resources/read on a concrete URI returns the session as markdown
with default options. Equivalent to calling get_conversation with
no optional args.
Portagenty workspace scoping
Section titled “Portagenty workspace scoping”portagenty’s workspace TOML (*.portagenty.toml) declares:
- a stable
id(UUID, survives folder moves) - a
projectslist — absolute or~-relative paths that belong to this workspace
Point portaconv at the TOML and list filters to just those
projects:
# Auto — walks up from cwd looking for *.portagenty.tomlpconv list --workspace-toml auto
# Explicit path — works from anywherepconv list --workspace-toml /path/to/my-workspace.portagenty.tomlSame flag works via MCP as the workspace_toml argument on
list_conversations. When projects is missing from the TOML,
the scope defaults to the TOML’s own directory.
Surviving folder moves — previous_paths
Section titled “Surviving folder moves — previous_paths”If a workspace has been moved (portagenty’s auto-re-register-on-walk-up
fires when it detects the TOML’s id at a new path), old Claude Code
sessions are keyed under the old cwd. To bridge them without any
out-of-band state:
# Appended by portagenty when it re-registers a moved workspace;# read by portaconv as additive scope entries.previous_paths = ["/home/alice/code/myproj"]portaconv reads this array alongside projects and unions both into
the workspace scope. Sessions authored at the old path surface in
list / dump the same way current-path sessions do. No id-lookup
coupling; everything lives in the committable TOML.
Currently portaconv reads previous_paths; portagenty’s auto-append
behavior is tracked as a separate upstream PR.
Pattern details
Section titled “Pattern details”1. Post-/compact recovery
Section titled “1. Post-/compact recovery”After /compact in Claude Code, long-context detail is summarized.
If the agent later needs pre-compact specifics:
# From the agent (or a shell):pconv list --workspace-toml auto --format json# (pick the relevant old session UUID from the list)
pconv dump <old-session-id> --full-results > /tmp/pre-compact.md# (read the file back into the current agent's context, or paste)2. Cross-tool handoff
Section titled “2. Cross-tool handoff”Session authored in Claude Code on WSL, continuing in opencode on Windows:
pconv dump <id> --rewrite wsl-to-win | clip.exe# paste into opencode, which reads the now-Windows-native paths3. Committed recovery artifact
Section titled “3. Committed recovery artifact”Freeze an important session as a repo-tracked doc so it survives Claude Code’s retention or a folder move:
mkdir -p docs/agent-context/pconv dump <id> --full-results > docs/agent-context/$(date +%F)-redesign-session.mdgit add docs/agent-context/ && git commit -m "capture redesign context"Re-load it later by pointing a fresh agent at the committed file. No daemon, no retention dependency — git is the store.
4. Agent-as-curator via MCP
Section titled “4. Agent-as-curator via MCP”An agent already inside a session can skip the picker entirely and just ask for the most recent relevant session:
// Simplest — "give me the previous session in this workspace"{ "name": "get_conversation", "arguments": { "latest": true, "workspace_toml": "auto", "include_thinking": false }}Or it can narrow first, then pick:
// 1) Shortlist with filters{ "name": "list_conversations", "arguments": { "workspace_toml": "auto", "since": "7d", "grep": "auth refactor", "limit": 3 }}
// 2) Pull the one the agent judges most relevant{ "name": "get_conversation", "arguments": { "id": "<chosen-uuid>" } }The user never has to copy anything. Because filters and latest
live on both the MCP schema and the CLI, the same workflow works
whether the agent is speaking protocol or shelling out.
What portaconv doesn’t do
Section titled “What portaconv doesn’t do”- Doesn’t write back to any tool’s storage. Ever.
- Doesn’t run a daemon / watcher / background sync.
- Doesn’t manage clipboards — pipe to
clip.exe/pbcopy/wl-copyyourself. - Doesn’t do full-text search — get-by-id only in v0.1 (search tracked for v0.2+).
- Doesn’t know about portagenty’s runtime state — only reads the TOML file at call time.
Planned portagenty shim (not v0.1)
Section titled “Planned portagenty shim (not v0.1)”The eventual pa convos subcommand will shell out to pconv with
workspace context pre-filled:
# Shorthand for: pconv list --workspace-toml <this-workspace>pa convos list
# Shorthand for: pconv dump <id> piped with reasonable defaultspa convos dump <id>
# Surfaced when pa's auto-re-register-on-walk-up detects a folder# move — prompts the user to run pconv to see old-path sessions.This ships as a separate PR in the portagenty repo once portaconv reaches v0.1 publish. portaconv stays usable standalone.