Skip to main content
Glama
Copilot Memory MCP

Copilot Memory MCP

by auspham

Copilot Memory MCP

Give GitHub Copilot CLI (or any MCP-compatible agent) persistent memory across sessions.

Without this, Copilot CLI starts every session as a blank slate. With this MCP server running, it can save and recall knowledge — learning from experience just like you do.

What It Does

  • Saves memories — fixes, preferences, lessons, code snippets, project context

  • Recalls memories — full-text search across everything it's ever learned

  • Categorizes knowledge — preference, lesson, fix, context, convention, environment, snippet

  • Tracks usage — knows which memories are accessed most often

  • Persists in SQLite — lightweight, no external services, survives restarts

Related MCP server: sill-ensoul

Tools Provided

Memory Tools

Tool

Description

save_memory

Store a new piece of knowledge with category and tags

recall_memories

Search or browse past memories (full-text search)

update_memory

Update an existing memory when things change

forget_memory

Delete a memory that's no longer relevant

memory_stats

See what's in the knowledge base

Monitoring Tools

These solve the "Copilot stops and asks should I continue?" problem. Each tool runs a long-running polling loop internally, so Copilot uses one tool call instead of burning through its iteration limit.

Tool

Description

monitor_command

Run a command repeatedly, collect output, stop on pattern/change/exit code

watch_file

Watch a file for changes or a regex pattern match

poll_url

Poll a URL until expected HTTP status or body pattern

run_long_command

Run a single long command, stream output, stop on pattern

Quick Start

1. Clone and install

git clone <this-repo> ~/projects/copilot-memory-mcp
cd ~/projects/copilot-memory-mcp
uv sync

Or if you don't have uv:

cd ~/projects/copilot-memory-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install "mcp[cli]>=1.20"

2. Test it works

# Quick test — should print tool list
uv run mcp dev server.py

This opens the MCP Inspector in your browser where you can test the tools interactively.

3. Add to GitHub Copilot CLI

Edit (or create) your Copilot MCP config file:

Linux/macOS:

mkdir -p ~/.config/github-copilot
nano ~/.config/github-copilot/mcp.json

Windows:

%LOCALAPPDATA%\github-copilot\mcp.json

Add this content:

{
  "mcpServers": {
    "copilot-memory": {
      "command": "uv",
      "args": ["run", "--directory", "/FULL/PATH/TO/copilot-memory-mcp", "server.py"],
      "env": {}
    }
  }
}

Important: Replace /FULL/PATH/TO/copilot-memory-mcp with the actual absolute path.

If you don't have uv, use the venv Python directly:

{
  "mcpServers": {
    "copilot-memory": {
      "command": "/FULL/PATH/TO/copilot-memory-mcp/.venv/bin/python",
      "args": ["/FULL/PATH/TO/copilot-memory-mcp/server.py"],
      "env": {}
    }
  }
}

Copy the included template to your global Copilot instructions so it knows to USE the memory:

mkdir -p ~/.github
cp copilot-instructions-template.md ~/.github/copilot-instructions.md

Or for a specific repo:

cp copilot-instructions-template.md YOUR_REPO/.github/copilot-instructions.md

5. Use it

Start Copilot CLI normally. It will now have access to memory tools. The instructions file tells it to check memory at session start and save important learnings.

$ copilot

> Hey, can you check what you remember about this project?

# Copilot calls recall_memories() automatically
# and loads any past context

How the Learning Loop Works

Session 1:
  You: "Always use pytest, never unittest"
  Copilot saves: {category: "preference", content: "User prefers pytest over unittest"}

Session 2:
  Copilot starts → calls recall_memories() → loads preference
  Copilot: "I'll set up the tests with pytest as you prefer."
  You debug a tricky async issue together
  Copilot saves: {category: "fix", content: "asyncio.gather swallows exceptions — use return_exceptions=True"}

Session 3:
  Copilot starts → recalls all memories → knows your preferences AND past fixes
  You hit a similar async bug
  Copilot: "This looks like the asyncio.gather issue we fixed before — need return_exceptions=True"

Each session makes the next one smarter.

Monitoring — No More "Should I Continue?"

The monitoring tools solve Copilot CLI's biggest limitation: it stops and asks for confirmation during long-running tasks. These tools do the looping internally.

Example: Watch a Kubernetes deployment

You: "Deploy the new version and monitor until all pods are running"

Copilot runs:
  monitor_command(
    command="kubectl get pods -l app=myapp",
    interval_seconds=10,
    timeout_seconds=300,
    stop_pattern="1/1.*Running"
  )

→ Tool polls every 10s for up to 5 minutes
→ Returns all snapshots when pods are Running
→ ONE tool call, no iteration limit hit

Example: Watch a build log

You: "Start the build and tell me when it's done"

Copilot runs:
  run_long_command(
    command="npm run build 2>&1",
    timeout_seconds=300,
    stop_pattern="Build complete|ERROR"
  )

→ Captures the entire build output
→ Returns immediately when it sees success or failure

Example: Wait for a service to come up

You: "Deploy and let me know when the health check passes"

Copilot runs:
  poll_url(
    url="http://localhost:8080/health",
    expected_status=200,
    expected_body_pattern="healthy",
    interval_seconds=5,
    timeout_seconds=120
  )

→ Polls every 5s until 200 + "healthy" in body
→ Reports back with timing and response details

Max monitoring duration

Default max is 1 hour (3600 seconds). Override with env var:

{
  "mcpServers": {
    "copilot-memory": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/copilot-memory-mcp", "server.py"],
      "env": {
        "COPILOT_MEMORY_MAX_MONITOR": "7200"
      }
    }
  }
}

Configuration

Custom database location

By default, memories are stored in ~/.copilot-memory/memory.db. Override with:

{
  "mcpServers": {
    "copilot-memory": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/copilot-memory-mcp", "server.py"],
      "env": {
        "COPILOT_MEMORY_DB": "/custom/path/to/memory.db"
      }
    }
  }
}

SSE transport (for HTTP-based clients)

uv run server.py --transport sse

This starts an HTTP server (default port 8000) for clients that prefer SSE over stdio.

Works With Other Agents Too

This isn't Copilot-specific. Any MCP client can use it:

  • Claude Code — add to .mcp.json in your project

  • Cline (VS Code) — add to MCP server settings

  • Hermes Agent — add to config.yaml under mcp.servers

  • Cursor — add to MCP configuration

  • Any MCP-compatible tool

Claude Code example (.mcp.json in project root):

{
  "mcpServers": {
    "memory": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/copilot-memory-mcp", "server.py"]
    }
  }
}

File Structure

copilot-memory-mcp/
├── server.py                        # The MCP server (all-in-one)
├── copilot-instructions-template.md # Template to tell Copilot to use memory
├── pyproject.toml                   # Python project config
├── uv.lock                          # Dependency lock file
└── README.md                        # You're reading it

License

MIT — do whatever you want with it.

Available Tools

9 tools
forget_memoryB

Delete a memory that's no longer relevant.

Args:
    memory_id: The ID of the memory to delete.

Inputs: memory_id (required). Returns: result

memory_statsA

Get statistics about stored memories.

Call this to understand what's in your knowledge base.

Inputs: no named parameters. Returns: result

monitor_commandA

Run a shell command repeatedly and collect output over time.

USE THIS instead of running commands in a loop yourself — it handles
the polling so you don't burn through your iteration limit.

Examples:
    - Monitor a build: command="kubectl get pods", stop_pattern="Running"
    - Watch a deploy: command="curl -s http://localhost:8080/health", stop_pattern="ok"
    - Track a job: command="squeue -u $USER", stop_pattern="", stop_on_change=true
    - Wait for completion: command="cat /tmp/job.status", stop_pattern="DONE"

Args:
    command: Shell command to run each interval.
    interval_seconds: Seconds between each run (default 10, min 2).
    timeout_seconds: Max total seconds to monitor (default 300 = 5 min, max 3600).
    stop_pattern: Regex pattern — stop early when output matches this. Leave empty to run until timeout.
    stop_on_change: Stop when output changes from the first run.
    stop_on_exit_code: Stop when command returns this exit code (default -999 = disabled).
    max_snapshots: Max number of output snapshots to keep (default 50). Older ones are dropped.

Inputs: command (required), stop_pattern, max_snapshots, stop_on_change, +3 more. Returns: result

poll_urlA

Poll a URL repeatedly until it returns expected status/content.

Useful for waiting on deployments, health checks, APIs.

Examples:
    - Health check: url="http://localhost:8080/health", expected_body_pattern="healthy"
    - Wait for deploy: url="https://myapp.com/version", expected_body_pattern="v2.1"
    - Wait for service: url="http://localhost:3000", expected_status=200

Args:
    url: URL to poll.
    method: HTTP method (default GET).
    headers: Headers as "Key: Value" lines, newline-separated. Optional.
    expected_status: Stop when this HTTP status is returned (default 200).
    expected_body_pattern: Regex pattern — stop when response body matches. Leave empty to only check status.
    timeout_seconds: Max seconds to poll (default 300, max 3600).
    interval_seconds: Seconds between requests (default 10, min 2).

Inputs: url (required), method, headers, expected_status, +3 more. Returns: result

recall_memoriesA

Search and recall past memories.

Call this at the START of every session to load relevant context,
and whenever you need to remember something from the past.

Args:
    query: Search keywords (uses full-text search). Leave empty to get recent memories.
    category: Filter by category (preference, lesson, fix, context, convention, environment, snippet, general). Leave empty for all.
    limit: Max memories to return (default 20).

Inputs: limit, query, category. Returns: result

run_long_commandA

Run a long-running shell command and capture its full output.

Unlike monitor_command (which re-runs a command repeatedly), this runs
ONE command and streams its output until it finishes or times out.

Use for: builds, installs, database migrations, test suites, any single
command that takes a while.

Examples:
    - Build: command="npm run build", timeout_seconds=300
    - Tests: command="pytest -v", stop_pattern="FAILED|passed"
    - Install: command="apt install -y nginx", timeout_seconds=120

Args:
    command: Shell command to run.
    timeout_seconds: Max seconds to wait (default 600 = 10 min, max 3600).
    tail_lines: Number of output lines to return from the end (default 100).
    stream_check_interval: Seconds between progress checks (default 5).
    stop_pattern: Regex — kill the process early if output matches this.

Inputs: command (required), tail_lines, stop_pattern, timeout_seconds, +1 more. Returns: result

save_memoryA

Save a piece of knowledge to persistent memory.

Call this when you learn something worth remembering:
- User preferences or corrections
- Bug fixes and their root causes
- Project conventions or patterns
- Environment details (OS, tools, versions)
- Code snippets that solved tricky problems
- Decisions and their reasoning

Args:
    content: What to remember. Be specific and concise.
    category: One of: preference, lesson, fix, context, convention, environment, snippet, general
    tags: Comma-separated tags for easier recall (e.g. "python,debugging,asyncio")

Inputs: content (required), tags, category. Returns: result

update_memoryA

Update an existing memory.

Use when a previous memory is outdated or needs correction.

Args:
    memory_id: The ID of the memory to update.
    content: New content (leave empty to keep existing).
    category: New category (leave empty to keep existing).
    tags: New tags (leave empty to keep existing).

Inputs: memory_id (required), tags, content, category. Returns: result

watch_fileA

Watch a file for changes or a specific pattern.

Useful for monitoring log files, build outputs, job status files.

Examples:
    - Watch a log: path="/var/log/app.log", pattern="ERROR|FATAL"
    - Wait for file: path="/tmp/job_done.flag", pattern=""
    - Tail a build log: path="build.log", pattern="BUILD SUCCESS|BUILD FAILURE"

Args:
    path: File path to watch.
    pattern: Regex pattern to stop on when found in the file. Leave empty to stop on any change.
    timeout_seconds: Max seconds to watch (default 300, max 3600).
    interval_seconds: Seconds between checks (default 5, min 2).
    tail_lines: Number of lines from end of file to return (default 50).

Inputs: path (required), pattern, tail_lines, timeout_seconds, +1 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 9 tools

    Disambiguation4/5

    The memory tools (recall, save, update, forget, stats) are clearly distinct, and the monitoring tools (monitor_command, run_long_command, watch_file, poll_url) each target a different mechanism. The only potential confusion is between monitor_command and run_long_command, but their descriptions explicitly differentiate repeated polling from single long-running execution.

    Naming Consistency4/5

    Most tools follow a verb_noun convention (save_memory, update_memory, monitor_command, watch_file, poll_url, run_long_command). Minor deviations include recall_memories (plural noun) and memory_stats (noun_noun), which break the strict pattern but remain predictable and readable.

    Tool Count4/5

    At 9 tools, the count is reasonable and not overwhelming. However, the set mixes two unrelated domains (memory persistence and process/URL monitoring), making the scope feel broader than the server name suggests. Still, no tool is redundant and the number is appropriate for its combined purpose.

    Completeness4/5

    The memory lifecycle is complete with recall, save, update, delete, and stats. The monitoring tools cover common asynchronous scenarios: repeated command polling, single long-running command, file watching, and HTTP polling. Minor gaps exist (e.g., no direct tag-based listing, no explicit 'wait' tool), but agents can work around these.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers