Getting Started¶
This guide walks you through setting up MGP, starting the reference gateway, and running your first governed memory operations — all in about five minutes.
What you'll learn:
- Install the MGP reference gateway and Python SDK
- Start a local gateway with the in-memory adapter
- Write, search, update, expire, and audit memory objects
- Understand core concepts: memory objects, policy context, adapters, and lifecycle
Prerequisites¶
- Python 3.11+
- Git
1. Clone And Install¶
git clone https://github.com/hkuds/MGP.git
cd MGP
make install
This creates a virtual environment at .venv/ and installs the reference gateway, compliance suite, documentation tooling, and the Python SDK.
If you only want the packaged reference gateway CLI instead of the whole repository toolchain:
python3 -m pip install ./reference
2. Start The Reference Gateway¶
make serve
The gateway starts at http://127.0.0.1:8080 using the in-memory adapter by default. You can verify it is running:
curl http://127.0.0.1:8080/mgp/capabilities
You should see a JSON response containing the backend capabilities, including backend_kind, supported operations, and feature flags. This confirms the gateway is ready.
Alternative run paths:
mgp-gateway --host 127.0.0.1 --port 8080
docker compose up --build
Operational helpers:
GET /healthzGET /readyzGET /version
3. Write Your First Memory¶
Every MGP request requires a policy context that describes who is acting, on whose behalf, and for what purpose. This gives the protocol a stable place to carry governance inputs such as actor, subject, tenant, and request intent. MGP does not define the internal policy engine itself.
Minimum required fields in policy context:
actor_agent— the agent or service performing the actionacting_for_subject— who the action is on behalf ofrequested_action— what operation is being requested
Using cURL¶
curl -X POST http://127.0.0.1:8080/mgp/write \
-H "Content-Type: application/json" \
-d '{
"request_id": "req_001",
"policy_context": {
"actor_agent": "my-agent/v1",
"acting_for_subject": {"kind": "user", "id": "user_alice"},
"requested_action": "write",
"tenant_id": "my_tenant"
},
"payload": {
"memory": {
"memory_id": "mem_001",
"subject": {"kind": "user", "id": "user_alice"},
"scope": "user",
"type": "preference",
"content": {
"statement": "User prefers dark mode.",
"preference_key": "theme",
"preference_value": "dark"
},
"source": {"kind": "human", "ref": "chat:1"},
"sensitivity": "internal",
"created_at": "2026-01-01T00:00:00Z",
"backend_ref": {"tenant_id": "my_tenant"},
"extensions": {}
}
}
}'
Expected response:
{"status": "ok", "request_id": "req_001", ...}
Using the Python SDK¶
from mgp_client import MGPClient, PolicyContextBuilder
context = PolicyContextBuilder(
actor_agent="my-agent/v1",
subject_id="user_alice",
tenant_id="my_tenant",
)
with MGPClient("http://127.0.0.1:8080") as client:
response = client.write_memory(
context.build("write"),
{
"memory_id": "mem_001",
"subject": {"kind": "user", "id": "user_alice"},
"scope": "user",
"type": "preference",
"content": {
"statement": "User prefers dark mode.",
"preference_key": "theme",
"preference_value": "dark",
},
"source": {"kind": "human", "ref": "chat:1"},
"sensitivity": "internal",
"created_at": "2026-01-01T00:00:00Z",
"backend_ref": {"tenant_id": "my_tenant"},
"extensions": {},
},
)
print(response.status) # "ok"
4. Search Memory¶
Now recall what you just wrote. MGP search returns structured results with consumable_text that runtimes can safely inject into prompts.
Using cURL¶
curl -X POST http://127.0.0.1:8080/mgp/search \
-H "Content-Type: application/json" \
-d '{
"request_id": "req_002",
"policy_context": {
"actor_agent": "my-agent/v1",
"acting_for_subject": {"kind": "user", "id": "user_alice"},
"requested_action": "search",
"tenant_id": "my_tenant"
},
"payload": {
"query": "dark mode",
"limit": 10
}
}'
The response contains a results array. Each result item includes the matched memory object, a consumable_text string safe for prompt injection, and a return_mode indicator.
Using the Python SDK¶
from mgp_client import MGPClient, PolicyContextBuilder, SearchQuery
search_context = PolicyContextBuilder(
actor_agent="my-agent/v1",
subject_id="user_alice",
tenant_id="my_tenant",
).build("search")
with MGPClient("http://127.0.0.1:8080") as client:
result = client.search_memory(
search_context,
SearchQuery(query="dark mode", limit=10),
)
for item in result.data.get("results", []):
print(item["consumable_text"])
5. Full Lifecycle Walkthrough¶
The following sequence demonstrates the complete governed memory lifecycle: write, search, get, update, expire, and audit.
from mgp_client import MGPClient, PolicyContextBuilder, SearchQuery, AuditQuery
context = PolicyContextBuilder(
actor_agent="my-agent/v1",
subject_id="user_alice",
tenant_id="my_tenant",
)
with MGPClient("http://127.0.0.1:8080") as client:
# Write a preference
client.write_memory(
context.build("write"),
{
"memory_id": "mem_lifecycle",
"subject": {"kind": "user", "id": "user_alice"},
"scope": "user",
"type": "preference",
"content": {
"statement": "User prefers Python.",
"preference": "Python",
"preference_key": "language",
"preference_value": "python",
},
"source": {"kind": "human", "ref": "chat:2"},
"created_at": "2026-01-01T00:00:00Z",
"backend_ref": {"tenant_id": "my_tenant"},
"extensions": {},
},
)
# Search — should find the preference
results = client.search_memory(
context.build("search"),
SearchQuery(query="python", limit=5),
)
print(f"Search found {len(results.data.get('results', []))} result(s)")
# Get by ID
mem = client.get_memory(context.build("read"), "mem_lifecycle")
print(f"Got memory: {mem.data['memory']['type']}")
# Update the content
client.update_memory(
context.build("update"),
"mem_lifecycle",
{
"content": {
"statement": "User prefers Rust.",
"preference": "Rust",
"preference_key": "language",
"preference_value": "rust",
}
},
)
# Expire the memory
client.expire_memory(
context.build("expire"),
"mem_lifecycle",
reason="user_changed_mind",
)
# Search again — expired memory should not appear
after = client.search_memory(
context.build("search"),
SearchQuery(query="python", limit=5),
)
print(f"After expire: {len(after.data.get('results', []))} result(s)")
# Audit trail — see what happened to this memory
audit = client.query_audit(
context.build("read"),
AuditQuery(target_memory_id="mem_lifecycle", limit=20),
)
for event in audit.data.get("events", []):
print(f" {event['action']} at {event.get('timestamp', 'N/A')}")
Expected console output:
Search found 1 result(s)
Got memory: preference
After expire: 0 result(s)
write at 2026-01-01T00:00:00Z
update at ...
expire at ...
You can also run the bundled end-to-end demo directly:
make serve # in one terminal
./.venv/bin/python examples/e2e_demo.py # in another terminal
Key Concepts¶
Memory Object¶
The canonical unit of governed memory. Every memory object has a subject (who it's about), a scope (how broadly it applies), a type (what kind of memory it is), and structured content.
Policy Context¶
Every request carries a policy context that tells the gateway who is acting, on whose behalf, and under what governance constraints. This enables a stable protocol contract for audit, access control, and policy outcomes, while leaving the concrete policy engine to the implementation.
Adapter¶
An adapter bridges a concrete storage backend into the MGP protocol surface. The repository includes adapters for in-memory, file, graph (SQLite), PostgreSQL, LanceDB, Mem0, and Zep backends. You can write your own by following the Adapter Guide.
Capability¶
Each adapter declares what it can and cannot do through a manifest.json. Runtimes use capability declarations to reason about backend behavior without trial and error.
Lifecycle¶
Memory in MGP is not just CRUD. Objects can be expired, revoked, deleted, or purged — each with distinct governance semantics. Audit trails record every state transition.
A Note On Reference Adapters¶
The in-memory adapter used in this guide (and the file and graph adapters) are reference implementations for protocol verification and learning. They are not intended for production use. For production deployments, build or adopt adapters targeting your actual storage backend — see the Adapter Guide.
Next Steps¶
| Goal | Resource |
|---|---|
| Understand the protocol in depth | Protocol Reference |
| See all JSON schemas | Schema Reference |
| Build your own adapter | Adapter Guide |
| Explore existing adapters | Adapters Overview |
| Use the Python SDK | Python SDK |
| Run compliance tests | Compliance Suite |
| Integrate via sidecar | Sidecar Integration |
| Understand MGP vs MCP | MGP vs MCP |
| Try different backends | make serve with MGP_ADAPTER=file or MGP_ADAPTER=graph |