Fabric UX System MCP Server (TypeScript)
April 12, 2025 ยท View on GitHub
A Model Context Protocol (MCP) server designed to act as an expert source for the Fabric UX System. It allows MCP-enabled AI clients (like Cursor) to access up-to-date information about Fabric UX components, development practices, design guidelines, and content standards by performing semantic search over local, RAG-optimized documentation files.
This server uses a Retrieval-Augmented Generation (RAG) approach:
- Indexing: Reads local Fabric UX documentation files from the
_docs_fabric_uxdirectory (the single source of truth for content), splits them into meaningful chunks, generates vector embeddings using a local model, and stores them in a vector database (ChromaDB) accessed via a running server. - Retrieval: When the
askFabricDocstool is called, it searches the vector database for documentation chunks semantically similar to the user's query. - Generation: The retrieved chunks are returned to the AI client, which uses them as context to generate an informed answer.
Features
- TypeScript: Modern, type-safe JavaScript.
- MCP SDK: Uses the official
@modelcontextprotocol/sdk. - Local RAG Pipeline:
- Source Data: RAG-optimized Markdown files in
_docs_fabric_ux. - Embedding Model: Local sentence transformers via
@xenova/transformers(Defaults toXenova/all-MiniLM-L6-v2). Runs offline. - Vector Database Client: Connects to a running ChromaDB server via its HTTP client (
chromadblibrary). - Markdown Parsing: Uses
unified/remarkecosystem for robust, structure-aware parsing and chunking.
- Source Data: RAG-optimized Markdown files in
- Core MCP Tool:
askFabricDocs(query: string): Performs semantic search over the indexed documentation and returns relevant chunks.
- Stdio Transport: Focused on
stdiotransport for easy integration with local clients like Cursor. - Configurable: Uses environment variables (
.envfile support) for paths, model names, and server URLs. - Structured Logging: Uses
pino. - Error Handling: Custom error classes (
src/errors.ts). - Containerization: Includes a
Dockerfile(note: requires adaptation for indexing or pre-indexed data volume). - Linting/Formatting: Uses Biome for fast, integrated linting and formatting.
- Testing: Setup with Vitest, includes tests for the core tool and indexing script orchestration.
Prerequisites
- Node.js (v18 or later recommended)
- npm (usually included with Node.js)
- Git (for cloning and getting updates)
- Docker (or another way to run a ChromaDB server instance)
Important: A running ChromaDB server instance is required both for indexing the documentation (npm run index-docs) and for running the MCP server itself (npm start, npm run dev).
Core Workflow Summary
- Start ChromaDB Server: Ensure your ChromaDB instance (e.g., via Docker) is running and accessible (Default:
http://127.0.0.1:8000). - Index Documentation: Run
npm run index-docsto populate ChromaDB with the content from_docs_fabric_ux. This only needs to be done once initially, or again after updating the source documents. - Start MCP Server: Run the server using
npm run dev(development) ornpm start(production). - Connect Client: Configure your MCP client (e.g., Cursor) to connect to the running server (typically via
stdio).
Setup and Installation
-
Clone the repository:
git clone <repository-url> cd mcp-fabric-ux-system -
Install dependencies: This installs the MCP server code, embedding libraries, ChromaDB client, etc.
npm install -
Configure environment (Optional):
- Copy the example environment file:
# On Windows (Command Prompt) copy .env.example .env # On macOS/Linux # cp .env.example .env - Edit the
.envfile if needed (see Configuration). Default paths usually work if running ChromaDB locally.
- Copy the example environment file:
-
Start ChromaDB Server: The server needs a running ChromaDB instance before indexing or running the MCP server. The easiest way is often via Docker.
# Pull the latest ChromaDB image docker pull chromadb/chroma # Run ChromaDB, exposing port 8000 and mounting a volume for persistence # Replace '/path/on/host/to/chroma-data' with an actual path on your machine docker run -d -p 8000:8000 -v /path/on/host/to/chroma-data:/chroma/chroma --name chroma_server chromadb/chromaEnsure Docker Desktop is running. Verify the container is running with
docker ps. If you stop the container (docker stop chroma_server), you can restart it later withdocker start chroma_server. -
Index Documentation: This crucial step scans the source documents in
_docs_fabric_ux, generates embeddings, and populates the running ChromaDB server. Ensure ChromaDB is running before executing this command.npm run index-docsThis might take some time, especially on the first run, as it downloads the embedding model and processes all documents.
Configuration
Configuration is managed via environment variables, loaded from .env. Key options:
LOG_LEVEL: Logging level (Default:info).NODE_ENV: Set toproductionfor optimized builds/JSON logs (Default:development).DOCS_PATH: Path to the directory containing source documentation files (Default:_docs_fabric_ux).VECTOR_DB_PATH: (Deprecated/Unused) Path for local ChromaDB files (No longer used as we connect to a server).CHROMA_SERVER_URL: URL of the running ChromaDB server (Default:http://127.0.0.1:8000).EMBEDDING_MODEL_NAME: Name of the sentence transformer model from Hugging Face Hub (via Xenova) (Default:Xenova/all-MiniLM-L6-v2).CHROMA_COLLECTION_NAME: Name for the collection within ChromaDB (Default:fabric_ux_docs).
Running the Server
Important: Ensure your ChromaDB server is running and you have run npm run index-docs at least once while the ChromaDB server was running before starting the MCP server.
Development Mode (with Hot-Reload and Pretty Logs)
Requires the ChromaDB server to be running.
npm run dev
Production Mode (Compiled JavaScript)
Requires the ChromaDB server to be running.
-
Build the TypeScript code:
npm run build -
Run the server:
# On Windows (Command Prompt) set NODE_ENV=production npm start # On macOS/Linux # NODE_ENV=production npm startLogs will be in JSON format.
Updating Content
To update the information the server uses (after modifying files in _docs_fabric_ux):
- Ensure ChromaDB server is running.
- Re-index the documentation: This clears the existing collection in ChromaDB and repopulates it with the latest content from
_docs_fabric_ux.npm run index-docs - Restart the MCP server if it was running.
Available MCP Tools
askFabricDocs- Description: Queries the indexed Fabric UX documentation in ChromaDB using semantic search.
- Arguments:
query(string, required): The natural language question or topic to search for.resultCount(number, optional, default: 3): The maximum number of relevant document chunks to return.
- Returns: An array of objects, each containing:
text: The content of the relevant document chunk.metadata: Information about the chunk's source (e.g.,filePath,title,area,chunkId).score: A similarity score (lower is better for ChromaDB's default L2 distance).
Extending the Boilerplate
(This section focuses on the RAG implementation)
- Modify Chunking: Improve the logic in
scripts/indexDocs.ts(specifically howunifiedis used to parse and split Markdown into chunks). - Add Metadata: Extract more metadata during indexing (e.g., using
remark-frontmatteror custom logic) and store it in ChromaDB to enable filtered searches. - Create Filtered Tools: Add new MCP tools that query
chromadbusing metadata filters (e.g.,getComponentExamples(componentName: string)). - Change Embedding Model: Update
EMBEDDING_MODEL_NAMEin.envand re-runnpm run index-docs. - Tune Search: Adjust the
resultCountor explore different search parameters in theaskFabricDocstool handler (src/tools/askFabricDocs.ts). - Change Vector DB: Modify
scripts/indexDocs.tsandsrc/tools/askFabricDocs.tsto use a different vector database client (e.g., LanceDB).
MCP Tool Invocation
When working with MCP tools, it's important to understand how they're invoked:
-
AI Tool Invocation: MCP tools are designed to be called by the AI assistant, not directly by users. The AI can call tools directly using their prefixed name.
-
Tool Naming:
- Register tools with simple names (e.g., "add")
- The AI will see tools with prefixed names (e.g., "mcp_mcp_minimal_add")
- Do not register tools with prefixed names, as this creates duplication
-
Logging Considerations:
- When running in stdio mode, all logging must go to stderr, never stdout
- Stdout is strictly reserved for JSON-RPC messages
- Using console.log() will break the JSON-RPC protocol - use a custom logger that writes to stderr
-
User Interface:
- Users cannot directly invoke MCP tools in the chat interface
- The AI assistant acts as the intermediary to invoke tools on behalf of the user
Client Configuration Examples
Here are examples of how to configure a client like Cursor to connect to this server.
Connecting via Stdio (Recommended)
-
Ensure ChromaDB server is running.
-
Ensure you have run
npm run buildandnpm run index-docssuccessfully. -
Ensure the
start:stdioscript exists and is correct inpackage.json:"scripts": { // ... other scripts "start:stdio": "cross-env NODE_ENV=production node dist/index.js --stdio" }(If
cross-envis not installed:npm install --save-dev cross-env) -
Configure the server in Cursor's
mcp.json(e.g.,C:\Users\<username>\.cursor\mcp.json):{ "mcpServers": { "mcp_fabricux": { "displayName": "Fabric UX System", "command": "npm", "args": [ "run", "start:stdio", "--prefix", "C:\\path\\to\\your\\project" // Use YOUR absolute project path ], "cwd": "C:\\path\\to\\your\\project", // Use YOUR absolute project path "env": { "NODE_ENV": "production" // Optionally override CHROMA_SERVER_URL etc. if needed }, "enabled": true } } }- Important: Replace
C:\path\to\your\projectwith the correct absolute path to this project directory. Use double backslashes (\\) on Windows. - This configuration uses
npm run start:stdiowhich correctly setsNODE_ENVviacross-envand runs the compiled code with the--stdioflag.
- Important: Replace
Basic Security Considerations
- Input Validation: Zod schemas validate tool inputs.
- Source Data: Be aware of any sensitive information within the source documentation (
_docs_fabric_ux) being indexed. - ChromaDB Access: If ChromaDB is exposed beyond localhost, ensure appropriate network security/authentication.
- Dependencies: Regularly audit dependencies (
npm audit). - Error Handling: Avoid leaking excessive detail in errors.
Testing
- Run tests using Vitest:
npm test - Tests cover the
askFabricDocstool and the orchestration logic of the indexing script (mainfunction).
Linting and Formatting
- Check formatting & linting:
npm run format&npm run lint - Apply fixes:
npm run format:fix&npm run lint:fix - Uses Biome.
Limitations
- Local Execution & Setup: This server is designed to run locally, requiring manual setup of a ChromaDB server and manual re-indexing for updates.
- Indexing Time: Initial indexing can take time depending on documentation size and machine specs.
- AI Model Compatibility: The ability for the Cursor AI agent to automatically use or be prompted to use custom MCP tools can be model-dependent. Some models may have difficulty initiating calls to dynamically discovered tools even if they are listed correctly in the settings. Testing with different AI models within Cursor may be necessary if you encounter issues with AI tool invocation.
- Tool Quantity: Some MCP servers, or user's with many MCP servers active, may have many tools available for Cursor to use. Currently, Cursor will only send the first 40 tools to the Agent.
- Remote Development: Cursor directly communicates with MCP servers from your local machine, either directly through
stdioor via the network usingsse. Therefore, MCP servers may not work properly when accessing Cursor over SSH or other development environments. We are hoping to improve this in future releases. - MCP Features Support: MCP servers offer three main capabilities: tools, resources, and prompts. Currently, Cursor only supports tools. Resources and prompts are defined in the protocol and implemented in this server, but are not yet accessible through Cursor. We are hoping to see support for these additional capabilities in future Cursor releases.
License
This project is licensed under the MIT License - see the LICENSE file for details.