A powerful snippet manager that organizes code through intelligent hierarchical metadata, enabling semantic search and multilingual code organization.
- MSM (Metadata Snippet Manager)
This project is distributed under the MIT License. See the LICENSE
file for details.
MSM is an MCP (Model Context Protocol) server that provides intelligent code snippet management through semantic metadata organization. Unlike traditional snippet managers that rely on file names or folders, MSM uses a graph-based metadata system to enable:
- Semantic search: Find snippets by concepts (e.g., "recursive sorting algorithms")
- Hierarchical organization: Metadata organized in meaningful parent-child relationships
- Multilingual support: Create metadata in any language, search with variants and synonyms
- Cross-language translations: Maintain algorithm implementations across multiple programming languages
- Author tracking: Organize snippets by creator
The system is designed to work seamlessly with AI assistants (Claude, Copilot, etc.) that can intelligently navigate the metadata hierarchy and suggest appropriate classifications.
- Graph-based metadata hierarchy: Organize concepts from general to specific
- Two metadata categories:
concept
: Abstract ideas (algorithm, sorting, recursion)language
: Language constructs (class, interface, async/await)
- Smart search strategies: Progressive search with fallback from specific to general
- Translation management: Link implementations of the same algorithm across languages
- Flexible queries: Search by exact match, subset (AND), or intersection (OR)
- Author attribution: Track snippet creators and filter by author
- Batch operations: Create entire metadata hierarchies in single operations
- Database: Neo4j (graph database) for metadata relationships
- API: Node.js MCP server with stdio/http modes
- Protocol: Model Context Protocol for AI assistant integration
- Storage: Snippets stored with content, metadata links, and translations
Create a .env
file in the project root:
# Neo4j Configuration
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
# Local use (when DB runs on host)
NEO4J_URI=bolt://localhost:7687
# Docker use (when app runs inside Docker)
# NEO4J_URI=bolt://neo4j:7687
# Server Configuration
PORT=3002
Note: Switch NEO4J_URI
based on deployment mode (local vs Docker).
- Clone and setup:
git clone <repo-url>
cd <repo-dir>
- Start Neo4j database:
docker compose -f docker-compose.local.yml up -d
- Build and run application:
npm install
npm run build
node dist/index.js stdio # For MCP client integration
# or
node dist/index.js http # For HTTP API
- Stop services:
# Stop app: Ctrl+C
docker compose -f docker-compose.local.yml down
-
Configure for Docker: Edit
.env
to useNEO4J_URI=bolt://neo4j:7687
-
Build and start:
docker compose build
docker compose up -d
- Stop everything:
docker compose down
MSM implements the Model Context Protocol, allowing AI assistants to interact with the snippet manager through standardized tool calls.
- Claude Desktop (recommended)
- VSCode Copilot
- VSCode Continue
- Any MCP-compatible client
Claude Desktop (claude_desktop_config.json
):
{
"mcpServers": {
"msm": {
"command": "node",
"args": ["/absolute/path/to/msm/dist/index.js", "stdio"]
}
}
}
VSCode Continue (.continue/config.json
):
{
"mcpServers": [
{
"name": "msm",
"command": "node",
"args": ["/absolute/path/to/msm/dist/index.js", "stdio"]
}
]
}
Important: You may need to manually add the instructions.md
file content to your AI assistant's system prompt for optimal behavior. This file contains detailed guidelines for metadata management, search strategies, and best practices.
-
concept: Abstract, language-independent concepts
- Examples:
algorithm
,sorting
,recursion
,tree
,graph
- Transversal across programming languages
- Examples:
-
language: Language-specific constructs
- Examples:
class
,async
,decorator
,generic
,lambda
- The programming language itself (Java, Python) is identified by file extension, NOT metadata
- Examples:
Metadata forms parent-child trees:
algorithm
├── sorting
│ ├── quicksort
│ ├── mergesort
│ └── bubblesort
├── search
│ ├── binary
│ └── linear
└── graph
├── traversal
└── shortest_path
Snippets can have translations in different programming languages:
- Original snippet:
quicksort.py
(Python implementation) - Translations:
quicksort.py
→ Java translationquicksort.py
→ C++ translationquicksort.py
→ TypeScript translation
All translations share the same metadata and are searchable together.
Creation:
create_metadata_tree
: Create entire hierarchies at oncecreate_metadata_subtree
: Add branches to existing metadatacreate_metadata_forest
: Create multiple independent trees
Navigation:
get_metadata_tree
: Retrieve metadata and descendantsget_metadata_forest
: Search multiple metadata by name (with language variants)get_metadata_siblings
: Find related concepts at same levelget_metadata_siblings_forest
: Get siblings with their subtreesget_metadata_path
: Get hierarchical path from root to metadataget_whole_metadata_forest
: Retrieve entire metadata database (expensive)
Modification:
rename_metadata
: Change metadata name (preserves all relationships)add_metadata_parent
: Connect metadata to create relationshipsprune_metadata_branch
: Separate metadata from parentdelete_metadata
: Remove metadata (cascades to relationships)
Creation:
create_snippet
: Create new snippet with metadatacreate_snippet_translation
: Add language translation of existing snippet
Modification:
update_snippet_content
: Update snippet codeupdate_snippet_metadata
: Change snippet's metadata associationsupdate_snippet_translation
: Update translation content
Deletion:
delete_snippets
: Remove snippets (cascades to translations)delete_snippet_translation
: Remove specific language translation
By Name:
search_snippet_by_name
: Find snippet by exact name
By Metadata:
get_snippets_by_metadata_subset
: Find snippets with ALL specified metadata (AND logic)get_snippets_by_metadata_intersection
: Find snippets with ANY metadata (OR logic)
Translations:
get_snippet_with_translations
: Get snippet with all language versionsget_snippet_translations
: List available translations
Filtering: All snippet searches support optional author
parameter for filtering by creator.
Basic interaction patterns:
-
Storing a snippet (vague):
"Save this quicksort implementation [paste code]"
→ AI will analyze code, infer concepts, create appropriate metadata in English
-
Storing a snippet (explicit):
"Store this snippet as bubble_sort.py with metadata: sorting, algorithm, iterative"
→ AI will verify metadata exists, create if missing, store snippet
-
Searching snippets:
"Find sorting algorithms that use recursion in Java"
→ AI searches with multilingual variants, checks translations if not found as original
-
Finding related snippets:
"Show me snippets similar to quicksort.py"
→ AI explores hierarchy, finds siblings, descendants, and translations
-
Managing translations:
"Create a Java version of quicksort.py"
→ AI creates translation linked to original
-
Language preference:
"I want metadata in Italian: 'ricorsione', 'ordinamento'"
→ AI will create as requested (though English is default)
Core principles:
-
Multilingual search strategy: Always use
get_metadata_forest
with language variants, synonyms, and typos:["recursion", "ricorsione", "rekursion", "recursive", "recusrion"]
-
Progressive data access: Start specific, expand gradually
- Forest search with variants (max 4-5 calls)
- Navigate through found metadata (siblings, path)
- Broader concepts if needed
- Ask user before
get_whole_metadata_forest
-
Generous depth values: Use maxDepth 5-8 for initial explorations (not all metadata exists)
-
Verify before navigate: Always check metadata exists before using
get_metadata_siblings
,get_metadata_path
, etc. -
Translation awareness:
- When snippet not found in requested language, automatically check translations
- Never say "not found" without checking
get_snippet_with_translations
-
English-first creation:
- Create metadata in English by default
- Inform user of the choice
- Allow override if user insists
-
Use rename for standardization: Prefer
rename_metadata
over delete+recreate
For users:
- Be as vague or specific as you want—AI adapts
- Search in your language; system handles translations
- Let AI suggest metadata; confirm or adjust
- Request English or local language metadata explicitly if desired
For AI assistants (from instructions.md):
- Search: Multilingual forest-first with generous depth
- Create: English metadata by default, inform user
- Navigate: Verify existence before using sibling/path functions
- Translate: Always check translations before reporting "not found"
- Standardize: Use
rename_metadata
for consistency - Batch operations: Few large calls better than many small ones
Naming conventions:
- Snippet names:
lowercase_with_underscores.ext
- Metadata names:
lowercase
, no spaces, meaningful terms - Avoid: language names as metadata (use extension instead)
1. Initialize empty database:
User: "Set up standard programming concepts"
AI: → Creates hierarchies: algorithm→sorting/search, datastructure→linear/tree, etc.
2. Store vague snippet:
User: "Save this [sorting code]"
AI: → Analyzes code
→ Searches for existing metadata (multilingual)
→ Creates missing metadata in English
→ Suggests snippet name
→ Creates snippet
3. Cross-language search:
User: "Find recursive sorting in Java"
AI: → Forest search: ["recursion", "ricorsione", "recursive", "sorting", "ordinamento"]
→ Find snippets with metadata
→ Filter by extension="java"
→ Check translations for non-Java results
→ Present: originals + available translations
4. Standardize metadata:
User: "Convert all Italian metadata to English"
AI: → Identifies mixed-language metadata
→ Proposes renames: "ricorsione"→"recursion", "ordinamento"→"sorting"
→ Uses rename_metadata (preserves relationships)
→ Reports: "X metadata standardized, Y snippets updated"
5. Create translation:
User: "I need quicksort.py in Java"
AI: → Searches for quicksort.py
→ Checks existing translations (avoid duplicates)
→ Creates Java translation if not exists
→ Links to original snippet
Ready to start? Launch the server, connect your AI assistant, and begin organizing your code semantically!