MCP Architector
 
Model Context Protocol (MCP) server for architecture and system design
Local-first MCP server that stores and manages project architecture information. All data is stored locally in ~/.mcp-architector for maximum privacy and confidentiality.
π¦ Install: npm install -g mcp-architector or use via npx π npm: https://www.npmjs.com/package/mcp-architector π GitHub: https://github.com/theSharque/mcp-architect
How to connect to Claude Desktop / IDE
Add the server to your MCP config. Example for claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"architector": {
"command": "npx",
"args": ["-y", "mcp-architector"],
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
For Cursor IDE: Settings β Features β Model Context Protocol β Edit Config, then add the same block inside mcpServers. See the Integration section for more options.
Cursor rule (recommended)
For Cursor IDE and Cursor Cloud Agents, use a phased onboarding rule so the agent does not dump the whole repo into context in one shot.
- Copy
.cursor/rules/architector-onboarding.mdcinto your project (the repo you are documenting):
mkdir -p /path/to/your-app/.cursor/rules
cp /path/to/mcp-architector/.cursor/rules/architector-onboarding.mdc /path/to/your-app/.cursor/rules/
- Ensure MCP Architector is configured with
MCP_PROJECT_IDpointing at that workspace (see How to connect).
- Ask in chat, for example: "Onboard this repo into architector β phase 0 plan first" or "Import architecture module by module".
The rule is alwaysApply: false β Cursor attaches it when the task matches architecture import/onboarding. It enforces: structure β one module per step β validate after each step β compact tools only.
If you develop this server repo, keep the same file here so contributors and Cloud Agents follow the same workflow when updating ~/.mcp-architector/_qs_mcp-architector/.
Overview
Store and manage project architecture, modules, scripts, data flow, and usage examples - all locally with complete privacy.
Features
- Local Storage: All data stored in
~/.mcp-architector(privacy-first) - Project Architecture: Store and retrieve overall project architecture
- Module Details: Detailed information about each module
- Resources: Access architecture data via resources
Storage Structure
~/.mcp-architector/
βββ {projectId}/
βββ architecture.json # Modules + dataFlow (vertical structure)
βββ modules/
β βββ {moduleId}.json
β βββ ...
βββ entries/
β βββ index.json # Catalog (no duplicate bodies)
β βββ {entryId}.json # Canonical facts (API, domain, flows, β¦)
βββ slices/
β βββ {sliceId}.json # Custom filters only (no items)
Data model
| Layer | Purpose | Tools | |-------|---------|-------| | Modules | Vertical structure: components, dependencies, dataFlow | set-project-architecture, set-module-details, set-module-data-flow, rebuild-data-flow, validate-architecture | | Entries | Single source of truth for horizontal facts (one fact = one file) | set-entry, set-entries, get-entry, list-entries | | Slices | Read-only views over entries (built-in or custom filters) | list-slices, get-slice |
Anti-patterns (no duplication): Do not copy module.description into entry.summary. Link with refs.moduleName. Slices never store item copiesβonly filters in slices/*.json.
Do not edit ~/.mcp-architector directly β always use MCP tools so timestamps, merge semantics, and dataFlow inverse sync stay consistent.
Agent workflow
list-projectsβ confirmprojectIdif data looks empty or wrong.- Structure task β
get-project-architecture/set-project-architecture. - Each module β
set-module-detailswithfiles+facts[](endpoints, entities, glossary) in the same call, orset-entries/set-entrywithrefs.moduleName. - Single module graph edge β
set-module-data-flow. - Bulk rebuild flow (many modules) β
rebuild-data-flow. - After edits, verify everything β
validate(summary +issues[]; no full project load). - Need a category (all APIs, all domain terms) β
list-slicesβget-slicewithformat=compactortable; useoffsetwhenhasMoreis true. - Find by name β
search-entriesβget-entryfor full payload. - After code refactor (same modules) β
refactor-architecture:scanβ dryRun preview β apply withconfirm=true.
| Scenario | Tool | |----------|------| | Update one module + its APIs/facts | set-module-details with facts[] | | Bulk facts for a domain | set-entries with moduleName | | Patch dataFlow for one module | set-module-data-flow | | Rebuild all module edges | rebuild-data-flow | | Diagnose graph + empty slices | validate (or validate-architecture) | | Sync paths/names after refactor | refactor-architecture (dryRun, then confirm) | | Index out of sync | rebuild-entry-index | | Create project from scratch | set-project-architecture with replaceModules: true | | Onboard a fresh git clone (phased) | Copy .cursor/rules/architector-onboarding.mdc β ask agent to onboard phase by phase |
Full project picture: modules alone do not populate slices β without http-endpoint (and other kinds) entries, slice api stays empty. New module β add facts or entries in the same step.
Example: set-module-details with facts: [{ kind: "http-endpoint", title: "POST /orders", ... }], then get-slice sliceId=api format=table.
Quick Start
For Users (using npm package)
# No installation needed - use directly in Cursor/Claude Desktop
# Just configure it as described in Integration section below
For Developers
- Clone the repository:
git clone https://github.com/theSharque/mcp-architect.git
cd mcp-architect
- Install dependencies:
npm install
- Build the project:
npm run build
Usage
Development Mode
Run with hot reload: ``bash npm run dev ``
Production Mode
Start the server: ``bash npm start ``
MCP Inspector
Debug and test your server with the MCP Inspector: ``bash npm run inspector ``
Integration
Cursor IDE
- Open Cursor Settings β Features β Model Context Protocol
- Click "Edit Config" button
- Add one of the configurations below
Option 1: Via npm (Recommended)
Installs from npm registry automatically:
{
"mcpServers": {
"architector": {
"command": "npx",
"args": ["-y", "mcp-architector"],
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
Option 2: Via npm link (Development)
For local development with live changes:
{
"mcpServers": {
"architector": {
"command": "mcp-architector",
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
Requires: cd /path/to/mcp-architector && npm link -g
Option 3: Direct path
{
"mcpServers": {
"architector": {
"command": "node",
"args": ["/path/to/mcp-architector/dist/index.js"],
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"architector": {
"command": "npx",
"args": ["-y", "mcp-architector"],
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
Continue.dev
Edit .continue/config.json:
{
"mcpServers": {
"architector": {
"command": "npx",
"args": ["-y", "mcp-architector"],
"env": {
"MCP_PROJECT_ID": "${workspaceFolder}"
}
}
}
}
Using Project ID
When calling tools, you can:
- Use automatic project ID (from
${workspaceFolder}env var): Just omit theprojectIdparameter - Override per call: Pass
projectIdexplicitly in the tool call - Use default: If neither is provided, uses "default-project"
Tools
set-project-architecture
Creates or updates the overall architecture for a project. By default merges modules and dataFlow by name; omit dataFlow to preserve existing flow. dependsOn is canonical; providesTo is recomputed on save.
Input:
projectId(optional): Project ID (defaults to "default-project")description: Overall project descriptionmodules: Array of module objects with:name: Module namedescription: Brief description of the moduleinputs(optional): What this module requires to workoutputs(optional): What this module produces or generatesdataFlow(optional): Object describing data flow between modules (omit to keep existing):- Key: module name
- Value: object with:
dependsOn(optional): Array of module names this module depends onprovidesTo(optional): Derived on save from alldependsOnedgesdataTransformation(optional): How data is transformed between modulesreplaceModules(optional): Replace entire modules list (defaultfalse= merge by name)replaceDataFlow(optional): Replace entire dataFlow (defaultfalse= merge by module name)
Output:
- Project ID and success message
get-project-architecture
Retrieves the overall architecture of the project.
Input:
projectId(optional): Project ID (defaults to "default-project")
Output:
- Complete project architecture
list-projects
Lists all projects in local storage (~/.mcp-architector). Use when the workspace may map to a different normalized projectId.
Input:
query(optional): Filter by substring in projectId or description (case-insensitive)
Output:
- Array of project summaries:
projectId,description,moduleCount,updatedAt,isCurrent(matches currentMCP_PROJECT_ID)
Entries and slices
| Tool | Purpose | |------|---------| | set-entry | Upsert one fact; response may include reminder if modules missing or unlinked | | set-entries | Bulk upsert (max 200); optional moduleName sets refs.moduleName on all | | get-entry | Full entry by id | | delete-entry | Remove entry | | list-entries | Catalog without payload; filter by kind, tags, query | | search-entries | Compact text search with snippet, slices, moduleName, pagination; filters: moduleName, kind, tags | | list-slices | Built-in + custom slices with entry counts | | get-slice | Filtered view: sliceId, format, query, limit, offset, hasMore | | set-slice | Save custom filter (kinds, tags) β no items | | delete-slice | Remove custom slice | | rebuild-entry-index | Rebuild entries/index.json from entry files |
Built-in sliceId values: api, persistence, events, domain, flows, integrations, config, runtime, decisions, scripts.
search-entries
Compact navigation searchβreturns enough context to pick a hit, then call get-entry for full payload.
Input: query (required), moduleName, kind, tags, limit (default 10, max 50), offset (default 0)
Output: summary, total, returned, offset, hasMore, results[] with snippet, matchedIn, slices, moduleName plus legacy summary, tags, refs
Recommended kind examples (any string allowed):
| sliceId | kinds | |---------|-------| | api | http-endpoint, grpc-method, mcp-tool, cli-command, β¦ | | persistence | db-table, entity, repository | | domain | glossary, invariant, lifecycle | | scripts | script β use set-entry / get-slice sliceId=scripts |
set-module-details
Creates or updates detailed information about a module. Slices read entries, not module text β pass facts[] to create linked entries in one call.
Input:
projectId(optional): Project IDname: Module namedescription: Detailed description of the moduleinputs: What the module accepts as inputoutputs: What the module produces as outputdependencies(optional): List of module dependencies (syncs todataFlow.dependsOnwhen provided)files(optional): List of files belonging to this modulefacts(optional): Array of horizontal facts (kind,title,summary, β¦) β each upserted as entry withrefs.moduleName= module nameusageExamples(optional): Array of usage examples with fields:title: Example titledescription(optional): Description of the examplecommand(optional): Command or code snippetinput(optional): Input dataoutput(optional): Expected outputnotes(optional): Additional notes about the examplenotes(optional): Additional notes
Output:
- Module ID and success message
set-module-data-flow
Patches dataFlow for a single module without sending the full architecture.
Input:
projectId(optional): Project IDmoduleName: Module namedependsOn(optional): Modules this module depends on (canonical)dataTransformation(optional): How data is transformedsyncInverse(optional): RecomputeprovidesTo(defaulttrue)
Output:
- Module name and success message
rebuild-data-flow
Rebuilds dataFlow for all modules from module file dependencies or existing dependsOn edges. Replaces bulk manual edits to architecture.json.
Input:
projectId(optional): Project IDsource(optional):module-dependencies(default) ordataFlow-dependsOnsyncInverse(optional): RecomputeprovidesTo(defaulttrue)pruneOrphans(optional): Remove invalid module references (defaulttrue)
Output:
edgesAdded,edgesRemoved,modulesUpdated, message
validate
Primary post-edit check. Read-only validation with a compact agent-friendly report. Does not modify data.
Checks (only rules we can verify from stored JSON):
- dataFlow: inverse drift, dangling
dependsOn/providesTo, orphan flow keys module.dependenciesvsdataFlow.dependsOn- entries:
entries-without-modules,entry-unlinked,orphan-entry-module,module-no-entries,module-missing-api/module-missing-persistence,entry-slice-orphan,module-too-many-entries,module-too-few-entries - storage: missing
modules/{id}.json, orphan module files, entry index drift - slices: empty built-in
api/domain/persistencewhen modules exist
Input: projectId, checkInverse, checkModuleDeps, checkEntryCoverage, checkStorage, checkEmptySlices, checkSliceCoverage, checkModuleEntryCounts, moduleEntryMax (default 50), moduleEntryMin (optional; omit to disable min check) β all boolean flags default true unless noted
Output: valid, issueCount, summary, stats, issuesByKind, issues[], coverage, checksRun
refactor-architecture
Preview or apply in-architector sync after a code refactor when module boundaries stay the same. Agent is the source of truth β no workspace or git access. Default dryRun=true.
Workflow: (1) scan with file or text β compact hits, (2) build mutation ops, (3) dryRun preview, (4) apply with dryRun=false and confirm=true.
Operations (max 10 per call): scan, move-file, replace-path-prefix, rename-text, patch-entry, merge-files, remove-file-ref.
Scope (optional): moduleName, kinds, tags β limits which entries/modules are touched.
Orphan entries with empty refs.files and no refs.entryIds are deleted after file operations.
Input: projectId, operations[], scope, dryRun (default true), confirm (required when applying), limit, offset
Output: summary, stats, hits (scan) or paginated changes, warnings, hasMore
validate-architecture
Same as validate (legacy alias). Prefer validate after edits.
Output:
valid(boolean),issuesarray
get-module-details
Retrieves detailed information about a specific module.
Input:
projectId(optional): Project IDmoduleName: Name of the module to retrieve
Output:
- Complete module details
list-modules
Lists all modules in the project architecture.
Input:
projectId(optional): Project ID
Output:
- Array of module summaries
delete-module
Deletes a module from the project architecture.
Input:
projectId(optional): Project IDmoduleName: Name of the module to delete
Output:
- Success message
Resources
architecture
Provides access to project architecture as a resource.
Usage: Access via URI: arch://{projectId}
module
Provides access to module details as a resource.
Usage: Access via URI: module://{projectId}/{moduleId}
Development
Project Structure
mcp-architector/
βββ src/
β βββ index.ts # Main server implementation
β βββ types.ts # Type definitions
β βββ storage.ts # Storage utilities
βββ dist/ # Compiled output (generated)
βββ package.json
βββ tsconfig.json
βββ README.md
Project ID and Workdir
The server uses projectId to organize data in separate directories. The priority for determining project ID is:
- Explicitly passed in tool call parameters (highest priority)
- From environment variable
MCP_PROJECT_ID(set during initialization) - Default fallback "default-project" (lowest priority)
For Cursor integration, set MCP_PROJECT_ID to use the workspace directory automatically as the project ID.
Extending the Server
To add new tools, resources, or prompts, edit src/index.ts:
// Add a tool
server.registerTool(
"tool-name",
{ /* tool config */ },
async (params) => { /* handler */ }
);
// Add a resource
server.registerResource(
"resource-name",
new ResourceTemplate("uri-template", { /* options */ }),
{ /* resource config */ },
async (uri, params) => { /* handler */ }
);
// Add a prompt
server.registerPrompt(
"prompt-name",
{ /* prompt config */ },
(args) => { /* handler */ }
);
License
MIT






