Skip to content

Getting Started with AMP

Get a memory server running and store your first memory in under 5 minutes.

Prerequisites: Docker, or Python 3.11+


1. Installation

Docker (recommended)

git clone https://github.com/glatinone/agent-memory-protocol.git
cd agent-memory-protocol/server
docker compose up -d

The server starts on http://localhost:8765. Confirm it's up:

curl http://localhost:8765/amp/v1/health
# {"status":"ok","amp_version":"0.1.0"}

Data is persisted to agent-memory-protocol/server/data/ on your host via the Docker volume.

Without Docker

cd agent-memory-protocol/server
pip install -e .
uvicorn amp_server.main:app --host 0.0.0.0 --port 8765

2. Your first memory

Three commands - create, search, delete.

Create a memory

curl -X POST http://localhost:8765/amp/v1/memories \
  -H "Content-Type: application/json" \
  -d '{
    "type": "semantic",
    "content": {
      "text": "User prefers Python for backend development"
    },
    "identity": {
      "owner_id": "user-123",
      "owner_type": "user",
      "created_by": "my-agent"
    }
  }'

Copy the id from the response - you'll need it in a moment.

{
  "id": "mem_01J5A3B7K9M2N4P6Q8R0S1T3V5",
  "type": "semantic",
  "lifecycle": { "status": "active" },
  ...
}

Search for it

curl -X POST http://localhost:8765/amp/v1/memories/search \
  -H "X-AMP-Agent-ID: my-agent" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "what language does the user prefer?",
    "owner_id": "user-123"
  }'
{
  "results": [
    { "id": "mem_01J5A3B7K9M2N4P6Q8R0S1T3V5", "content": { "text": "User prefers Python for backend development" } }
  ],
  "returned": 1,
  "query": "what language does the user prefer?"
}

Delete it

# a cell has to be archived before it can be deleted; the protocol has no
# "delete it whatever state it is in" step
curl -X PATCH http://localhost:8765/amp/v1/memories/mem_01J5A3B7K9M2N4P6Q8R0S1T3V5 \
  -H "X-AMP-Agent-ID: my-agent" \
  -H "Content-Type: application/json" \
  -d '{"lifecycle": {"status": "archived"}}'

curl -X DELETE http://localhost:8765/amp/v1/memories/mem_01J5A3B7K9M2N4P6Q8R0S1T3V5 \
  -H "X-AMP-Agent-ID: my-agent"
# 204 No Content

Deletion is a soft-delete: lifecycle.status is set to "deleted" and the cell is excluded from future searches. Deleting a cell that is not archived answers 409 INVALID_TRANSITION - the two-step order is deliberate, so a delete cannot race the decay engine.


3. Python quickstart

The official Python SDK client package amp-client makes it easy to integrate AMP into your python-based agents:

pip install amp-client

Use the following quickstart pattern to manage memories with the client:

from amp_client import AMPClient

client = AMPClient("http://localhost:8765", agent_id="my-agent")

# Store a memory
cell = client.remember(
    content="User prefers Python for backend development",
    owner_id="user-123",
    type="semantic"
)
print(cell["id"])

# Search
results = client.recall(
    query="what language does the user prefer?",
    owner_id="user-123"
)
for r in results:
    print(r["content"]["text"])

# Delete
client.forget(cell["id"])

4. Claude Desktop + MCP

AMP includes a Model Context Protocol (MCP) server that exposes memory operations directly to LLM clients. You can configure Claude Desktop to connect to the MCP server by adding it to your claude_desktop_config.json configuration file.

Configuration

Add the following JSON snippet to your claude_desktop_config.json (typically located at %APPDATA%\Claude\claude_desktop_config.json on Windows or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "amp": {
      "command": "python",
      "args": ["-m", "amp_server.mcp_server"],
      "env": {
        "AMP_PERSIST_DIR": "C:\\path\\to\\your\\persistent\\dir",
        "AMP_MCP_AGENT_ID": "claude-desktop"
      }
    }
  }
}

AMP_MCP_AGENT_ID is the agent this MCP server acts as. Set it to something that names the client, and set a different value for each one you run: every access rule is decided from this identity, so a shared value means every MCP client pointed at the same store is the same agent - cells one of them created are readable by the others, and readable_by patterns naming real agent ids never match. Unset, it falls back to mcp_client, which is a shared namespace rather than an identity.

[!IMPORTANT] The command must be run in an environment where the amp-server package (containing the amp_server module) is installed. Ensure your python environment path or active virtual environment is correctly accessible to the command.


5. Choosing an embedding provider

Memory cells are stored as vectors, so something has to turn text into them. By default the server uses the model Chroma ships (a local all-MiniLM-L6-v2), which needs no configuration and no network.

To use a different one, set AMP_EMBEDDING_PROVIDER. The alternative that ships with the server is openai-compatible: it speaks the OpenAI /embeddings API, so it also works with Ollama, LM Studio, vLLM, and any other service that mirrors that shape.

export AMP_EMBEDDING_PROVIDER=openai-compatible
export AMP_EMBEDDING_BASE_URL=http://localhost:11434/v1   # your service
export AMP_EMBEDDING_MODEL=nomic-embed-text
export AMP_EMBEDDING_API_KEY=...        # optional; omit for a local server
export AMP_EMBEDDING_DIMENSIONS=768     # optional; reported at GET /spec

With this provider selected, memory text is sent to that endpoint. That is what choosing it means, and it is why the default stays local.

Two things to know before switching a server that already holds data:

  • Vectors from different models are not comparable. Cells written under the old provider were embedded in a different space, so search stops being meaningful. Use a fresh AMP_PERSIST_DIR, or re-create the cells; re-embedding in place is not automated.
  • An unknown provider name stops the server from starting instead of falling back to the default, so a typo cannot quietly produce vectors nobody can search consistently.

GET /spec reports the provider in use and the width of the vectors it produces.


6. Choosing a storage backend

By default cells live in an embedded Chroma database under AMP_PERSIST_DIR, which suits a single process and a quick start.

For anything else, AMP_STORAGE_BACKEND=postgres keeps cells in PostgreSQL with the pgvector extension, so AMP can sit next to data you already back up and monitor, and more than one server process can share it.

pip install "amp-server[postgres]"          # the optional driver
export AMP_STORAGE_BACKEND=postgres
export AMP_POSTGRES_DSN=postgresql://user:password@localhost:5432/amp

The adapter creates the vector extension, its table and its indexes on start.

With the Compose file in server/, docker compose --profile postgres up -d brings up a Postgres-backed deployment using the pgvector/pgvector:pg16 image.

Both backends are held to the same behaviour, and CI proves it rather than asserting it: a job runs the whole storage contract suite against a real Postgres, including the test that the two backends rank the same data in the same order. GET /spec reports which one is in use under storage_backends.

The embedding-provider rules in step 5 apply to either backend: switching provider invalidates the vectors already stored.


7. Turning on API keys (optional)

By default the server trusts the X-AMP-Agent-ID header, which is what the spec's binding describes: the header names the agent, and every access rule is decided from it. Anyone who can reach the port can therefore claim any agent id.

To require proof, point the server at a key store:

python -m amp_server.auth hash 'the-agent-key'   # prints the value to paste

```json title="api-keys.json" { "agent_assistant": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" }


```bash
export AMP_API_KEYS_FILE=/etc/amp/api-keys.json

Clients then send the key alongside the identity header:

client = AMPClient("http://localhost:8765", "agent_assistant", api_key="the-agent-key")

The file stores digests rather than keys, and a store that cannot be read stops the server rather than falling back to trusting the header. Full detail, including the two rules this changes, is in the API reference.