Nanostores MCP

by Valyay

133 downloads
Not rated
GitHub

About

MCP transforms the Nanostores state layer from a collection of disparate files into a clear dependency map - enabling LLM and you to understand the architecture and helps spend less time mapping out dependencies and more time on actual architectural solutions especially in large

Details

Author
Valyay
Downloads
133
Categories
Developer Tools, Other

- Transforms Nanostores state layer into a dependency map
- Enables LLM and human understanding of architecture
- Reduces time spent on mapping dependencies
- Helps focus on actual architectural solutions
- Especially useful for large codebases

- 📊 Static Analysis:AST-based project scanning, dependency graphs, store inspection
- 🔥 Runtime Monitoring:Live events from@nanostores/logger, performance metrics, activity tracking
- 📚 Documentation:Search and browse Nanostores docs by topic or store kind
- 🎯 Zero Config:Works out of the box — auto-detects project roots and nanostores docs
- 🌐 Framework-Agnostic:Works with React, Vue, Svelte, Angular, Solid, Preact, Lit — any framework that uses Nanostores

Ask your AI:"Analyze my store architecture"or"Which stores update most frequently?"

Made atEvil Martians, product consulting fordeveloper tools.

- Features
-
Requirements
-
Installation
-
Configuration
-
Quick Start
-
MCP Interface

- Resources
-
Tools
-
Advanced Tool Arguments
-
Prompts

Understand your nanostores architecture without running your app:

🔥 Runtime Monitoring (Logger Integration)

Real-time insights into your running application:

- Live event capture— mount/unmount, value changes, action calls from@nanostores/logger
- Performance analysis— find noisy stores, high error rates, performance bottlenecks
- Activity metrics— change frequency, action success/failure rates, action duration
- Combined analysis— merge static structure with runtime behavior for deep debugging

Search and browse Nanostores documentation directly from your AI assistant:

- Full-text search— find guides, API references, and best practices by query
- Store-kind lookup— get docs relevant to a specific store type (atom, map, computed, etc.)
- Auto-detection— picks up docs fromnanostoresin yournode_modulesautomatically

Required peer dependency(for static analysis):

Optional peer dependencies— install only if you use the corresponding file format:

Without these optional packages the server still works — it silently skips unsupported file types.

npm install -g nanostores-mcp # or pnpm add -g nanostores-mcp

Add to~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or%APPDATA%\Claude\claude_desktop_config.json(Windows):

{ "mcpServers": { "nanostores": { "command": "npx", "args": ["-y", "nanostores-mcp"], "env": { "NANOSTORES_MCP_ROOT": "/path/to/your/project" } } } }

RequiresGitHub Copilotextension (VS Code 1.99+). Create.vscode/mcp.jsonin your project:

{ "servers": { "nanostores": { "type": "stdio", "command": "npx", "args": ["-y", "nanostores-mcp"] } } }

Tools are available in Copilot'sAgent mode(select "Agent" in the Copilot Chat dropdown).

Create.cursor/mcp.jsonin your project root (or~/.cursor/mcp.jsonfor global):

{ "mcpServers": { "nanostores": { "command": "npx", "args": ["-y", "nanostores-mcp"] } } }
{ "context_servers": { "nanostores": { "command": "npx", "args": ["-y", "nanostores-mcp"], "env": { "NANOSTORES_MCP_ROOT": "/path/to/your/project" } } } }

The server appears in Zed'sAgent Panelsettings.

Add to~/.codeium/windsurf/mcp_config.json:

{ "mcpServers": { "nanostores": { "command": "npx", "args": ["-y", "nanostores-mcp"], "env": { "NANOSTORES_MCP_ROOT": "/path/to/your/project" } } } }

You can also open this file from the MCP icon in the Cascade panel → "Configure".

claude mcp add --transport stdio nanostores -- npx -y nanostores-mcp

Or create.mcp.jsonin your project root (shared with the team):

{ "mcpServers": { "nanostores": { "command": "npx", "args": ["-y", "nanostores-mcp"], "env": { "NANOSTORES_MCP_ROOT": "/path/to/your/project" } } } }

The server picks workspace roots in priority order:
- Environment variables(highest priority) —NANOSTORES_MCP_ROOTS/NANOSTORES_MCP_ROOT/WORKSPACE_FOLDER_PATHS/WORKSPACE_FOLDER
- Client roots— roots reported by the MCP client via theroots/listcapability (set automatically by some editors)
- Current working directoryprocess.cwd()used as fallback when neither env nor client roots are configured

When a tool is called without an explicitprojectRootargument the server uses thefirst configured root. In a multi-root setup always passprojectRootto avoid ambiguity.

Works out of the box — just point at your project and ask:

- "Analyze my store architecture"
- "Explain how nanostores is used in this project"
- "Give me a summary of the $cart store"
- "My stores changed — re-scan the project"← the AI will force a fresh scan

Auto-detected fromnanostoresin yournode_modules:

- "How do I use computed stores?"
- "Show me the docs for persistentAtom"

Requires logger integration in your app. SeeRuntime Monitoringbelow.

- "Which stores update most frequently?"
- "Show me recent activity for $user"
- "Give me an overall health report"

Run these four tools in order to confirm everything is working:

Ifnanostores_scan_projectreturns zero stores, check thatNANOSTORES_MCP_ROOTpoints to the correct project directory.

Usenanostores://docs/page/{id}resource to read the full content of pages returned by search.

Most tools accept these optional arguments that significantly change their behavior:

For runtime analysis, integrate the MCP Logger client into your application.

1. Install in your app and enable the logger bridge:

The logger bridge starts automatically — no extra config needed. To disable it, setNANOSTORES_MCP_LOGGER_ENABLED=falsein your MCP server config.

2. Define stores with logger attached(src/stores.ts):

import { atom, map, computed } from "nanostores"; import { initMcpLogger, attachMcpLogger } from "nanostores-mcp/mcpLogger"; // Automatically disabled in production (checks NODE_ENV / import.meta.env.DEV) initMcpLogger(); // Stores export const $count = atom(0); export const $user = map({ name: "", role: "guest" }); export const $greeting = computed($user, user => Hello, ${user.name}); // Attach logger — each call returns a cleanup function attachMcpLogger($count, "$count"); attachMcpLogger($user, "$user"); attachMcpLogger($greeting, "$greeting");

3. Use stores normally— events (mount, unmount, change, actions) are captured automatically and batched to the MCP server every second.

- "Which stores change most frequently?"nanostores_find_noisy_stores
- "Show me recent activity for $user"nanostores_store_activity
- "Give me an overall health report"nanostores_runtime_overview

initMcpLogger({ url: "http://127.0.0.1:3999/nanostores-logger", // default; change if using a custom port batchMs: 1000, // default; lower for faster delivery (e.g. 200) projectRoot: "/absolute/path/to/project", // link runtime events with static analysis // Mask sensitive data — return null to skip event entirely maskEvent: event => { if (event.storeName === "authToken") return null; return event; }, });
import { getMcpLogger } from "nanostores-mcp/mcpLogger"; window.addEventListener("beforeunload", async () => { await getMcpLogger()?.forceFlush(); });

nanostores_runtime_overviewhealth summary

The overview groups stores into three categories:

- Top active stores— sorted by total event count (changes + actions). A store that appears here with hundreds of changes in seconds may be a performance concern.
- Error-prone stores— stores withaction-errorevents. High error counts indicate failing async actions.
- Unmounted stores— stores seen at mount but never unmounted. May indicate memory leaks.

Compares your static store graph against observed runtime events:

Returns stores ranked by total activity (changes + actions combined) within thewindowMsperiod. A store is considered "noisy" when its change frequency is disproportionately high relative to visible UI updates — use this to find re-render hotspots or thrashing computed chains.

The runtime logger is designed to stay on your local machine:

- Loopback-only binding— the HTTP bridge accepts connections exclusively from127.0.0.1,localhost, or::1. Binding to0.0.0.0is explicitly blocked. Data never leaves your machine.
- What is transmitted— from your app to the MCP server over localhost: store name, timestamp, event kind, and optionally value snapshots (truncated to 200 characters). Nothing is sent to Anthropic or any third party.
- Nothing is persisted— events are held in a ring buffer (5 000 events max) in process memory and discarded when the server restarts.
- Mask sensitive data— usemaskEventto filter or redact events client-side before they are batched and sent:

initMcpLogger({ maskEvent: event => { if (event.storeName === "$authToken") return null; // drop entirely if (event.storeName === "$paymentInfo") return { ...event, newValue: undefined }; // strip value return event; }, });

- CORS— the bridge rejects cross-origin requests from non-loopback origins.

Ask your AI assistant natural language questions:

- "Which stores update most frequently?"
- "Are there stores declared in code but never used at runtime?"
- "Debug the $user store — combine static analysis with runtime behavior"

- "Open my app in the browser, interact with it, and analyze which stores cause the most recalculations"

- "How do I use computed stores?"
- "Show me best practices for persistent stores"

┌──────────────────────┐ │ Your Application │ │ │ │ @nanostores/logger │ │ events │ └──────────┬───────────┘ │ HTTP POST (localhost:3999) ▼ ┌──────────────────────┐ │ nanostores-mcp │ │ │ │ ┌──────────────┐ │ │ │ Logger Bridge │ │ ← HTTP server for runtime events │ └──────┬───────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ Event Store │ │ ← Ring buffer (5000 events) + stats │ └──────┬───────┘ │ │ │ │ │ ┌──────┴───────┐ │ │ │ AST Scanner │ │ ← ts-morph static analysis │ └──────┬───────┘ │ │ │ │ │ ┌──────┴───────┐ │ │ │ Docs Index │ │ ← Auto-detected from node_modules │ └──────┬───────┘ │ │ │ │ │ ┌──────┴───────┐ │ │ │ MCP Interface│ │ ← Resources, Tools, Prompts │ └──────────────┘ │ └──────────┬───────────┘ │ MCP Protocol (stdio) ▼ ┌──────────────────────┐ │ LLM Client │ │ (Claude, VS Code, …) │ └──────────────────────┘

Multi-root: same store name in multiple projects

In multi-root mode a store named$usercan exist in two different projects. The runtime event store uses a composite key (projectRoot + storeName) to keep them separate, but summary views may show the same name twice with no project label. Always specifyprojectRootwhen querying tools in a multi-root setup to get unambiguous results.

Static analysis only covers discovered files

The AST scanner follows TypeScript/JavaScript imports from your project root. Stores created dynamically at runtime, generated by factories, or living innode_moduleswill not appear in static results — they may show up as "runtime-only" in coverage reports.

Vue and Svelte parsing requires optional dependencies

If@vue/compiler-sfcorsvelteare not installed,.vue/.sveltefiles are silently skipped during scanning. Install them as dev dependencies if you want full coverage for those file types.

Event ring buffer is capped at 5 000 events

Older events are dropped when the buffer is full. For high-frequency stores usewindowMsto narrow your queries to recent data, or lowerbatchMsininitMcpLoggerto deliver events more frequently and reduce the chance of buffer overflow during bursts.

Stores with many dependencies (hub score > 5) can return most of the project graph atradius=2. Start withradius=1and increase only if you need broader context.

git clone https://github.com/Valyay/nanostores-mcp.git cd nanostores-mcp pnpm install pnpm dev # Run dev server pnpm build # TypeScript compile pnpm test # Run vitest pnpm lint # ESLint pnpm check # All checks: lint + format + test + build # Test with MCP Inspector npx @modelcontextprotocol/inspector pnpm run dev

- Use thepingtool to verify logger bridge is enabled and running
- Check browser console for
[nanostores-mcp]warnings about connection issues
- Confirm the port matches between server (NANOSTORES_MCP_LOGGER_PORT) and client URL
- Test with a simple atom store to verify events flow

# Change server port NANOSTORES_MCP_LOGGER_PORT=4000 npx nanostores-mcp # Update client initMcpLogger({ url: "http://127.0.0.1:4000/nanostores-logger" });
// Import from the mcpLogger subpath export import { initMcpLogger, attachMcpLogger } from "nanostores-mcp/mcpLogger";

- The server auto-detects docs fromnanostoresin yournode_modules
- Make surenanostoresis installed:npm install nanostores
- Or setNANOSTORES_DOCS_ROOTto point at a docs directory manually

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.