Skip to content
Merged

Dev #13

Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Central Memory MCP Server
[![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/MWGMorningwood/Central-Memory-MCP)](https://archestra.ai/mcp-catalog/mwgmorningwood__central-memory-mcp)

Model Context Protocol (MCP) memory server built with Azure Functions and TypeScript, providing persistent knowledge graph storage for AI assistants in VS Code.
Inspired by and forked from [`@modelcontextprotocol/server-memory`](https://github.com/modelcontextprotocol/servers/tree/main/src/memory)
Expand Down Expand Up @@ -32,31 +33,53 @@ curl http://localhost:7071/api/health

### Example Usage in VS Code Copilot

**Recommended workflow for best results:**

```text
Create an entity:
1. First, check existing data:
#memory-test_read_graph workspaceId="my-project"

2. Search for existing entities:
#memory-test_search_entities workspaceId="my-project" name="Alice"

3. Create entities (auto-updates existing ones):
#memory-test_create_entities workspaceId="my-project" entities={"name": "Alice", "entityType": "Person", "observations": ["Software engineer"]}

Create a relation:
4. Create relationships (auto-creates missing entities):
#memory-test_create_relations workspaceId="my-project" relations={"from": "Alice", "to": "React Project", "relationType": "worksOn"}

Search entities:
#memory-test_search_entities workspaceId="my-project" name="Alice"
5. Add observations (auto-creates entity if missing):
#memory-test_add_observation workspaceId="my-project" entityName="Alice" observation="Leads the frontend team" entityType="Person"
```

**Key Features for Better LLM Usability:**
- ✅ Auto-creation of missing entities when adding observations or relations
- ✅ Helpful error messages with examples when validation fails
- ✅ Workflow guidance to view graph first, then search, then create
- ✅ Clear parameter descriptions with expected formats
- ✅ Reduced friction - tools handle common edge cases automatically

## 🔧 MCP Tools

**Core Operations:**

- `create_entities` - Create single entity with observations
- `create_relations` - Create single relationship between entities
- `read_graph` - Read the entire knowledge graph
- `search_entities` / `search_relations` - Search by name/type
- `add_observation` - Add observations to existing entities
- `read_graph` - **RECOMMENDED FIRST STEP**: View the entire knowledge graph to understand existing data
- `create_entities` - Create entities with auto-update of existing ones
- `create_relations` - Create relationships with auto-creation of missing entities
- `search_entities` / `search_relations` - Search and verify existing data
- `add_observation` - Add observations with auto-creation of missing entities
- `update_entity` - Update entity observations and metadata
- `delete_entity` - Remove entity and all its relations
- `get_stats` - Get workspace statistics
- `clear_memory` - Clear all workspace data

**Recommended Workflow:**
1. Use `read_graph` to understand existing data
2. Use `search_entities` to check for existing entities
3. Use `create_entities` to add new entities
4. Use `create_relations` to connect entities
5. Use `add_observation` to add new information

**Advanced Features:**

- `get_temporal_events` - Time-based activity tracking
Expand Down
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
},
"dependencies": {
"@azure/data-tables": "^13.3.1",
"@azure/functions": "^4.7.3-beta.0",
"@azure/identity": "^4.11.1"
"@azure/functions": "^4.8.0",
"@azure/identity": "^4.12.0"
},
"devDependencies": {
"@types/node": "^24",
Expand Down
51 changes: 28 additions & 23 deletions src/functions/mcpTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getTemporalEvents, detectDuplicateEntities, mergeEntities, executeBatch
// =============================================================================
app.mcpTool('createEntities', {
toolName: 'create_entities',
description: 'Create a new entity in the centralized knowledge graph for a specific workspace',
description: 'Create new entities in the knowledge graph. This is typically the first step when adding new information. Use read_graph first to check if entities already exist. Creates or updates entities with observations.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -22,15 +22,15 @@ app.mcpTool('createEntities', {
{
propertyName: 'entities',
propertyType: 'object',
description: 'Single entity object to create with name, entityType, and observations',
description: 'Entity object with required fields: name (string), entityType (string), observations (array of strings). Example: {"name": "Alice", "entityType": "Person", "observations": ["Software engineer", "Works on React"]}',
},
],
handler: createEntities,
});

app.mcpTool('createRelations', {
toolName: 'create_relations',
description: 'Create a new relation between entities in the knowledge graph for a specific workspace. Supports enhanced features like strength scoring and user attribution.',
description: 'Create relationships between entities in the knowledge graph. Will automatically create any missing entities referenced in the relationship. Use read_graph first to understand existing entities.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -40,15 +40,15 @@ app.mcpTool('createRelations', {
{
propertyName: 'relations',
propertyType: 'object',
description: 'Single relation object to create with from, to, relationType, and optional strength/createdBy',
description: 'Relation object with required fields: from (string), to (string), relationType (string). Optional: strength (0-1). Example: {"from": "Alice", "to": "React Project", "relationType": "worksOn", "strength": 0.9}',
},
],
handler: createRelations,
});

app.mcpTool('readGraph', {
toolName: 'read_graph',
description: 'Read the entire centralized knowledge graph for a specific workspace',
description: 'RECOMMENDED FIRST STEP: Read the entire knowledge graph to understand existing entities and relationships before making changes. Always use this tool first to avoid duplicates and understand the current state.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -61,7 +61,7 @@ app.mcpTool('readGraph', {

app.mcpTool('searchEntities', {
toolName: 'search_entities',
description: 'Search for entities by name or type in a specific workspace',
description: 'Search for existing entities by name or type. Use this to check if entities exist before creating new ones or adding relationships.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -71,20 +71,20 @@ app.mcpTool('searchEntities', {
{
propertyName: 'name',
propertyType: 'string',
description: 'Search by entity name (partial match, optional)',
description: 'Search by entity name (partial match, case-insensitive, optional)',
},
{
propertyName: 'entityType',
propertyType: 'string',
description: 'Search by entity type (partial match, optional)',
description: 'Search by entity type (partial match, case-insensitive, optional)',
},
],
handler: searchEntities,
});

app.mcpTool('searchRelations', {
toolName: 'search_relations',
description: 'Search for relations by entity names or type in a specific workspace',
description: 'Search for existing relationships between entities. Use this to understand how entities are connected before creating new relationships.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -94,25 +94,25 @@ app.mcpTool('searchRelations', {
{
propertyName: 'from',
propertyType: 'string',
description: 'Source entity name (optional)',
description: 'Source entity name (partial match, case-insensitive, optional)',
},
{
propertyName: 'to',
propertyType: 'string',
description: 'Target entity name (optional)',
description: 'Target entity name (partial match, case-insensitive, optional)',
},
{
propertyName: 'relationType',
propertyType: 'string',
description: 'Relation type (partial match, optional)',
description: 'Relation type (partial match, case-insensitive, optional)',
},
],
handler: searchRelations,
});

app.mcpTool('addObservation', {
toolName: 'add_observation',
description: 'Add a new observation to an existing entity in a specific workspace',
description: 'Add a new observation to an existing entity. If entity does not exist, will automatically create it with basic information. IMPORTANT: Use read_graph or search_entities first to check if entity exists.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -122,20 +122,25 @@ app.mcpTool('addObservation', {
{
propertyName: 'entityName',
propertyType: 'string',
description: 'Name of the entity to add observation to',
description: 'Name of the entity to add observation to (required)',
},
{
propertyName: 'observation',
propertyType: 'string',
description: 'Observation content to add',
description: 'Observation content to add (required)',
},
{
propertyName: 'entityType',
propertyType: 'string',
description: 'Entity type to use if creating new entity (optional, defaults to "Unknown")',
},
],
handler: addObservation,
});

app.mcpTool('deleteEntity', {
toolName: 'delete_entity',
description: 'Delete an entity and all its relations from a specific workspace',
description: 'Delete an entity and all its relationships from the workspace. Use search_entities or read_graph first to confirm the entity exists.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -145,15 +150,15 @@ app.mcpTool('deleteEntity', {
{
propertyName: 'entityName',
propertyType: 'string',
description: 'Name of the entity to delete',
description: 'Name of the entity to delete (required)',
},
],
handler: deleteEntity,
});

app.mcpTool('getStats', {
toolName: 'get_stats',
description: 'Get statistics about the centralized knowledge graph for a specific workspace',
description: 'Get statistics about the knowledge graph including entity counts, types, and relationships. Useful for understanding the current state of your workspace.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -166,7 +171,7 @@ app.mcpTool('getStats', {

app.mcpTool('clearMemory', {
toolName: 'clear_memory',
description: 'Clear all memory data for a specific workspace',
description: 'CAUTION: Permanently delete all memory data for a workspace. Use get_stats first to understand what will be deleted.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -179,7 +184,7 @@ app.mcpTool('clearMemory', {

app.mcpTool('updateEntity', {
toolName: 'update_entity',
description: 'Update an existing entity with new observations or metadata',
description: 'Update an existing entity with new observations or metadata. Use this to modify entities found via search_entities or read_graph.',
toolProperties: [
{
propertyName: 'workspaceId',
Expand All @@ -189,17 +194,17 @@ app.mcpTool('updateEntity', {
{
propertyName: 'entityName',
propertyType: 'string',
description: 'Name of the entity to update',
description: 'Name of the entity to update (required)',
},
{
propertyName: 'newObservations',
propertyType: 'object',
description: 'Single observation object to add to the entity',
description: 'Single observation string or array of observation strings to add to the entity (optional)',
},
{
propertyName: 'metadata',
propertyType: 'object',
description: 'Object containing metadata fields to update',
description: 'Object containing metadata fields to update (optional)',
},
],
handler: updateEntity,
Expand Down
Loading