https://github.com/danielgerlag/copilot-sync
https://github.com/danielgerlag/copilot-sync
Last synced: 10 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/danielgerlag/copilot-sync
- Owner: danielgerlag
- Created: 2026-03-07T20:37:47.000Z (5 months ago)
- Default Branch: master
- Last Pushed: 2026-03-07T21:22:45.000Z (5 months ago)
- Last Synced: 2026-07-13T03:26:27.989Z (17 days ago)
- Language: TypeScript
- Size: 50.8 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# copilot-session-sync
An MCP server that syncs your GitHub Copilot CLI and VS Code extension sessions across machines, Codespaces, and environments via a private GitHub repository.
## Why?
Your Copilot sessions (conversation history, plans, checkpoints, artifacts) are stored locally in `~/.copilot/`. When you switch machines, open a Codespace, or work from a different environment, those sessions are gone. This tool fixes that.
## How It Works
`copilot-session-sync` exposes MCP tools that you can invoke directly from Copilot CLI or VS Code Copilot chat. Behind the scenes, it uses a private GitHub repository (`{your-username}/.copilot`) as cloud storage for your sessions.
- **Bidirectional sync** — pushes new/updated local sessions and pulls new/updated remote sessions
- **Session-level merge** — uses `updated_at` timestamps to determine which side wins
- **SQLite DB merge** — row-level merge of the `session-store.db` database with FTS5 index rebuild
- **Auto-creates** the private `.copilot` repo if it doesn't exist
- **Cross-platform** — works on macOS, Linux, and Windows (no native compilation required)
## Quick Start
### Prerequisites
- **Node.js** >= 20
- **GitHub CLI** authenticated (`gh auth login`), **or** a `GITHUB_TOKEN` environment variable
### Option 1: Use with `npx` (recommended — no install needed)
Just add the MCP server config and start using it. No clone, no build, no install.
### Option 2: Install globally
```bash
npm install -g copilot-session-sync
```
### Option 3: Clone and build from source
```bash
git clone https://github.com/danielgerlag/copilot-sync.git
cd copilot-sync
npm install
npm run build
```
## Configuration
### GitHub Copilot CLI
Add to your MCP configuration file (typically `~/.config/github-copilot/mcp.json` or as configured):
**Using npx (recommended):**
```json
{
"mcpServers": {
"copilot-session-sync": {
"command": "npx",
"args": ["-y", "copilot-session-sync"]
}
}
}
```
**Using global install:**
```json
{
"mcpServers": {
"copilot-session-sync": {
"command": "copilot-session-sync"
}
}
}
```
**Using local build:**
```json
{
"mcpServers": {
"copilot-session-sync": {
"command": "node",
"args": ["/path/to/copilot-sync/dist/index.js"]
}
}
}
```
### VS Code (GitHub Copilot Chat)
Add to your VS Code `settings.json` (`Cmd+Shift+P` → "Preferences: Open User Settings (JSON)"):
**Using npx (recommended):**
```json
{
"mcp": {
"servers": {
"copilot-session-sync": {
"command": "npx",
"args": ["-y", "copilot-session-sync"]
}
}
}
}
```
**Using global install:**
```json
{
"mcp": {
"servers": {
"copilot-session-sync": {
"command": "copilot-session-sync"
}
}
}
}
```
**Using local build:**
```json
{
"mcp": {
"servers": {
"copilot-session-sync": {
"command": "node",
"args": ["/path/to/copilot-sync/dist/index.js"]
}
}
}
}
```
### GitHub Codespaces
Add the same VS Code configuration to your dotfiles or devcontainer settings. The `npx` approach works out of the box since Node.js is available in Codespaces. Make sure `gh` is authenticated or `GITHUB_TOKEN` is set (Codespaces usually have this automatically).
## MCP Tools
Once configured, these tools are available in Copilot CLI and VS Code Copilot chat:
### `sync_sessions`
Bidirectional sync of all sessions. Compares local and remote by session ID and `updated_at` timestamps. Pushes new/updated local sessions, pulls new/updated remote sessions, and merges the session-store database.
| Parameter | Type | Description |
|-----------|------|-------------|
| `dry_run` | boolean (optional) | Preview what would be synced without making changes |
### `list_remote_sessions`
Lists all sessions (local and remote) with their sync status.
| Parameter | Type | Description |
|-----------|------|-------------|
| `filter` | string (optional) | Filter by summary text or repository name |
Status icons:
- ✅ Synced — session is identical on both sides
- 📤 Local only — session exists locally but not in remote
- 📥 Remote only — session exists in remote but not locally
- ⬆️ Local newer — local version is more recent
- ⬇️ Remote newer — remote version is more recent
### `pull_session`
Pull a specific session from the remote repo to your local machine.
| Parameter | Type | Description |
|-----------|------|-------------|
| `session_id` | string (required) | UUID of the session to pull |
### `push_session`
Push a specific local session to the remote repo.
| Parameter | Type | Description |
|-----------|------|-------------|
| `session_id` | string (required) | UUID of the session to push |
### `sync_status`
Show sync overview — last sync time, which machine last synced, session counts, and what needs syncing.
## Usage Examples
Just talk to Copilot naturally. The MCP tools are invoked automatically based on your request:
```
You: Sync my sessions
→ Calls sync_sessions — pushes 5 new sessions, pulls 2 from remote
You: Show me what sessions need syncing
→ Calls sync_status — shows 3 local-only, 1 remote-only, 42 synced
You: What sessions do I have about drasi?
→ Calls list_remote_sessions with filter "drasi" — shows matching sessions
You: Pull session 03a59c35-d7f8-4e35-8307-beb207d80fb0
→ Calls pull_session — downloads that session from remote
You: Push this session to remote
→ Calls push_session with the current session ID
You: Do a dry run sync first
→ Calls sync_sessions with dry_run=true — previews without changes
```
## Environment Variables
All configuration is optional — the tool auto-detects everything it can.
| Variable | Description | Default |
|----------|-------------|---------|
| `GITHUB_TOKEN` | GitHub personal access token | Falls back to `gh auth token` |
| `GITHUB_USER` | GitHub username | Auto-detected via GitHub API |
| `COPILOT_HOME` | Path to Copilot config directory | `~/.copilot` |
| `COPILOT_SYNC_REPO` | Name of the sync repository | `.copilot` |
## Architecture
### What Gets Synced
```
~/.copilot/
├── session-state/ ← ✅ SYNCED
│ ├── {session-uuid}/
│ │ ├── events.jsonl ← Full conversation events
│ │ ├── workspace.yaml ← Session metadata
│ │ ├── checkpoints/ ← Checkpoint history
│ │ ├── files/ ← Session artifacts
│ │ └── plan.md ← Implementation plans
│ └── {session-uuid}.jsonl ← Legacy event logs
├── session-store.db ← ✅ SYNCED (row-level merge)
├── sync-cache/ ← 🔧 Local clone cache (not synced)
├── config.json ← ❌ NOT synced (machine-specific)
├── permissions-config.json ← ❌ NOT synced
└── logs/ ← ❌ NOT synced
```
### Remote Repository Structure
The private `{username}/.copilot` repo mirrors the synced data:
```
.copilot (private GitHub repo)
├── session-state/ ← Same structure as local
│ ├── {session-uuid}/
│ └── {session-uuid}.jsonl
├── session-store.db ← Merged database
└── manifest.json ← Sync metadata (timestamps, machine IDs)
```
### Sync Mechanics
1. **Clone/pull** the remote `.copilot` repo to `~/.copilot/sync-cache/`
2. **Discover** sessions on both sides by reading `workspace.yaml` files
3. **Compare** by session UUID and `updated_at` timestamp
4. **Copy** session directories (newer side wins)
5. **Merge** `session-store.db` at the row level (INSERT OR REPLACE)
6. **Rebuild** FTS5 search index
7. **Commit and push** changes back to the remote repo
### Security
- The `.copilot` repo is created as **private** — only you can see it
- Authentication reuses your existing GitHub credentials (`gh` CLI or `GITHUB_TOKEN`)
- No data is sent to any third-party service — only to your own GitHub repo
- The sync cache is stored locally at `~/.copilot/sync-cache/`
## Troubleshooting
### "No GitHub token found"
Make sure you're authenticated with the GitHub CLI (`gh auth login`) or have `GITHUB_TOKEN` set in your environment.
### "Could not determine GitHub username"
Set the `GITHUB_USER` environment variable explicitly, or ensure `gh api user` works.
### npx cache issues on Windows
If you get stale cache errors, clear the npx cache:
```powershell
npm cache clean --force
npx -y copilot-session-sync@latest
```
### Large session data
Session data can grow large (especially `events.jsonl` files). The tool syncs everything via git. For very large histories, consider periodically cleaning old sessions you no longer need.
## License
MIT