This note documents a working MemPalace setup for VS Code + GitHub Copilot, including MCP registration, hook wiring, and a custom transcript conversion flow for Copilot chat transcripts.
All paths below are sanitized. Replace placeholders like ${HOME} and ${WORKSPACE} with your own values.
MemPalace conversation mining supports several formats out of the box, including ChatGPT exports, Claude JSON, Slack exports, Markdown, and plain text transcripts.
VS Code Copilot chat transcripts are different.
MemPalace's ChatGPT import path expects a turn-oriented JSON structure with a mapping tree. VS Code Copilot stores chat history as JSONL event logs under a workspace storage directory, with records like:
session.startuser.messageassistant.messageassistant.turn_startassistant.turn_endtool.execution_starttool.execution_complete
Because of that mismatch, raw VS Code Copilot transcript files should not be passed directly to mempalace mine --mode convos.
The working solution is:
- Discover VS Code Copilot transcript files.
- Convert the event stream into a plain-text transcript format MemPalace already accepts.
- Mine those converted transcripts with
mempalace mine ... --mode convos.
Add a MemPalace server entry to .vscode/mcp.json:
{
"servers": {
"mempalace": {
"type": "stdio",
"command": "uv",
"args": ["run", "--with", "mempalace", "python", "-m", "mempalace.mcp_server"]
}
}
}This uses uv instead of requiring a permanently activated virtualenv.
If you already have other MCP servers configured, merge the mempalace entry into your existing servers object instead of replacing the whole file.
Example of a fuller .vscode/mcp.json:
{
"servers": {
"serena": {
"type": "stdio",
"command": "serena",
"args": ["start-mcp-server", "--context=vscode", "--project", "${workspaceFolder}"]
},
"context-mode": {
"type": "stdio",
"command": "context-mode"
},
"mempalace": {
"type": "stdio",
"command": "uv",
"args": ["run", "--with", "mempalace", "python", "-m", "mempalace.mcp_server"]
},
"git": {
"type": "stdio",
"command": "uvx",
"args": ["mcp-server-git", "--repository", "${workspaceFolder}"]
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "${workspaceFolder}"]
},
"eslint": {
"type": "stdio",
"command": "npx",
"args": ["@eslint/mcp@latest"]
}
},
"inputs": []
}That full example is optional. The only MemPalace-specific part is the mempalace server block.
Create .github/hooks/mempalace.json:
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "./.bin/mempal_save_hook.sh",
"cwd": ".",
"timeout": 120,
"env": {
"MEMPAL_DIR": "."
}
}
],
"PreCompact": [
{
"type": "command",
"command": "./.bin/mempal_precompact_hook.sh",
"cwd": ".",
"timeout": 120,
"env": {
"MEMPAL_DIR": "."
}
}
]
}
}These hooks are VS Code/Copilot variants of the upstream MemPalace save/precompact hooks.
Store the scripts in ./.bin/:
mempal_precompact_hook.shmempal_save_hook.shmempal_mine_vscode_transcripts.pymempal_reseed_vscode_transcripts.sh
Make them executable:
chmod +x .bin/mempal_precompact_hook.sh
chmod +x .bin/mempal_save_hook.sh
chmod +x .bin/mempal_mine_vscode_transcripts.py
chmod +x .bin/mempal_reseed_vscode_transcripts.shVS Code Copilot transcripts live under a workspace storage path like this:
${HOME}/.config/Code/User/workspaceStorage/<workspace-storage-id>/GitHub.copilot-chat/transcripts
The hooks use transcript discovery logic that:
- Uses
transcript_pathwhen the hook payload provides it. - Otherwise searches the VS Code workspace storage directory.
- Prefers a filename matching the Copilot
sessionId. - Falls back to the most recently modified transcript file.
An optional override is supported:
export VSCODE_WORKSPACE_STORAGE_DIR="${HOME}/.config/Code/User/workspaceStorage"The custom converter script reads the Copilot JSONL event stream and keeps only real conversation turns:
user.message-> user turnassistant.message-> assistant turn
It ignores lifecycle and tool execution noise, then emits plain-text transcript content like:
> User question
Assistant answer
> Next question
Next answer
This output is written to a cache directory, by default:
${HOME}/.mempalace/vscode-copilot-transcripts
Each converted file is named by session ID when available.
To re-import everything from the VS Code Copilot transcript folder, use:
./.bin/mempal_reseed_vscode_transcripts.shThis script:
- Targets the Copilot transcript directory.
- Clears the converted transcript cache.
- Rebuilds the converted plain-text transcript set.
- Runs MemPalace conversation mining on the converted output.
Optional modes:
./.bin/mempal_reseed_vscode_transcripts.sh --dry-run
./.bin/mempal_reseed_vscode_transcripts.sh --extract general
./.bin/mempal_reseed_vscode_transcripts.sh --convert-onlyYou can also override the source directory:
./.bin/mempal_reseed_vscode_transcripts.sh /path/to/GitHub.copilot-chat/transcriptsOr set it via environment:
export MEMPAL_VSCODE_TRANSCRIPTS_DIR="/path/to/GitHub.copilot-chat/transcripts"If you want to rebuild MemPalace from scratch:
rm -rf ${HOME}/.mempalace
./.bin/mempal_reseed_vscode_transcripts.shIf you also want general memory extraction:
rm -rf ${HOME}/.mempalace
./.bin/mempal_reseed_vscode_transcripts.sh
./.bin/mempal_reseed_vscode_transcripts.sh --extract generalMemPalace's conversation miner currently treats conversation files as effectively immutable for idempotency checks.
That means the custom converter/reseed flow works well for:
- first-time imports
- full reseeds after wiping the palace
- historical backfills
But repeated incremental re-mining of an already-filed converted transcript may still be skipped by MemPalace unless the underlying miner behavior changes.
So the safest model today is:
- use hooks for ongoing capture attempts
- use the reseed script when doing a fresh rebuild or historical import
.vscode/mcp.jsonupdated with the MemPalace MCP server.github/hooks/mempalace.json.bin/mempal_precompact_hook.sh.bin/mempal_save_hook.sh.bin/mempal_mine_vscode_transcripts.py.bin/mempal_reseed_vscode_transcripts.sh
# MCP server runs via VS Code using uv
# reseed from VS Code Copilot transcripts
./.bin/mempal_reseed_vscode_transcripts.sh
# dry-run
./.bin/mempal_reseed_vscode_transcripts.sh --dry-run
# general extraction pass
./.bin/mempal_reseed_vscode_transcripts.sh --extract general