midnight-mcp 0.1.8 → 0.1.9

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.
package/README.md CHANGED
@@ -10,113 +10,86 @@ MCP server that gives AI assistants access to Midnight blockchain—search contr
10
10
 
11
11
  ## Quick Start
12
12
 
13
- ### Claude Desktop
14
-
15
- Add to your `claude_desktop_config.json`:
13
+ **Claude Desktop** — Add to `claude_desktop_config.json`:
16
14
 
17
15
  ```json
18
16
  {
19
17
  "mcpServers": {
20
- "midnight": {
21
- "command": "npx",
22
- "args": ["-y", "midnight-mcp"]
23
- }
18
+ "midnight": { "command": "npx", "args": ["-y", "midnight-mcp"] }
24
19
  }
25
20
  }
26
21
  ```
27
22
 
28
- <details>
29
- <summary><strong>Config file locations</strong></summary>
30
-
31
- - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
32
- - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
33
- - **Linux**: `~/.config/Claude/claude_desktop_config.json`
34
-
35
- </details>
36
-
37
- ### Cursor
38
-
39
- **Click the button to auto install the MCP for Cursor**
23
+ **Cursor** — One-click install:
40
24
 
41
25
  [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=midnight&config=eyJjb21tYW5kIjoibnB4IC15IG1pZG5pZ2h0LW1jcCJ9)
42
26
 
43
- ---
44
-
45
- **Manual setup instructions are below if you need them:**
27
+ <details>
28
+ <summary><strong>Other Editors (Windsurf, VS Code Copilot, Manual Setup)</strong></summary>
46
29
 
47
- Add to Cursor's MCP settings (Settings → MCP → Add Server):
30
+ **Windsurf** — Add to `~/.codeium/windsurf/mcp_config.json`:
48
31
 
49
32
  ```json
50
33
  {
51
34
  "mcpServers": {
52
- "midnight": {
53
- "command": "npx",
54
- "args": ["-y", "midnight-mcp"]
55
- }
35
+ "midnight": { "command": "npx", "args": ["-y", "midnight-mcp"] }
56
36
  }
57
37
  }
58
38
  ```
59
39
 
60
- Or add to `.cursor/mcp.json` in your project:
40
+ **VS Code Copilot** — Add to `.vscode/mcp.json` or use Command Palette: `MCP: Add Server` → "command (stdio)" → `npx -y midnight-mcp`
61
41
 
62
42
  ```json
63
43
  {
64
44
  "mcpServers": {
65
- "midnight": {
66
- "command": "npx",
67
- "args": ["-y", "midnight-mcp"]
68
- }
45
+ "midnight": { "command": "npx", "args": ["-y", "midnight-mcp"] }
69
46
  }
70
47
  }
71
48
  ```
72
49
 
73
- ### Windsurf
74
-
75
- Add to `~/.codeium/windsurf/mcp_config.json`:
50
+ **Cursor Manual** — Settings → MCP → Add Server, or add to `.cursor/mcp.json`:
76
51
 
77
52
  ```json
78
53
  {
79
54
  "mcpServers": {
80
- "midnight": {
81
- "command": "npx",
82
- "args": ["-y", "midnight-mcp"]
83
- }
55
+ "midnight": { "command": "npx", "args": ["-y", "midnight-mcp"] }
84
56
  }
85
57
  }
86
58
  ```
87
59
 
88
- ### VS Code Copilot
60
+ **Config file locations (Claude Desktop):**
89
61
 
90
- Add to your VS Code settings (`.vscode/mcp.json` in your workspace or user settings):
62
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
63
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
64
+ - Linux: `~/.config/Claude/claude_desktop_config.json`
91
65
 
92
- ```json
93
- {
94
- "mcpServers": {
95
- "midnight": {
96
- "command": "npx",
97
- "args": ["-y", "midnight-mcp"]
98
- }
99
- }
100
- }
101
- ```
66
+ </details>
102
67
 
103
- Or via Command Palette: `MCP: Add Server` select "command (stdio)" → enter `npx -y midnight-mcp`
68
+ Restart your editor after adding the config. **No API keys required.**
69
+
70
+ > **Quality Metrics**: To ensure the MCP stays accurate as Midnight's codebase evolves rapidly, we collect anonymous usage metrics (query counts, relevance scores) to monitor search quality. No query content or personal data is stored. This helps us identify when re-indexing is needed and improve results over time.
104
71
 
105
72
  ---
106
73
 
107
- Restart your editor after adding the config. All features work out of the box—no API keys or setup required.
74
+ ## Features
108
75
 
109
- ---
76
+ **19 Tools** — Search, analyze, version tracking, AI generation
110
77
 
111
- ## How It Works
78
+ | Category | Tools |
79
+ | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
80
+ | Search | `midnight-search-compact`, `midnight-search-typescript`, `midnight-search-docs` |
81
+ | Analysis | `midnight-analyze-contract`, `midnight-explain-circuit` |
82
+ | Repository | `midnight-get-file`, `midnight-list-examples`, `midnight-get-latest-updates` |
83
+ | Versioning | `midnight-get-version-info`, `midnight-check-breaking-changes`, `midnight-get-migration-guide`, `midnight-get-file-at-version`, `midnight-compare-syntax`, `midnight-get-latest-syntax` |
84
+ | AI Generation | `midnight-generate-contract`, `midnight-review-contract`, `midnight-document-contract` |
85
+ | Status | `midnight-health-check`, `midnight-get-status` |
112
86
 
113
- By default, the MCP uses a **hosted API** for semantic search:
87
+ **9 Embedded Resources** Quick references available offline: Compact syntax, SDK API, OpenZeppelin contracts, tokenomics, wallet integration, common errors
114
88
 
115
- - **Zero configuration** — just install and use
116
- - **Semantic search** works immediately
117
- - **No API keys** needed
89
+ **5 Prompts** — `create-contract`, `review-contract`, `explain-concept`, `compare-approaches`, `debug-contract`
118
90
 
119
- > **Quality Metrics**: To ensure the MCP stays accurate as Midnight's codebase evolves rapidly, we collect anonymous usage metrics (query counts, relevance scores) to monitor search quality. No query content or personal data is stored. This helps us identify when re-indexing is needed and improve results over time.
91
+ <details>
92
+ <summary><strong>Advanced Configuration</strong></summary>
120
93
 
121
94
  ### Local Mode (Optional)
122
95
 
@@ -138,171 +111,58 @@ Run everything locally for privacy or offline use:
138
111
  }
139
112
  ```
140
113
 
141
- Local mode requires ChromaDB (`docker run -d -p 8000:8000 chromadb/chroma`) and an OpenAI API key.
114
+ Requires ChromaDB (`docker run -d -p 8000:8000 chromadb/chroma`) and OpenAI API key.
142
115
 
143
116
  ### GitHub Token (Optional)
144
117
 
145
118
  Add `"GITHUB_TOKEN": "ghp_..."` for higher GitHub API rate limits (60 → 5000 requests/hour).
146
119
 
120
+ </details>
121
+
147
122
  ---
148
123
 
149
- ## Features
124
+ ## Indexed Repositories
125
+
126
+ The API indexes **22+ Midnight repositories**:
150
127
 
151
- ### Tools (19)
152
-
153
- | Tool | Description |
154
- | --------------------------------- | ------------------------------------------- |
155
- | `midnight-search-compact` | Search Compact contract code |
156
- | `midnight-search-typescript` | Search TypeScript SDK |
157
- | `midnight-search-docs` | Search documentation |
158
- | `midnight-analyze-contract` | Analyze contract structure and security |
159
- | `midnight-explain-circuit` | Explain circuits in plain language |
160
- | `midnight-get-file` | Get files from Midnight repos |
161
- | `midnight-list-examples` | List example contracts |
162
- | `midnight-get-latest-updates` | Recent repo changes |
163
- | `midnight-get-version-info` | Get version and release info |
164
- | `midnight-check-breaking-changes` | Check for breaking changes |
165
- | `midnight-get-migration-guide` | Migration guides between versions |
166
- | `midnight-get-file-at-version` | Get file at specific version |
167
- | `midnight-compare-syntax` | Compare files between versions |
168
- | `midnight-get-latest-syntax` | Latest syntax reference |
169
- | `midnight-health-check` | Check server health status |
170
- | `midnight-get-status` | Get rate limits and cache stats |
171
- | `midnight-generate-contract` | AI-generate contracts from natural language |
172
- | `midnight-review-contract` | AI-powered security review of contracts |
173
- | `midnight-document-contract` | AI-generate documentation for contracts |
174
-
175
- > **Note:** The AI-powered tools require a client with [MCP Sampling](https://spec.modelcontextprotocol.io/specification/client/sampling/) support (e.g., Claude Desktop). Without sampling, these tools will return a helpful message instead.
176
-
177
- ### Resource Templates (4)
178
-
179
- Dynamic access to any resource using URI templates:
180
-
181
- | Template | Description |
182
- | --------------------------------------- | ------------------------------ |
183
- | `midnight://code/{owner}/{repo}/{path}` | Any code file from any repo |
184
- | `midnight://docs/{section}/{topic}` | Documentation by section/topic |
185
- | `midnight://examples/{category}/{name}` | Example contracts by category |
186
- | `midnight://schema/{type}` | JSON schemas (AST, tx, proofs) |
187
-
188
- ### Embedded Resources (9)
189
-
190
- Curated documentation that's always available without network calls:
191
-
192
- | URI | Description |
193
- | --------------------------------------- | --------------------------------------- |
194
- | `midnight://docs/compact-reference` | Compact syntax quick reference |
195
- | `midnight://docs/sdk-api` | TypeScript SDK API reference |
196
- | `midnight://docs/openzeppelin` | OpenZeppelin Compact contracts overview |
197
- | `midnight://docs/openzeppelin/token` | FungibleToken standard |
198
- | `midnight://docs/openzeppelin/access` | Access control patterns |
199
- | `midnight://docs/openzeppelin/security` | Security patterns (Pausable) |
200
- | `midnight://docs/tokenomics` | NIGHT/DUST tokenomics summary |
201
- | `midnight://docs/wallet-integration` | DApp Connector API guide |
202
- | `midnight://docs/common-errors` | Common errors & troubleshooting |
203
-
204
- > **Note:** For comprehensive docs (glossary, Zswap, Kachina, etc.), use the `midnight-search-docs` tool which queries the full indexed documentation.
205
-
206
- ### Prompts (5)
207
-
208
- - `midnight:create-contract` — Create new contracts
209
- - `midnight:review-contract` — Security review
210
- - `midnight:explain-concept` — Learn Midnight concepts
211
- - `midnight:compare-approaches` — Compare implementation approaches
212
- - `midnight:debug-contract` — Debug issues
128
+ | Category | Repositories |
129
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
130
+ | Core | `compact`, `midnight-js`, `midnight-wallet`, `midnight-docs` |
131
+ | Examples | `example-counter`, `example-bboard`, `example-dex`, `create-mn-app` |
132
+ | Infrastructure | `midnight-indexer`, `midnight-node-docker`, `midnight-dapp-connector-api` |
133
+ | Partner Libraries | `OpenZeppelin/compact-contracts`, `OpenZeppelin/midnight-apps` |
134
+ | Official Partners | `bricktowers/midnight-seabattle`, `bricktowers/midnight-identity`, `bricktowers/midnight-rwa`, `MeshJS/midnight-starter-template`, `midnames/core` |
213
135
 
214
136
  ---
215
137
 
216
138
  ## Developer Setup
217
139
 
218
- For contributors:
219
-
220
140
  ```bash
221
- git clone https://github.com/Olanetsoft/midnight-mcp.git
222
- cd midnight-mcp
223
- npm install
224
- npm run build
225
- npm test
141
+ git clone https://github.com/Olanetsoft/midnight-mcp.git && cd midnight-mcp
142
+ npm install && npm run build && npm test
226
143
  ```
227
144
 
228
- ### Testing with Local API
145
+ <details>
146
+ <summary><strong>API Backend & Local Development</strong></summary>
147
+
148
+ The hosted API runs on Cloudflare Workers + Vectorize. See [api/README.md](./api/README.md).
229
149
 
230
- To test against a local API server instead of production:
150
+ **Testing with Local API:**
231
151
 
232
152
  ```bash
233
153
  # Terminal 1: Start local API
234
- cd api
235
- npm install
236
- npm run dev # Starts at http://localhost:8787
154
+ cd api && npm install && npm run dev
237
155
 
238
156
  # Terminal 2: Run MCP with local API
239
157
  MIDNIGHT_API_URL=http://localhost:8787 npm start
240
158
  ```
241
159
 
242
- ### API Backend
243
-
244
- The hosted API runs on Cloudflare Workers + Vectorize. See [api/README.md](./api/README.md) for deployment and development instructions.
245
-
246
- ### Search Quality
247
-
248
- The API indexes **16 Midnight repositories** including core infrastructure, SDK, examples, and developer tools:
249
-
250
- | Repository | Description |
251
- | -------------------------------- | ---------------------------------------------- |
252
- | `compact` | Compact language compiler and standard library |
253
- | `midnight-js` | TypeScript SDK |
254
- | `midnight-docs` | Official documentation |
255
- | `example-counter` | Simple counter DApp example |
256
- | `example-bboard` | Bulletin board DApp example |
257
- | `example-dex` | DEX DApp example |
258
- | `create-mn-app` | Project scaffolding CLI |
259
- | `midnight-wallet` | Wallet implementation |
260
- | `midnight-indexer` | Blockchain indexer |
261
- | `midnight-node-docker` | Node Docker setup |
262
- | `midnight-dapp-connector-api` | Wallet connector API |
263
- | `compact-tree-sitter` | Syntax highlighting support |
264
- | `setup-compact-action` | GitHub Action for CI/CD |
265
- | `midnight-awesome-dapps` | Curated DApp list |
266
- | `contributor-hub` | Contributor resources |
267
- | `OpenZeppelin/compact-contracts` | OpenZeppelin Compact library |
268
-
269
- Search quality techniques:
160
+ </details>
270
161
 
271
- - **Optimized chunking** — 1000-char chunks with 200-char overlap for precise, contextual results
272
- - **Hybrid search** — Combines vector similarity with keyword boosting (up to 20% boost for exact matches)
273
- - **Incremental indexing** — Daily updates via tarball download + batch embeddings (~5 min)
162
+ ## Links
274
163
 
275
- View live metrics at the [Dashboard](https://midnight-mcp-api.midnightmcp.workers.dev/dashboard).
164
+ - [Midnight Docs](https://docs.midnight.network) [MCP Spec](https://modelcontextprotocol.io) • [Midnight GitHub](https://github.com/midnightntwrk)
276
165
 
277
166
  ## License
278
167
 
279
168
  MIT
280
-
281
- ## Changelog
282
-
283
- ### v0.1.7
284
-
285
- - Added `setup-compact-action` repository to indexed sources
286
- - New aliases: `setup-compact`, `compact-action`, `tree-sitter`
287
-
288
- ### v0.1.6
289
-
290
- - Fixed bug where tools crashed with "Cannot read properties of undefined" when repo param was omitted
291
-
292
- ### v0.1.5
293
-
294
- - Added `common-errors` embedded resource with verified troubleshooting guide
295
- - Added comprehensive search tool tests
296
- - Refactored to follow MCP best practices (tools over embedded knowledge)
297
-
298
- ### v0.1.4
299
-
300
- - Initial stable release with 19 tools, 9 embedded resources, 5 prompts
301
- - Hosted API with zero-config semantic search
302
- - Support for Claude Desktop, Cursor, and Windsurf
303
-
304
- ## Links
305
-
306
- - [Midnight Docs](https://docs.midnight.network)
307
- - [MCP Spec](https://modelcontextprotocol.io)
308
- - [Midnight GitHub](https://github.com/midnightntwrk)
@@ -141,8 +141,10 @@ export async function getLatestUpdates(input) {
141
141
  * Get version and release info for a repository
142
142
  */
143
143
  export async function getVersionInfo(input) {
144
- logger.debug("Getting version info", input);
145
- const resolved = resolveRepo(input.repo);
144
+ // Ensure repo defaults to compact if undefined/empty
145
+ const repoName = input?.repo || "compact";
146
+ logger.debug("Getting version info", { repo: repoName });
147
+ const resolved = resolveRepo(repoName);
146
148
  if (!resolved) {
147
149
  throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
148
150
  }
@@ -170,10 +172,15 @@ export async function getVersionInfo(input) {
170
172
  * Check for breaking changes since a specific version
171
173
  */
172
174
  export async function checkBreakingChanges(input) {
173
- logger.debug("Checking breaking changes", input);
174
- const resolved = resolveRepo(input.repo);
175
+ // Ensure repo defaults to compact if undefined/empty
176
+ const repoName = input?.repo || "compact";
177
+ logger.debug("Checking breaking changes", {
178
+ repo: repoName,
179
+ currentVersion: input.currentVersion,
180
+ });
181
+ const resolved = resolveRepo(repoName);
175
182
  if (!resolved) {
176
- throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
183
+ throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
177
184
  }
178
185
  const outdatedInfo = await releaseTracker.isOutdated(resolved.owner, resolved.repo, input.currentVersion);
179
186
  const breakingChanges = await releaseTracker.getBreakingChangesSince(resolved.owner, resolved.repo, input.currentVersion);
@@ -196,10 +203,16 @@ export async function checkBreakingChanges(input) {
196
203
  * Get migration guide between versions
197
204
  */
198
205
  export async function getMigrationGuide(input) {
199
- logger.debug("Getting migration guide", input);
200
- const resolved = resolveRepo(input.repo);
206
+ // Ensure repo defaults to compact if undefined/empty
207
+ const repoName = input?.repo || "compact";
208
+ logger.debug("Getting migration guide", {
209
+ repo: repoName,
210
+ fromVersion: input.fromVersion,
211
+ toVersion: input.toVersion,
212
+ });
213
+ const resolved = resolveRepo(repoName);
201
214
  if (!resolved) {
202
- throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
215
+ throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
203
216
  }
204
217
  const guide = await releaseTracker.getMigrationGuide(resolved.owner, resolved.repo, input.fromVersion, input.toVersion);
205
218
  return {
@@ -226,14 +239,20 @@ export async function getMigrationGuide(input) {
226
239
  * Get a file at a specific version - critical for version-accurate recommendations
227
240
  */
228
241
  export async function getFileAtVersion(input) {
229
- logger.debug("Getting file at version", input);
230
- const resolved = resolveRepo(input.repo);
242
+ // Ensure repo defaults to compact if undefined/empty
243
+ const repoName = input?.repo || "compact";
244
+ logger.debug("Getting file at version", {
245
+ repo: repoName,
246
+ path: input.path,
247
+ version: input.version,
248
+ });
249
+ const resolved = resolveRepo(repoName);
231
250
  if (!resolved) {
232
- throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
251
+ throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
233
252
  }
234
253
  const result = await releaseTracker.getFileAtVersion(resolved.owner, resolved.repo, input.path, input.version);
235
254
  if (!result) {
236
- throw new Error(`File not found: ${input.path} at version ${input.version} in ${input.repo}`);
255
+ throw new Error(`File not found: ${input.path} at version ${input.version} in ${repoName}`);
237
256
  }
238
257
  return {
239
258
  repository: `${resolved.owner}/${resolved.repo}`,
@@ -247,10 +266,16 @@ export async function getFileAtVersion(input) {
247
266
  * Compare syntax between two versions - shows what changed
248
267
  */
249
268
  export async function compareSyntax(input) {
250
- logger.debug("Comparing syntax between versions", input);
251
- const resolved = resolveRepo(input.repo);
269
+ // Ensure repo defaults to compact if undefined/empty
270
+ const repoName = input?.repo || "compact";
271
+ logger.debug("Comparing syntax between versions", {
272
+ repo: repoName,
273
+ oldVersion: input.oldVersion,
274
+ newVersion: input.newVersion,
275
+ });
276
+ const resolved = resolveRepo(repoName);
252
277
  if (!resolved) {
253
- throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
278
+ throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
254
279
  }
255
280
  // If no newVersion specified, get latest
256
281
  let newVersion = input.newVersion;
@@ -280,10 +305,12 @@ export async function compareSyntax(input) {
280
305
  * This is the source of truth for writing valid, compilable contracts
281
306
  */
282
307
  export async function getLatestSyntax(input) {
283
- logger.debug("Getting latest syntax reference", input);
284
- const resolved = resolveRepo(input.repo);
308
+ // Ensure repo defaults to compact if undefined/empty
309
+ const repoName = input?.repo || "compact";
310
+ logger.debug("Getting latest syntax reference", { repo: repoName });
311
+ const resolved = resolveRepo(repoName);
285
312
  if (!resolved) {
286
- throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
313
+ throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
287
314
  }
288
315
  const reference = await releaseTracker.getLatestSyntaxReference(resolved.owner, resolved.repo);
289
316
  if (!reference || reference.syntaxFiles.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",