How to Implement Custom Memory Types Beyond the Built-in Ontology in MCP Memory Service
You can extend the memory taxonomy at runtime by setting the MCP_CUSTOM_MEMORY_TYPES environment variable with a JSON payload defining new base types and subtypes, which the ontology module automatically merges with the built-in taxonomy without modifying source code.
MCP Memory Service uses a formal ontology to classify every stored memory, but you are not limited to the default taxonomy. The doobidoo/mcp-memory-service repository provides a configuration-driven mechanism that lets you define custom memory types for domain-specific needs—such as legal contracts, sales opportunities, or HR records—while maintaining full compatibility with the validation and query APIs.
Understanding the Memory Type Ontology
The service maintains its core taxonomy in src/mcp_memory_service/models/ontology.py. This file defines the static TAXONOMY dictionary that organizes memories into hierarchical base types (like episodic, semantic, or procedural) and their subtypes. When you store or retrieve memories, the system validates the memory_type field against this taxonomy to ensure data consistency and enable filtered queries.
Rather than editing ontology.py directly, the architecture supports runtime extension through environment-based configuration. All downstream components—including the REST API at /api/memories, the Python client, and the internal MemoryService—query a merged view of the taxonomy through cached helper functions like get_all_types() and validate_memory_type(). This means custom types become first-class citizens immediately after configuration.
Configuring Custom Memory Types via Environment Variables
The extension point is the MCP_CUSTOM_MEMORY_TYPES environment variable. Before starting the server, export a JSON object where keys are base type names and values are lists of subtypes.
JSON Structure for Custom Types
The payload must follow the schema {base_type: [subtype, ...]}. You can introduce entirely new base types or extend existing ones by adding subtypes to a base that already exists in the built-in taxonomy.
export MCP_CUSTOM_MEMORY_TYPES='{
"legal": ["contract", "clause", "obligation"],
"sales": ["opportunity", "objection", "competitor"],
"meeting": ["board_meeting"]
}'
In this example, legal and sales are new base types, while meeting extends an existing base with an additional subtype. The system validates the JSON at startup; invalid entries are logged and ignored, ensuring the service always falls back to the safe, built-in ontology.
Runtime Loading and Validation Architecture
The ontology module implements a sophisticated loading and caching system to handle custom types efficiently.
Loading Custom Types from Configuration
The private method _load_custom_types_from_config() in src/mcp_memory_service/models/ontology.py (lines 196–252) reads the MCP_CUSTOM_MEMORY_TYPES environment variable, parses the JSON, and returns a dictionary mapping base types to their subtype lists. This method includes error handling that logs malformed entries without crashing the service, preserving operational stability.
Merging with the Built-in Taxonomy
The method _get_merged_taxonomy() (lines 555–592) starts from the static TAXONOMY dictionary and overlays the custom types. If a custom base type already exists, its subtypes are appended; if it is new, it is added to the hierarchy. The result is cached in memory for fast lookups by validation functions. You can inspect whether custom types are active by checking the startup logs generated by src/mcp_memory_service/config.py (lines 1087–1101), which explicitly reports the presence of custom configuration.
Cache Invalidation Strategies
During testing or dynamic reconfiguration scenarios, you can force a reload by calling clear_ontology_caches() (lines 28–34). This removes the in-memory caches, causing the next validation call to re-execute the merge logic and pick up any changes to the environment variable. The test suite in tests/test_ontology.py uses this mechanism to guarantee test isolation.
Implementation Examples
Environment Setup and Server Startup
Configure the environment variable and start the HTTP server. The custom taxonomy merges automatically during initialization.
export MCP_CUSTOM_MEMORY_TYPES='{
"legal": ["contract", "clause", "obligation"],
"sales": ["opportunity", "objection", "competitor"]
}'
# Optional: clear caches if reloading in a running Python session
python -c "from mcp_memory_service.models import ontology; ontology.clear_ontology_caches()"
# Start the service
memory server --http
Validating Types in Python
Use the MemoryTypeOntology class to verify that custom types are recognized before storing memories.
from mcp_memory_service.models.ontology import MemoryTypeOntology
# Validate custom base types and subtypes
assert MemoryTypeOntology.validate_memory_type("legal") is True
assert MemoryTypeOntology.validate_memory_type("contract") is True
# Verify hierarchy relationships
assert MemoryTypeOntology.get_parent_type("contract") == "legal"
# Retrieve all available types including custom ones
all_types = MemoryTypeOntology.get_all_types()
Querying via REST API
Once configured, you can store and filter memories using custom types through the HTTP interface.
import httpx
async def store_legal_memory():
async with httpx.AsyncClient() as client:
# Store a contract memory
await client.post(
"http://localhost:8000/api/memories",
json={
"content": "NDA signed with Acme Corp.",
"memory_type": "contract"
},
headers={"X-Agent-ID": "legal-team"}
)
# Query by custom base type
response = await client.get(
"http://localhost:8000/api/memories?memory_type=legal"
)
return response.json()
GET /api/memories?memory_type=legal HTTP/1.1
Host: localhost:8000
Authorization: Bearer <token>
Summary
- Configure via environment: Set
MCP_CUSTOM_MEMORY_TYPESwith a JSON object to define new base types and subtypes without editing source code. - Automatic merging: The ontology module merges custom types with the built-in
TAXONOMYat startup, caching results for performance (see_get_merged_taxonomy()insrc/mcp_memory_service/models/ontology.py). - Validation support: All APIs recognize custom types immediately because they use
MemoryTypeOntology.validate_memory_type()and other cached helpers that query the merged view. - Safe fallback: Invalid JSON in the environment variable is logged and ignored, ensuring the service remains operational using the default ontology.
- Cache control: Call
clear_ontology_caches()to force a reload during testing or dynamic reconfiguration scenarios.
Frequently Asked Questions
What happens if I provide invalid JSON in MCP_CUSTOM_MEMORY_TYPES?
The _load_custom_types_from_config() method catches parsing errors and schema violations, logs a warning message, and returns an empty dictionary. The service continues operating with only the built-in taxonomy, ensuring high availability even with configuration mistakes.
Can I extend existing base types like "episodic" or "semantic"?
Yes. When you include a base type name that already exists in the static TAXONOMY, the merger appends your custom subtypes to the existing list. For example, adding "meeting": ["board_meeting"] extends the meeting base type with a new subtype while preserving all original entries.
Do I need to restart the server to add new custom types?
Yes. The environment variable is read once at startup by the ontology initialization logic. To apply new custom types, you must restart the service process. However, if you are using the Python client in a long-running interactive session, you can call clear_ontology_caches() and re-import the module to pick up changes, though a full restart is recommended for production consistency.
How can I verify that my custom types loaded correctly?
Check the startup logs generated by src/mcp_memory_service/config.py (lines 1087–1101), which reports whether custom memory types are present. Additionally, you can programmatically verify by calling MemoryTypeOntology.get_all_types() and confirming your custom base types and subtypes appear in the returned dictionary.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →