12 KiB
CLAUDE.md — MCP Wiki Server for EasyWMS
Project Overview
Build an MCP (Model Context Protocol) server that serves a compiled wiki about EasyWMS (Mecalux WMS) to Claude. The wiki contains ~65-70 dense, cross-referenced Markdown pages covering every aspect of the WMS: core entities, operational flows, modules, architecture, troubleshooting.
This MCP server is read-only — it serves knowledge. It is designed to work alongside a separate MCP API server (already built) that queries live WMS data. Together:
- MCP Wiki (this project) = "how the WMS is supposed to work" (theory, logic, configuration)
- MCP API (separate project) = "what the WMS actually contains right now" (live data, logs, workflows)
Target Environment
- Runtime: Node.js (v18+)
- OS: Windows Server (same VM as the WMS) or any machine with Node.js
- Transport: stdio (launched by Claude Desktop or Claude Code)
- Dependencies:
@modelcontextprotocol/sdk,dotenv, and minimal others — keep it lightweight - No network required: all data is local (wiki/ folder)
Project Structure
mcp-wiki-server/
├── CLAUDE.md ← This file
├── package.json
├── .env ← Wiki path configuration
├── wiki/ ← Compiled wiki pages (copied from mcp-wiki project)
│ ├── _index.md
│ ├── _log.md
│ ├── _lint_report.md
│ ├── glossary.md
│ ├── concepts/ ← ~30 concept pages
│ ├── modules/ ← ~23 module pages
│ ├── architecture/ ← ~4 pages
│ └── operations/ ← ~2 pages
└── src/
├── index.js ← Main MCP server entry point
├── config/
│ └── constants.js ← Paths, cache settings
├── services/
│ ├── wiki-index.js ← Loads and parses _index.md + frontmatter from all pages
│ ├── search.js ← Full-text + tag search across wiki pages
│ └── page.js ← Read individual wiki pages
├── tools/
│ ├── search-tool.js ← search_wiki tool
│ ├── page-tool.js ← get_wiki_page tool
│ ├── browse-tool.js ← list_wiki_sections tool
│ ├── glossary-tool.js← get_glossary_term tool
│ └── related-tool.js ← get_related_pages tool
└── resources/
├── overview.js ← wiki://overview resource
└── entities-map.js ← wiki://entities-map resource
MCP Tools to Implement (5 tools)
1. search_wiki
Purpose: Search across all wiki pages by keyword, tag, or entity name. Parameters:
query(string, required) — Search termstags(string[], optional) — Filter by tags from frontmattertype(string, optional) — Filter by page type: "concept", "module", "architecture", "operation"max_results(number, optional, default: 5) — Max pages returned
Behavior:
- Search in page titles (highest weight)
- Search in frontmatter tags and
relatedentries (medium weight) - Search in page body text (lower weight)
- Return results sorted by relevance score
- Each result includes: title, path, type, summary (first paragraph), relevance score
Implementation notes:
- Build an in-memory inverted index at startup from all wiki pages
- Parse YAML frontmatter to extract title, type, tags, related, sources
- Index words from title, tags, headings (h2/h3), and body text with different weights
- Support partial matches and case-insensitive search
- The search index should be rebuilt if wiki files change (check mtime on page load, or just rebuild at startup since pages are static)
2. get_wiki_page
Purpose: Load the full content of a specific wiki page. Parameters:
path(string, required) — Page path relative to wiki/ (e.g., "concepts/container.md")
Behavior:
- Read the file from wiki/{path}
- Return full markdown content including frontmatter
- If page not found, return a helpful error listing similar page names (fuzzy match)
Implementation notes:
- Simple file read — no transformation needed
- Add a "Related pages" footer with clickable links if the frontmatter has
relatedentries - Cache file contents in memory (pages don't change at runtime)
3. list_wiki_sections
Purpose: Return the complete wiki structure for navigation. Parameters:
section(string, optional) — Filter by section: "concepts", "modules", "architecture", "operations", or omit for all
Behavior:
- Return a structured list of all pages grouped by section
- Each entry includes: title, path, type, one-line summary
- If section filter is provided, return only that section
Implementation notes:
- Built from the in-memory index (same data as search_wiki)
- This is the first tool Claude should call when it needs to orient itself
4. get_glossary_term
Purpose: Quick definition lookup for WMS-specific terms. Parameters:
term(string, required) — Term to look up (case-insensitive)
Behavior:
- Parse glossary.md into a dictionary of term → definition
- Search for exact match first, then partial match
- Return the definition + link to the glossary page
- If not found, suggest similar terms
Implementation notes:
- Parse glossary.md at startup into a Map<string, string>
- Support abbreviations (e.g., "PDL" → "Picking Dedicated Location")
- Fuzzy matching: Levenshtein distance or simple startsWith/includes
5. get_related_pages
Purpose: Find all pages related to a given entity, command, or concept. Parameters:
name(string, required) — Entity name, command name, or concept (e.g., "Container", "putaway", "ASN")
Behavior:
- Search the
relatedfrontmatter field of all pages for the given name - Also search page body for mentions of the name
- Return list of pages that reference this concept, with context (the sentence/heading where it's mentioned)
Implementation notes:
- Uses the same inverted index as search_wiki
- Additionally parses
relatedfrontmatter arrays - Useful when Claude wants to understand all the places a concept appears
MCP Resources to Implement (2 resources)
wiki://overview
Content: A condensed overview of the EasyWMS wiki — what sections exist, how many pages, key concepts. This is automatically loaded into Claude's context when the MCP connects.
Build from: wiki/_index.md content + page counts per section
wiki://entities-map
Content: The entities relationship map showing how WMS entities relate to each other.
Build from: wiki/architecture/entities-map.md content
Implementation Guidelines
Startup Sequence
- Read
WIKI_PATHfrom.env(default:./wiki) - Scan all
.mdfiles in wiki/ - Parse frontmatter (YAML between
---markers) for each file - Build in-memory index:
pages[]— array of {path, title, type, tags, related, summary, body, headings}invertedIndex{}— word → [{page, weight, context}]glossary{}— term → definition
- Register MCP tools and resources
- Start stdio transport
Frontmatter Parsing
Every wiki page has this structure:
---
title: "Page Title"
type: concept | module | architecture | operation
sources:
- path/to/raw/source.md
related:
- concepts/other-page.md
- modules/some-module.md
last_compiled: "2026-04-10"
---
# Page Title
Page body content...
Parse the YAML between the --- markers. Use a simple regex-based parser or yaml npm package.
Search Relevance Scoring
title exact match: 100
title partial match: 50
tag exact match: 40
heading (h2/h3) match: 30
related entry match: 25
body text match: 10
Error Handling
- All tools must return structured errors, never crash the server
- Use
console.error()for logging (stdout reserved for MCP protocol) - If wiki/ folder is missing or empty, return a clear error message
Performance
- Wiki is small (~70 files, ~1-2MB total) — load everything into memory at startup
- No database needed
- No pagination needed for search results (max 10-20 results)
- File watching is optional (pages are static between syncs)
.env Configuration
# Path to the wiki folder (absolute or relative to project root)
WIKI_PATH=./wiki
# Optional: enable debug logging
DEBUG=false
Claude Desktop Integration
After building, configure Claude Desktop to use both MCP servers:
{
"mcpServers": {
"wms-wiki": {
"command": "node",
"args": ["C:\\path\\to\\mcp-wiki-server\\src\\index.js"]
},
"wms-api": {
"command": "node",
"args": ["C:\\path\\to\\wms-mcp-server\\src\\index.js"]
}
}
}
Custom Instructions for Claude Desktop
When both MCPs are configured, add this to Claude Desktop's custom instructions:
You have access to two MCP servers for EasyWMS:
1. wms-wiki — Documentation and knowledge base. Use it to understand HOW the WMS works:
- search_wiki: find relevant documentation pages
- get_wiki_page: read full page content
- list_wiki_sections: browse available documentation
- get_glossary_term: look up WMS-specific terms
- get_related_pages: find all pages mentioning a concept
2. wms-api — Live WMS data. Use it to see WHAT the WMS currently contains:
- query_wms_entities: query live data via LINQ
- search_workflows: find workflow definitions
- search_ad_elements: search application dictionary
- read_recent_logs: check recent log entries
WORKFLOW for diagnosing issues:
1. FIRST use wms-wiki to understand the feature/concept involved
2. THEN use wms-api to check the actual state of the WMS
3. Compare theory (wiki) vs reality (live data) to identify the problem
4. Use wiki error/troubleshooting sections for known solutions
WORKFLOW for answering "how does X work":
1. search_wiki or list_wiki_sections to find relevant pages
2. get_wiki_page to read the full documentation
3. If needed, get_glossary_term for specific terminology
Always consult the wiki BEFORE querying live data — it gives you the context to interpret what the API returns.
Testing
After implementation, test these scenarios in Claude Desktop:
-
"What is a container in EasyWMS?" → Should call search_wiki("container") → get_wiki_page("concepts/container.md")
-
"How does putaway work?" → Should call get_wiki_page("concepts/putaway.md") → comprehensive answer
-
"What's a PDL?" → Should call get_glossary_term("PDL") → "Picking Dedicated Location" + link to replenishment.md
-
"What ERP messages are involved in reception?" → Should call search_wiki("reception ERP") → get_wiki_page("concepts/reception.md") → extract ERP section
-
"Why are my putaway tasks failing?" (with wms-api also connected) → Should call search_wiki("putaway errors") → read troubleshooting → then query live WMS data for comparison
-
"List all available modules" → Should call list_wiki_sections("modules") → return all module pages
Development Commands
# Install dependencies
npm install
# Run locally for testing
node src/index.js
# Test with MCP inspector (if available)
npx @modelcontextprotocol/inspector node src/index.js
Dependencies
{
"dependencies": {
"@modelcontextprotocol/sdk": "latest",
"dotenv": "^16.0.0"
}
}
Keep dependencies minimal. No YAML parser needed if you use regex for frontmatter. No search library needed — the wiki is small enough for a custom in-memory index.
Key Technical Constraints
- stdout is reserved for MCP protocol — use
console.error()for all logging - Windows paths — use
path.join()everywhere, never hardcode/or\\ - Encoding — all wiki files are UTF-8
- No network — everything is local file reads
- Startup speed — loading ~70 MD files into memory should take < 1 second
- Memory — wiki is ~1-2MB, index adds maybe 5MB — trivial for Node.js