Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
SEP-2072: Memory Portals - Portable Context Storage with chDB
Abstract
This SEP proposes Memory Portals, an MCP extension that enables servers to expose persistent, portable context storage using chDB embedded databases. Memory Portals provide a standardized way to store and retrieve conversation context, tool outputs, and user data in portable
.dbfiles that can be shared across different MCP hosts and tools. The extension introduces themem://URI scheme for declaring memory resources and integrates with MCP Apps (SEP-1865) to provide interactive user interfaces for viewing, managing, importing, and deleting stored data.Motivation
Current MCP implementations lack a standardized approach for persistent context storage. While servers can maintain in-memory state during a session, there is no protocol-level mechanism for:
This leads to several problems:
Memory Portals addresses these issues by providing a standardized, portable, and user-controllable storage layer built on chDB, an embedded SQL database that produces single-file databases compatible with ClickHouse format.
Why chDB?
chDB was chosen for several key reasons:
.dbfile that can be easily copied, shared, or backed upSpecification
Memory Portal Resources
Memory Portals are exposed as MCP resources using the
mem://URI scheme.Resource Declaration
Servers declare memory portal resources during initialization:
{ "uri": "mem://conversation/default", "name": "Default Conversation Memory", "description": "Stores conversation history and context", "mimeType": "application/vnd.mcp.memory+json", "_meta": { "memory": { "dbPath": "/path/to/conversation.db", "schema": { "tables": [ { "name": "messages", "columns": [ { "name": "id", "type": "UUID", "primary": true }, { "name": "timestamp", "type": "DateTime64(3)" }, { "name": "role", "type": "String" }, { "name": "content", "type": "String" }, { "name": "tool_calls", "type": "Array(String)" } ] } ] }, "viewerUri": "ui://memory/viewer" } } }URI Scheme
The
mem://URI follows this structure:Examples:
mem://conversation/default- Root portal referencemem://conversation/default/messages- Specific tablemem://conversation/default/messages?since=2024-01-01- Filtered queryResource Reading
When a client requests a memory portal resource via
resources/read, the server returns:{ "contents": [ { "uri": "mem://conversation/default", "mimeType": "application/vnd.mcp.memory+json", "text": "{\"schema\": {...}, \"stats\": {...}, \"dbPath\": \"...\"}" } ] }For table-specific queries:
{ "contents": [ { "uri": "mem://conversation/default/messages?limit=10", "mimeType": "application/json", "text": "[{\"id\": \"...\", \"timestamp\": \"...\", \"content\": \"...\"}]" } ] }Memory Portal Tools
Servers implementing Memory Portals should provide standard tools for data manipulation:
memory/writeWrites data to a memory portal:
{ "name": "memory/write", "description": "Write data to a memory portal", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI of the portal" }, "table": { "type": "string", "description": "Target table name" }, "data": { "type": "array", "description": "Array of records to insert", "items": { "type": "object" } } }, "required": ["portalUri", "table", "data"] } }memory/queryQueries a memory portal with SQL:
{ "name": "memory/query", "description": "Query a memory portal using SQL", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI of the portal" }, "sql": { "type": "string", "description": "SQL query to execute (SELECT only)" }, "parameters": { "type": "object", "description": "Query parameters for prepared statements" } }, "required": ["portalUri", "sql"] } }memory/deleteDeletes data from a memory portal:
{ "name": "memory/delete", "description": "Delete data from a memory portal", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI of the portal" }, "table": { "type": "string", "description": "Table to delete from" }, "where": { "type": "object", "description": "Conditions for deletion" } }, "required": ["portalUri", "table"] } }memory/importImports data from external sources:
{ "name": "memory/import", "description": "Import data into a memory portal", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI of the portal" }, "source": { "type": "string", "description": "Source file path or URL" }, "format": { "type": "string", "enum": ["json", "csv", "parquet", "db"], "description": "Source data format" }, "mapping": { "type": "object", "description": "Column mapping configuration" } }, "required": ["portalUri", "source", "format"] } }memory/exportExports portal data:
{ "name": "memory/export", "description": "Export data from a memory portal", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI of the portal" }, "destination": { "type": "string", "description": "Export destination path" }, "format": { "type": "string", "enum": ["json", "csv", "parquet", "db"], "description": "Export format" }, "query": { "type": "string", "description": "Optional SQL query to filter exported data" } }, "required": ["portalUri", "destination", "format"] } }Integration with MCP Apps (SEP-1865)
Memory Portals integrate with MCP Apps to provide interactive viewing and management interfaces.
UI Resource Declaration
Servers should declare UI resources for memory portal viewers:
{ "uri": "ui://memory/viewer", "name": "Memory Portal Viewer", "description": "Interactive interface for viewing and managing memory portals", "mimeType": "text/html+mcp" }Tool-UI Linking
Memory portal tools can reference UI resources:
{ "name": "memory/view", "description": "Open interactive viewer for a memory portal", "inputSchema": { "type": "object", "properties": { "portalUri": { "type": "string", "description": "mem:// URI to open" } }, "required": ["portalUri"] }, "_meta": { "ui/resourceUri": "ui://memory/viewer", "ui/params": { "portalUri": "{{portalUri}}" } } }Viewer Capabilities
The interactive viewer should support:
The viewer communicates with the host using MCP JSON-RPC over
postMessage, calling memory portal tools as needed.Portability Specification
File Format
Memory Portal
.dbfiles use the chDB/ClickHouse format, which:Metadata Storage
Each
.dbfile should include a_mcp_metadatatable:Standard metadata keys:
mcp.version- MCP protocol versionmcp.portal.id- Portal identifiermcp.portal.name- Human-readable namemcp.portal.description- Portal descriptionmcp.server.name- Creating server namemcp.server.version- Creating server versionmcp.created_at- Creation timestampmcp.schema_version- Schema version for migrationsPortability Guidelines
To ensure maximum portability:
Rationale
Why chDB Over Alternatives?
Several embedded database options were considered:
SQLite:
DuckDB:
chDB (chosen):
chDB was selected because MCP contexts often involve analytical queries (searching conversation history, aggregating tool outputs) where columnar storage excels, and the ClickHouse compatibility provides a rich ecosystem.
URI Scheme Design
The
mem://scheme was chosen to:ui://: Consistent with MCP Apps extension patternsAlternative schemes considered:
mcp-memory://- Too verbosedb://- Too generic, conflicts with database connection URIscontext://- Too vague, doesn't convey persistenceIntegration with MCP Apps
Rather than defining a custom UI protocol, Memory Portals leverages SEP-1865 (MCP Apps) for interactive interfaces. This provides:
Standard Tool Set
The defined tools (
memory/write,memory/query, etc.) provide a consistent API while allowing servers flexibility in implementation. This enables:Backward Compatibility
Memory Portals is an optional extension. Existing MCP implementations continue working without changes.
For MCP Hosts
Hosts that don't implement Memory Portals:
mem://resources during resource listingHosts can adopt Memory Portals incrementally:
For MCP Servers
Servers that don't implement Memory Portals:
Servers implementing Memory Portals should:
Migration Path
For existing servers with custom storage:
Reference Implementation
A reference implementation is planned with the following components:
Server SDK (
@mcp/memory-portals)TypeScript SDK providing:
MemoryPortalclass for creating and managing portalschDBAdapterfor database operationsExample Server
A demonstration server showcasing:
Documentation
Implementation repository:
https://github.com/modelcontextprotocol/ext-memory-portals(TBD)Alternatives Considered
Server-Side Storage Only
Keep storage implementation-specific, no protocol standardization.
Rejected because:
File-Based Resources
Use
file://URIs to reference database files directly.Rejected because:
REST API Extension
Add HTTP endpoints for database operations.
Rejected because:
Vector Database Focus
Use vector stores (Pinecone, Weaviate) instead of SQL.
Rejected because:
In-Memory Only with Snapshots
Keep data in memory, provide snapshot export.
Rejected because:
Open Questions
Schema Evolution: How should schema migrations be handled when portals are shared between servers with different schema versions?
Multi-Portal Queries: Should there be a way to query across multiple memory portals in a single operation?
Replication: Should the spec define portal replication/sync mechanisms for distributed scenarios?
Access Control Model: Should portals support fine-grained permissions (row-level, column-level)?
Compression Codecs: Should specific compression algorithms be recommended or required?
Binary Data: How should large binary objects (images, files) be stored in portals?
Full-Text Search: Should full-text search capabilities be part of the core spec or an optional extension?
Encryption: Should at-rest encryption be mandatory, optional, or out-of-scope?
Version Control: Should portals support version history/time-travel queries?
Federation: Should there be a discovery mechanism for portals available across multiple servers?
Acknowledgments
This proposal builds on:
Special thanks to the MCP maintainers and community members who provided feedback during the drafting of this specification.