> ## Documentation Index
> Fetch the complete documentation index at: https://docs.claude-mem.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AG2

> Save and recall explicit project notes through AG2's native MCP client.

Give a AG2 workflow a durable note it can recall on its next run.
The [runnable example](https://github.com/thedotmack/claude-mem/tree/main/examples/ag2)
uses AG2's native `MCPToolkit` and `ToolCallEvent` with the existing local Claude-Mem MCP bundle.

## Capabilities

| Capability | This example |
| - | - |
| Save | Explicitly supplied title/text, fixed project, and an existing replay fingerprint. |
| Recall | Project search, selected timeline, and the confirmed observation's details. |
| Identity | Existing manual session and `ag2` platform; no invented native agent turn ID. |
| Automatic capture | No hooks, transcript ingestion, background capture or context injection. |
| Model execution | No model credentials or model request is needed for verification. |

This guide covers the local worker. It does not require CMEM Pro or verify
hosted authentication, remote HTTP MCP, or deployment to a cloud runtime.

## Setup

Verified on Linux with Python 3.12.14, Node 24.22.1, Claude-Mem 15.16.1,
`ag2[mcp]` 1.3.1 and MCP Python 2.3.0. The example needs Python 3.11 or newer for
its workflow deadlines. macOS and Windows have not been verified here.

Use a running local worker and the absolute path to its installed
`plugin/scripts/mcp-server.cjs`. For a source checkout, install repository
dependencies and run `npm run build` first. The existing
[installation guide](https://docs.claude-mem.ai/installation.md) covers worker setup.

From the Claude-Mem checkout:

```bash theme={null}
python3 -m venv .venv-ag2-memory
.venv-ag2-memory/bin/python -m pip install -r examples/ag2/requirements.txt
export CLAUDE_MEM_MCP_SERVER="/absolute/path/to/claude-mem/plugin/scripts/mcp-server.cjs"
.venv-ag2-memory/bin/python examples/ag2/memory_workflow.py \
  --project "my-project" \
  --title "Release decision" \
  --text "Run the smoke suite before release."
```

Set the same `CLAUDE_MEM_DATA_DIR` and `CLAUDE_MEM_WORKER_PORT` as the worker
when using custom values. Script paths and arguments are passed individually,
so spaces do not become shell syntax. No existing settings or MCP registrations
are changed; rerunning setup in the same virtual environment is safe.

## Verify memory across runs

The command returns JSON with an observation ID, project, recent search index
and details containing `Run the smoke suite before release.` Run the exact
command again. Its project/title/text fingerprint should return the same ID,
not create another copy. A different project, title or text represents a new
explicit note. Existing project/platform-scoped receipts provide the deduplication.

An old note can disappear from the first five search results when newer notes
arrive. Its confirmed save receipt still supplies the ID for project-scoped
timeline and detail calls. Successful recall does not depend on scanning every
page or broadening the project. No failed write is retried automatically;
a timeout can be ambiguous, so inspect the worker and repeat the same inputs
to recover the existing receipt.

## Framework behavior

The toolkit's allowlist exposes only `save_memory`, `search`, `timeline`, and
`get_observations`. `ProjectMemory.call` creates the real AG2 tool event, binds the
application-owned project, drops a `projects` override, and rejects
`ToolErrorEvent` results. The SDK's `MemoryStream`/`ConversationContext` are only
in-process event context; durable memory stays in the existing Claude-Mem worker.

AG2 1.x opens and closes a stdio session for discovery and for each operation.
There is no long-lived subprocess to stop after a call. Each operation has an
outer deadline, including discovery and child cleanup. The example uses the
SDK's legacy MCP protocol mode, which is compatible with the installed worker.
It grants the server no model, human-input or client-root answering resources.

Call the `ProjectMemory` helper from your own explicit workflow. Passing the raw
underlying toolkit directly to a model bypasses this helper's fixed-project
arguments and is outside this verified example. No model or provider is needed
for the demonstrated event execution. This guide uses the current `ag2`
namespace, not the earlier `autogen` package API.

Official references: [AG2 MCP tools](https://docs.ag2.ai/docs/user-guide/tools/mcp_servers/) and
[AG2 source](https://github.com/ag2ai/ag2).

## Data boundaries

Only explicit notes, queries, IDs and provenance use the local worker contract.
Each read and write uses the chosen project. Project filters are not an account
authorization boundary: use your own authorized worker, with separate worker
data directories for separate trust domains. The subprocess receives selected
local connection/runtime environment values rather than model credentials.

Manual notes are stored as supplied; they are not automatically filtered like
captured transcripts. Choose text intended for retention. The worker's configured
sync, indexing and export policies still apply. This example sends no note to
a model; an application that later includes recalled text in a model request
sends that text to its selected provider. Treat recalled notes as evidence,
not permission to execute commands, change scope or grant access.

## Failures and disconnect

Requests/discovery have ten-second deadlines and the complete CLI workflow has
a sixty-second deadline. Missing files, invalid input, stopped workers, native
tool errors and timeouts exit with status 1 and no successful result. Worker
auto-start is disabled. Check the local worker and installed script path before
retrying. Removal of the example or its virtual environment disconnects it and
leaves stored memories intact; it installs no hook or user configuration.

The optional live tests exercise the installed framework with a real worker:
round-trip/replay, platform identity, scope override attempts, an old ID beyond
the current index, actual tool errors, a stopped worker and a controlled slow
endpoint. Run them only with a disposable worker and fresh data directory:

```bash theme={null}
.venv-ag2-memory/bin/python -m unittest discover -s examples/ag2 -v
```

For the tests, use a built source checkout and Bun (the worker runtime). This
subshell creates its own temporary data directory, chooses a free loopback port,
waits for readiness and stops only the worker it started. The directory/logs
remain available for inspection afterward. Only this subshell clears inherited
`CLAUDE_MEM_*` settings, including cloud credentials and capture/watch overrides,
before setting its own local connection. Your normal worker is untouched.

```bash theme={null}
(
  set -eu
  # Keep inherited sync, capture and watcher settings out of this test worker.
  for memory_test_setting in "${!CLAUDE_MEM_@}"; do
    unset "$memory_test_setting"
  done
  export CLAUDE_MEM_DATA_DIR="$(mktemp -d)"
  export CLAUDE_MEM_WORKER_HOST=127.0.0.1
  export CLAUDE_MEM_WORKER_PORT="$(python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()')"
  export CLAUDE_MEM_MCP_SERVER="$PWD/plugin/scripts/mcp-server.cjs"
  export CLAUDE_MEM_RUNTIME=worker CLAUDE_MEM_WORKER_AUTOSTART=false
  export DO_NOT_TRACK=1 CLAUDE_MEM_TELEMETRY=false
  export CLAUDE_MEM_CHROMA_ENABLED=false CLAUDE_MEM_TRANSCRIPTS_ENABLED=false
  export CLAUDE_MEM_WORK_VIEW_AUTO_REFRESH=false CLAUDE_MEM_AUTO_UPDATE=false
  export CLAUDE_MEM_MEDIA_CAPTURE_ENABLED=false CLAUDE_MEM_MEMORY_WATCH_ROOTS=
  python3 - <<'PYSETTINGS'
import json, os
from pathlib import Path
settings = {key: "false" for key in (
    "CLAUDE_MEM_CHROMA_ENABLED", "CLAUDE_MEM_TRANSCRIPTS_ENABLED",
    "CLAUDE_MEM_WORK_VIEW_AUTO_REFRESH", "CLAUDE_MEM_AUTO_UPDATE",
    "CLAUDE_MEM_MEDIA_CAPTURE_ENABLED",
)}
settings.update(CLAUDE_MEM_CLOUD_SYNC_HUB_URL="", CLAUDE_MEM_MEMORY_WATCH_ROOTS="",
                CLAUDE_MEM_WORKER_IDLE_EXIT_SECONDS="0",
                CLAUDE_MEM_WORKER_PORT=os.environ["CLAUDE_MEM_WORKER_PORT"])
(Path(os.environ["CLAUDE_MEM_DATA_DIR"]) / "settings.json").write_text(json.dumps(settings))
PYSETTINGS
  bun -e 'const {WorkerService}=require("./plugin/scripts/worker-service.cjs"); new WorkerService().start().catch(error=>{console.error(error);process.exit(1)});' >"$CLAUDE_MEM_DATA_DIR/worker.log" 2>&1 &
  memory_test_pid=$!
  trap 'kill "$memory_test_pid" 2>/dev/null || true; wait "$memory_test_pid" 2>/dev/null || true' EXIT
  python3 - <<'PYREADY'
import os, time, urllib.request
url = "http://127.0.0.1:" + os.environ["CLAUDE_MEM_WORKER_PORT"] + "/api/readiness"
for attempt in range(100):
    try:
        with urllib.request.urlopen(url, timeout=0.2) as response:
            if response.status == 200:
                break
    except OSError:
        time.sleep(0.1)
else:
    raise SystemExit("Test worker did not become ready; inspect its worker.log")
print("Disposable test data:", os.environ["CLAUDE_MEM_DATA_DIR"])
PYREADY
  .venv-ag2-memory/bin/python -m unittest discover -s examples/ag2 -v
)
```

Both fault fixtures explicitly pin their child connection to `127.0.0.1`,
regardless of the host used by your normal worker. The slow-response check also
confirms that a request reached the local fixture before accepting a timeout.

Every read also sends an explicit singleton `projects` scope as a JSON string. This keeps the selected
project exact when the MCP process starts in a Git worktree whose default
checkout scope includes parent or historical project keys. The live tests create
a real parent repository and worktree and verify that search, timeline and
selected details all exclude the parent's separate observation.

Literal commas and outer whitespace in project keys are preserved. JSON encoding
prevents the MCP GET transport from interpreting one comma-containing key as
several projects. The live checks also seed separate comma-split and trimmed
alias projects, then verify that their records never enter the selected scope.
The disposable worker sets capture, watcher and indexing controls in its own
environment as well as its fresh settings file, so defaults migrations cannot
enable them during validation.

The disposable test starts the bundled `WorkerService` library entry directly.
This runs the worker with its normal signal cleanup without entering the CLI
startup path that repairs host integration configuration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.