statemap-mcp 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +138 -0
  2. package/dist/index.js +14 -8
  3. package/package.json +3 -2
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # statemap-mcp
2
+
3
+ MCP server for [Statemap](https://statemap.io) — system state working memory for AI coding agents.
4
+
5
+ Gives any MCP-compatible agent (Claude Code, Cursor, Windsurf, VS Code Copilot) native access to your project's state model. No context window loading required — agents call tools directly.
6
+
7
+ ## Setup
8
+
9
+ ### 1. Create a `.statemap` file in your repo root
10
+
11
+ ```json
12
+ {
13
+ "project_id": "your-project-id",
14
+ "base_url": "https://statemap.io"
15
+ }
16
+ ```
17
+
18
+ Get this from your project page — click **connect** in the header.
19
+
20
+ ### 2. Set your API key
21
+
22
+ ```sh
23
+ export STATEMAP_API_KEY="sm_your_key_here"
24
+ ```
25
+
26
+ Find your key at [statemap.io/app](https://statemap.io/app) under **API Key**. Add to `.env` or shell profile. Never commit this.
27
+
28
+ ### 3. Add to your editor
29
+
30
+ #### Claude Code
31
+
32
+ ```sh
33
+ claude mcp add statemap-mcp -e STATEMAP_API_KEY=sm_your_key_here -- npx -y statemap-mcp
34
+ ```
35
+
36
+ Or add to `.claude/mcp.json`:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "statemap": {
42
+ "command": "npx",
43
+ "args": ["-y", "statemap-mcp"],
44
+ "env": {
45
+ "STATEMAP_API_KEY": "sm_your_key_here"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ #### Cursor
53
+
54
+ Add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
55
+
56
+ ```json
57
+ {
58
+ "mcpServers": {
59
+ "statemap": {
60
+ "command": "npx",
61
+ "args": ["-y", "statemap-mcp"],
62
+ "env": {
63
+ "STATEMAP_API_KEY": "sm_your_key_here"
64
+ }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ #### Windsurf
71
+
72
+ Add to `~/.codeium/windsurf/mcp_config.json`:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "statemap": {
78
+ "command": "npx",
79
+ "args": ["-y", "statemap-mcp"],
80
+ "env": {
81
+ "STATEMAP_API_KEY": "sm_your_key_here"
82
+ }
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ #### VS Code Copilot
89
+
90
+ Add to `.vscode/mcp.json`:
91
+
92
+ ```json
93
+ {
94
+ "servers": {
95
+ "statemap": {
96
+ "command": "npx",
97
+ "args": ["-y", "statemap-mcp"],
98
+ "env": {
99
+ "STATEMAP_API_KEY": "sm_your_key_here"
100
+ }
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## Tools
107
+
108
+ | Tool | Description |
109
+ |------|-------------|
110
+ | `statemap_snapshot` | Load the full system state model |
111
+ | `statemap_query` | Natural language query ("what breaks if I remove X?") |
112
+ | `statemap_validate` | Check all invariant constraints pass |
113
+ | `statemap_divergence` | Check for internal consistency issues |
114
+ | `statemap_update_model` | Create or update a data model |
115
+ | `statemap_update_container` | Create or update a state container |
116
+ | `statemap_update_transition` | Create or update a state transition |
117
+ | `statemap_add_invariant` | Add a constraint |
118
+ | `statemap_update_read_deps` | Create or update read dependencies |
119
+ | `statemap_import` | Bulk import entities |
120
+ | `statemap_analyze` | Submit source files for drift detection |
121
+
122
+ ## Environment Variables
123
+
124
+ | Variable | Required | Description |
125
+ |----------|----------|-------------|
126
+ | `STATEMAP_API_KEY` | Yes | Your Statemap API key (`sm_...`) |
127
+ | `STATEMAP_PROJECT_ID` | No | Override project ID (default: from `.statemap`) |
128
+ | `STATEMAP_BASE_URL` | No | Override base URL (default: from `.statemap` or `https://statemap.io`) |
129
+
130
+ ## How It Works
131
+
132
+ The MCP server is a thin wrapper around the [Statemap REST API](https://statemap.io). Each tool maps to one API call. The server reads `.statemap` from your working directory for the project ID and base URL, authenticates with `STATEMAP_API_KEY` from your environment, and communicates over stdio.
133
+
134
+ Agents use it to check existing state before writing code, update the model after changes, and validate constraints before merging — all without you manually loading anything into context.
135
+
136
+ ## License
137
+
138
+ MIT
package/dist/index.js CHANGED
@@ -7,8 +7,7 @@ import { resolve } from "node:path";
7
7
  function loadConfig() {
8
8
  const apiKey = process.env.STATEMAP_API_KEY;
9
9
  if (!apiKey) {
10
- process.stderr.write("STATEMAP_API_KEY environment variable is required\n");
11
- process.exit(1);
10
+ return { error: "STATEMAP_API_KEY environment variable is required. Get your key at https://statemap.io/app" };
12
11
  }
13
12
  let projectId = process.env.STATEMAP_PROJECT_ID || "";
14
13
  let baseUrl = process.env.STATEMAP_BASE_URL || "https://statemap.io";
@@ -25,18 +24,20 @@ function loadConfig() {
25
24
  // .statemap file not found — rely on env vars
26
25
  }
27
26
  if (!projectId) {
28
- process.stderr.write("Project ID required: set in .statemap file or STATEMAP_PROJECT_ID env var\n");
29
- process.exit(1);
27
+ return { error: "Project ID required: add a .statemap file to your repo root or set STATEMAP_PROJECT_ID env var. See https://statemap.io" };
30
28
  }
31
29
  return { projectId, baseUrl: baseUrl.replace(/\/$/, ""), apiKey };
32
30
  }
33
- async function api(config, path, opts) {
34
- const url = `${config.baseUrl}/api/projects/${config.projectId}${path}`;
31
+ async function api(cfg, path, opts) {
32
+ const err = checkConfig();
33
+ if (err)
34
+ throw new Error(err);
35
+ const url = `${cfg.baseUrl}/api/projects/${cfg.projectId}${path}`;
35
36
  const res = await fetch(url, {
36
37
  ...opts,
37
38
  headers: {
38
39
  "Content-Type": "application/json",
39
- "Authorization": `Bearer ${config.apiKey}`,
40
+ "Authorization": `Bearer ${cfg.apiKey}`,
40
41
  "X-Agent-Id": "mcp-server",
41
42
  ...opts?.headers,
42
43
  },
@@ -60,11 +61,16 @@ async function api(config, path, opts) {
60
61
  function text(data) {
61
62
  return { content: [{ type: "text", text: typeof data === "string" ? data : JSON.stringify(data, null, 2) }] };
62
63
  }
63
- const config = loadConfig();
64
+ const loaded = loadConfig();
65
+ const configError = "error" in loaded ? loaded.error : null;
66
+ const config = "error" in loaded ? { projectId: "", baseUrl: "", apiKey: "" } : loaded;
64
67
  const server = new McpServer({
65
68
  name: "statemap",
66
69
  version: "0.1.0",
67
70
  });
71
+ function checkConfig() {
72
+ return configError;
73
+ }
68
74
  server.tool("statemap_snapshot", "Load the full system state model — all models, containers, transitions, invariants, and read dependencies", async () => {
69
75
  const data = await api(config, "/snapshot");
70
76
  return text(data);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statemap-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server for Statemap — system state working memory for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,7 +12,8 @@
12
12
  "dev": "tsc --watch"
13
13
  },
14
14
  "files": [
15
- "dist"
15
+ "dist",
16
+ "README.md"
16
17
  ],
17
18
  "dependencies": {
18
19
  "@modelcontextprotocol/sdk": "^1.12.1",