# How the X-Agent-ID Header Enables Agent-Scoped Memory Retrieval in MCP Memory Service

> Discover how the X-Agent-ID header in MCP Memory Service creates agent-scoped memory retrieval automatically injecting a namespace tag for isolated data access.

- Repository: [Henry/mcp-memory-service](https://github.com/doobidoo/mcp-memory-service)
- Tags: how-to-guide
- Published: 2026-02-28

---

**The X-Agent-ID header automatically injects an `agent:<id>` namespace tag into memory records, enabling isolated retrieval per agent without manual tag management.**

The MCP Memory Service provides a lightweight mechanism for multi-agent systems to maintain isolated memory contexts. By leveraging the `X-Agent-ID` HTTP header, developers can scope memories to specific agents during ingestion, ensuring that retrieval operations return only relevant results for that agent identity.

## Understanding Agent-Scoped Memory Isolation

In multi-agent architectures, preventing cross-contamination of memories between different agent instances is critical. The MCP Memory Service solves this through **namespace-based tagging** rather than separate databases or complex access control lists. When a memory is stored with an agent identifier, the service automatically prefixes it with the `agent:` namespace defined in the global tag taxonomy.

This approach allows the existing tag-based indexing system to handle agent isolation transparently. Because the storage layer treats all tags uniformly, agent-scoped memories benefit from the same semantic search and temporal filtering capabilities as unscoped memories.

## How X-Agent-ID Works Under the Hood

### Header Detection in the API Layer

When a `POST /api/memories` request arrives, the API handler in [`src/mcp_memory_service/web/api/memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/web/api/memories.py) extracts the header value before processing the request body:

```python
agent_id = http_request.headers.get('X-Agent-ID')

```

(see [`src/mcp_memory_service/web/api/memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/web/api/memories.py) lines 158-159)

If the header is present, the service proceeds to namespace the identifier; if absent, the memory is stored without agent scoping, making it globally accessible within the user's namespace.

### Automatic Namespace Tagging

The service constructs the agent tag using the `NAMESPACE_AGENT` constant defined in the tag taxonomy model. In [`src/mcp_memory_service/models/tag_taxonomy.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/models/tag_taxonomy.py) line 29, the namespace is defined as:

```python
NAMESPACE_AGENT = "agent:"

```

The API handler concatenates this prefix with the header value to create the final tag:

```python
agent_tag = f"agent:{agent_id}"

```

This tag is then appended to the list of tags provided in the request payload, ensuring the memory carries the agent identifier without overwriting user-defined tags.

### Deduplication Safety

To prevent duplicate tags if the caller manually included the agent identifier, the handler checks for existing entries before appending:

```python
if agent_tag not in tags:
    tags.append(agent_tag)

```

(see [`src/mcp_memory_service/web/api/memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/web/api/memories.py) lines 162-164)

This guarantees a single authoritative tag per memory record, maintaining clean indexing and preventing search anomalies caused by redundant identical tags.

## Practical Implementation Examples

### Store a Memory with Agent Scoping via cURL

The following request stores a memory and automatically tags it with `agent:researcher`:

```bash
curl -X POST http://localhost:8000/api/memories \
  -H "Content-Type: application/json" \
  -H "X-Agent-ID: researcher" \
  -d '{"content":"Deadline is March 15","tags":["project","deadline"]}'

```

The server appends `agent:researcher` to the stored tags, making this memory retrievable only when filtering for that specific agent.

### Store a Memory Using Python httpx

For programmatic access, use the header in your HTTP client:

```python
import httpx

response = httpx.post(
    "http://localhost:8000/api/memories",
    json={"content": "API limit is 100 req/min", "tags": ["api", "rate-limit"]},
    headers={"X-Agent-ID": "researcher"},
)
print(response.json()["memory"]["tags"])

# → ["api", "rate-limit", "agent:researcher"]

```

### Retrieve Agent-Scoped Memories

To query memories for a specific agent, include the agent tag in the search filter:

```bash
curl -X POST http://localhost:8000/api/memories/search \
  -H "Content-Type: application/json" \
  -d '{"query":"API limits","tags":["agent:researcher"]}'

```

Only memories tagged with `agent:researcher` are returned, effectively isolating this agent's context from other agents in the system.

### Explicit Tagging Without the Header

You can achieve identical results by manually including the agent tag in the payload, though this requires knowledge of the namespace format:

```python
await store_memory(
    content="...", 
    tags=["api", "agent:researcher"]
)

```

Both approaches yield identical stored memories; the header simply automates the namespace formatting and appends it safely.

## Summary

- The **X-Agent-ID header** triggers automatic injection of an `agent:<id>` tag during memory creation in [`src/mcp_memory_service/web/api/memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/web/api/memories.py).
- Agent isolation relies on the **tag taxonomy namespace** defined in [`src/mcp_memory_service/models/tag_taxonomy.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/models/tag_taxonomy.py), ensuring consistent formatting across the storage layer.
- The mechanism includes **deduplication logic** to prevent redundant tags when callers manually specify agent identifiers.
- Retrieval uses standard tag filtering, making agent-scoped memories accessible through any search endpoint by including the `agent:<id>` tag in the query parameters.

## Frequently Asked Questions

### What is the X-Agent-ID header in MCP Memory Service?

The **X-Agent-ID** header is an HTTP request header that identifies the agent instance making a memory storage request. When present, the MCP Memory Service automatically converts this value into an `agent:<id>` namespace tag, binding the memory record to that specific agent identity without requiring manual tag management in the request payload.

### How does agent-scoped retrieval work without the X-Agent-ID header?

If the **X-Agent-ID** header is omitted during storage, the memory is saved with only the user-provided tags, making it accessible to any query within the user's namespace. To restrict retrieval without the header, you must manually include the `agent:<id>` tag in the storage payload and subsequently filter by that same tag during search operations.

### Can I use multiple agent tags on a single memory?

Yes, the MCP Memory Service supports multiple tags per memory record, including multiple agent identifiers. However, the **X-Agent-ID** header processing in [`memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/memories.py) specifically checks for duplicates to prevent adding the same agent tag twice. If you need to associate a memory with multiple agents, you can manually append additional `agent:<id>` tags to the request payload.

### Where is the agent namespace defined in the codebase?

The agent namespace is defined as a constant in [`src/mcp_memory_service/models/tag_taxonomy.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/models/tag_taxonomy.py) at line 29, where `NAMESPACE_AGENT = "agent:"` is declared. This constant ensures consistent formatting across the service, and the API handler in [`src/mcp_memory_service/web/api/memories.py`](https://github.com/doobidoo/mcp-memory-service/blob/main/src/mcp_memory_service/web/api/memories.py) references this pattern when constructing the `agent_tag = f"agent:{agent_id}"` string during header processing.