midnight-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.
@@ -1,6 +1,6 @@
1
1
  export { documentationResources, getDocumentation, listDocumentationResources, } from "./docs.js";
2
- export { codeResources, getCode, listCodeResources, } from "./code.js";
3
- export { schemaResources, getSchema, listSchemaResources, } from "./schemas.js";
4
- export type { ResourceDefinition } from "./docs.js";
5
- export declare const allResources: import("./docs.js").ResourceDefinition[];
2
+ export { codeResources, getCode, listCodeResources } from "./code.js";
3
+ export { schemaResources, getSchema, listSchemaResources } from "./schemas.js";
4
+ export type { ResourceDefinition } from "./schemas.js";
5
+ export declare const allResources: import("./schemas.js").ResourceDefinition[];
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  export { documentationResources, getDocumentation, listDocumentationResources, } from "./docs.js";
2
- export { codeResources, getCode, listCodeResources, } from "./code.js";
3
- export { schemaResources, getSchema, listSchemaResources, } from "./schemas.js";
2
+ export { codeResources, getCode, listCodeResources } from "./code.js";
3
+ export { schemaResources, getSchema, listSchemaResources } from "./schemas.js";
4
4
  // Combine all resources
5
5
  import { documentationResources } from "./docs.js";
6
6
  import { codeResources } from "./code.js";
package/dist/server.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ /**
3
+ * Clear all subscriptions (useful for server restart/testing)
4
+ */
5
+ export declare function clearSubscriptions(): void;
2
6
  /**
3
7
  * Create and configure the MCP server
4
8
  */
package/dist/server.js CHANGED
@@ -15,6 +15,13 @@ const SERVER_INFO = {
15
15
  };
16
16
  // Resource subscriptions tracking
17
17
  const resourceSubscriptions = new Set();
18
+ /**
19
+ * Clear all subscriptions (useful for server restart/testing)
20
+ */
21
+ export function clearSubscriptions() {
22
+ resourceSubscriptions.clear();
23
+ logger.debug("Subscriptions cleared");
24
+ }
18
25
  // Resource templates for parameterized resources (RFC 6570 URI Templates)
19
26
  const resourceTemplates = [
20
27
  {
@@ -295,7 +302,7 @@ function registerSubscriptionHandlers(server) {
295
302
  const isValid = validPrefixes.some((prefix) => uri.startsWith(prefix));
296
303
  if (!isValid) {
297
304
  logger.warn(`Invalid subscription URI: ${uri}`);
298
- return {};
305
+ throw new Error(`Invalid subscription URI: ${uri}. Valid prefixes: ${validPrefixes.join(", ")}`);
299
306
  }
300
307
  resourceSubscriptions.add(uri);
301
308
  logger.debug(`Active subscriptions: ${resourceSubscriptions.size}`);
@@ -355,7 +362,17 @@ function setupSampling(server) {
355
362
  },
356
363
  // Use a schema that matches the expected response
357
364
  {
358
- parse: (data) => data,
365
+ parse: (data) => {
366
+ const response = data;
367
+ // Basic validation of expected response structure
368
+ if (!response || typeof response !== "object") {
369
+ throw new Error("Invalid sampling response: expected object");
370
+ }
371
+ if (!response.content || typeof response.content !== "object") {
372
+ throw new Error("Invalid sampling response: missing content");
373
+ }
374
+ return response;
375
+ },
359
376
  _def: { typeName: "SamplingResponse" },
360
377
  });
361
378
  return response;
@@ -191,10 +191,31 @@ Respond in JSON format:
191
191
  maxTokens: 4096,
192
192
  temperature: 0.2,
193
193
  });
194
- // Parse JSON response
194
+ // Parse JSON response with error handling
195
195
  const jsonMatch = response.match(/\{[\s\S]*\}/);
196
196
  if (jsonMatch) {
197
- return JSON.parse(jsonMatch[0]);
197
+ try {
198
+ const parsed = JSON.parse(jsonMatch[0]);
199
+ // Validate expected structure
200
+ return {
201
+ summary: typeof parsed.summary === "string"
202
+ ? parsed.summary
203
+ : "Review complete",
204
+ issues: Array.isArray(parsed.issues) ? parsed.issues : [],
205
+ improvedCode: typeof parsed.improvedCode === "string"
206
+ ? parsed.improvedCode
207
+ : undefined,
208
+ };
209
+ }
210
+ catch (parseError) {
211
+ logger.warn("Failed to parse JSON from LLM response", {
212
+ error: String(parseError),
213
+ });
214
+ return {
215
+ summary: response,
216
+ issues: [],
217
+ };
218
+ }
198
219
  }
199
220
  return {
200
221
  summary: response,
@@ -230,46 +230,77 @@ function getPrivacyConsiderations(circuit) {
230
230
  }
231
231
  return considerations;
232
232
  }
233
- // Output schemas for analysis tools
233
+ // Output schemas for analysis tools - aligned with actual function return types
234
234
  const analyzeContractOutputSchema = {
235
235
  type: "object",
236
236
  properties: {
237
- name: { type: "string", description: "Contract name" },
238
- summary: { type: "string", description: "Brief contract summary" },
239
- ledgerState: {
240
- type: "array",
241
- description: "Ledger state fields",
242
- items: {
243
- type: "object",
244
- properties: {
245
- name: { type: "string" },
246
- type: { type: "string" },
247
- isPrivate: { type: "boolean" },
248
- },
237
+ summary: {
238
+ type: "object",
239
+ description: "Summary statistics of the contract",
240
+ properties: {
241
+ hasLedger: { type: "boolean" },
242
+ hasCircuits: { type: "boolean" },
243
+ hasWitnesses: { type: "boolean" },
244
+ totalLines: { type: "number" },
245
+ publicCircuits: { type: "number" },
246
+ privateCircuits: { type: "number" },
247
+ publicState: { type: "number" },
248
+ privateState: { type: "number" },
249
249
  },
250
250
  },
251
- circuits: {
252
- type: "array",
253
- description: "Circuit definitions",
254
- items: {
255
- type: "object",
256
- properties: {
257
- name: { type: "string" },
258
- isPublic: { type: "boolean" },
259
- parameters: { type: "array", items: { type: "object" } },
260
- purpose: { type: "string" },
251
+ structure: {
252
+ type: "object",
253
+ description: "Contract structure breakdown",
254
+ properties: {
255
+ imports: { type: "array", items: { type: "string" } },
256
+ exports: { type: "array", items: { type: "string" } },
257
+ ledger: {
258
+ type: "array",
259
+ description: "Ledger state fields",
260
+ items: {
261
+ type: "object",
262
+ properties: {
263
+ name: { type: "string" },
264
+ type: { type: "string" },
265
+ isPrivate: { type: "boolean" },
266
+ },
267
+ },
261
268
  },
262
- },
263
- },
264
- witnesses: {
265
- type: "array",
266
- description: "Witness functions",
267
- items: {
268
- type: "object",
269
- properties: {
270
- name: { type: "string" },
271
- returnType: { type: "string" },
272
- purpose: { type: "string" },
269
+ circuits: {
270
+ type: "array",
271
+ description: "Circuit definitions",
272
+ items: {
273
+ type: "object",
274
+ properties: {
275
+ name: { type: "string" },
276
+ isPublic: { type: "boolean" },
277
+ parameters: { type: "array", items: { type: "object" } },
278
+ returnType: { type: "string" },
279
+ },
280
+ },
281
+ },
282
+ witnesses: {
283
+ type: "array",
284
+ description: "Witness functions",
285
+ items: {
286
+ type: "object",
287
+ properties: {
288
+ name: { type: "string" },
289
+ parameters: { type: "array", items: { type: "object" } },
290
+ returnType: { type: "string" },
291
+ },
292
+ },
293
+ },
294
+ types: {
295
+ type: "array",
296
+ description: "Type definitions",
297
+ items: {
298
+ type: "object",
299
+ properties: {
300
+ name: { type: "string" },
301
+ definition: { type: "string" },
302
+ },
303
+ },
273
304
  },
274
305
  },
275
306
  },
@@ -294,31 +325,14 @@ const analyzeContractOutputSchema = {
294
325
  description: "Recommendations for improvement",
295
326
  },
296
327
  },
297
- required: ["summary", "circuits"],
328
+ required: ["summary", "structure", "securityFindings", "recommendations"],
298
329
  description: "Detailed contract analysis with security findings",
299
330
  };
300
331
  const explainCircuitOutputSchema = {
301
332
  type: "object",
302
333
  properties: {
303
- name: { type: "string", description: "Circuit name" },
304
- type: {
305
- type: "string",
306
- description: "Type: circuit or witness",
307
- },
334
+ circuitName: { type: "string", description: "Circuit name" },
308
335
  isPublic: { type: "boolean", description: "Whether it's exported" },
309
- plainEnglishExplanation: {
310
- type: "string",
311
- description: "Plain language explanation",
312
- },
313
- zkProofImplications: {
314
- type: "string",
315
- description: "Zero-knowledge proof implications",
316
- },
317
- privacyConsiderations: {
318
- type: "array",
319
- items: { type: "string" },
320
- description: "Privacy-related considerations",
321
- },
322
336
  parameters: {
323
337
  type: "array",
324
338
  items: {
@@ -326,13 +340,37 @@ const explainCircuitOutputSchema = {
326
340
  properties: {
327
341
  name: { type: "string" },
328
342
  type: { type: "string" },
329
- description: { type: "string" },
330
343
  },
331
344
  },
345
+ description: "Circuit parameters",
346
+ },
347
+ returnType: { type: "string", description: "Return type" },
348
+ explanation: {
349
+ type: "string",
350
+ description: "Plain language explanation",
351
+ },
352
+ operations: {
353
+ type: "array",
354
+ items: { type: "string" },
355
+ description: "Operations performed by the circuit",
356
+ },
357
+ zkImplications: {
358
+ type: "array",
359
+ items: { type: "string" },
360
+ description: "Zero-knowledge proof implications",
361
+ },
362
+ privacyConsiderations: {
363
+ type: "array",
364
+ items: { type: "string" },
365
+ description: "Privacy-related considerations",
332
366
  },
333
- returnType: { type: "string" },
334
367
  },
335
- required: ["name", "plainEnglishExplanation"],
368
+ required: [
369
+ "circuitName",
370
+ "explanation",
371
+ "zkImplications",
372
+ "privacyConsiderations",
373
+ ],
336
374
  description: "Detailed circuit explanation with privacy analysis",
337
375
  };
338
376
  // Tool definitions for MCP
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Repository constants
3
+ * Aliases, example definitions, and configuration data
4
+ */
5
+ export declare const REPO_ALIASES: Record<string, {
6
+ owner: string;
7
+ repo: string;
8
+ }>;
9
+ export interface ExampleDefinition {
10
+ name: string;
11
+ repository: string;
12
+ description: string;
13
+ category: string;
14
+ complexity: "beginner" | "intermediate" | "advanced";
15
+ mainFile: string;
16
+ features: string[];
17
+ }
18
+ export declare const EXAMPLES: ExampleDefinition[];
19
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Repository constants
3
+ * Aliases, example definitions, and configuration data
4
+ */
5
+ // Repository name mapping
6
+ export const REPO_ALIASES = {
7
+ // Core Language & SDK
8
+ compact: { owner: "midnightntwrk", repo: "compact" },
9
+ "midnight-js": { owner: "midnightntwrk", repo: "midnight-js" },
10
+ js: { owner: "midnightntwrk", repo: "midnight-js" },
11
+ sdk: { owner: "midnightntwrk", repo: "midnight-js" },
12
+ // Documentation
13
+ docs: { owner: "midnightntwrk", repo: "midnight-docs" },
14
+ "midnight-docs": { owner: "midnightntwrk", repo: "midnight-docs" },
15
+ // Example DApps
16
+ "example-counter": { owner: "midnightntwrk", repo: "example-counter" },
17
+ counter: { owner: "midnightntwrk", repo: "example-counter" },
18
+ "example-bboard": { owner: "midnightntwrk", repo: "example-bboard" },
19
+ bboard: { owner: "midnightntwrk", repo: "example-bboard" },
20
+ "example-dex": { owner: "midnightntwrk", repo: "example-dex" },
21
+ dex: { owner: "midnightntwrk", repo: "example-dex" },
22
+ // Developer Tools
23
+ "create-mn-app": { owner: "midnightntwrk", repo: "create-mn-app" },
24
+ "midnight-wallet": { owner: "midnightntwrk", repo: "midnight-wallet" },
25
+ wallet: { owner: "midnightntwrk", repo: "midnight-wallet" },
26
+ // Infrastructure
27
+ "midnight-indexer": { owner: "midnightntwrk", repo: "midnight-indexer" },
28
+ indexer: { owner: "midnightntwrk", repo: "midnight-indexer" },
29
+ "midnight-node-docker": {
30
+ owner: "midnightntwrk",
31
+ repo: "midnight-node-docker",
32
+ },
33
+ node: { owner: "midnightntwrk", repo: "midnight-node-docker" },
34
+ // APIs & Connectors
35
+ "midnight-dapp-connector-api": {
36
+ owner: "midnightntwrk",
37
+ repo: "midnight-dapp-connector-api",
38
+ },
39
+ connector: { owner: "midnightntwrk", repo: "midnight-dapp-connector-api" },
40
+ // Tooling
41
+ "compact-tree-sitter": {
42
+ owner: "midnightntwrk",
43
+ repo: "compact-tree-sitter",
44
+ },
45
+ // Community
46
+ "midnight-awesome-dapps": {
47
+ owner: "midnightntwrk",
48
+ repo: "midnight-awesome-dapps",
49
+ },
50
+ awesome: { owner: "midnightntwrk", repo: "midnight-awesome-dapps" },
51
+ "contributor-hub": { owner: "midnightntwrk", repo: "contributor-hub" },
52
+ // Partner Libraries (OpenZeppelin)
53
+ "compact-contracts": { owner: "OpenZeppelin", repo: "compact-contracts" },
54
+ openzeppelin: { owner: "OpenZeppelin", repo: "compact-contracts" },
55
+ oz: { owner: "OpenZeppelin", repo: "compact-contracts" },
56
+ };
57
+ export const EXAMPLES = [
58
+ {
59
+ name: "Counter",
60
+ repository: "midnightntwrk/example-counter",
61
+ description: "Simple counter contract demonstrating basic Compact concepts. Perfect for learning ledger state, circuits, and witnesses.",
62
+ category: "counter",
63
+ complexity: "beginner",
64
+ mainFile: "contract/src/counter.compact",
65
+ features: [
66
+ "Ledger state management",
67
+ "Basic circuit definition",
68
+ "Counter increment/decrement",
69
+ "TypeScript integration",
70
+ ],
71
+ },
72
+ {
73
+ name: "Bulletin Board",
74
+ repository: "midnightntwrk/example-bboard",
75
+ description: "Full DApp example with CLI and React UI. Demonstrates posting messages with privacy features.",
76
+ category: "bboard",
77
+ complexity: "intermediate",
78
+ mainFile: "contract/src/bboard.compact",
79
+ features: [
80
+ "Private messaging",
81
+ "React frontend",
82
+ "CLI interface",
83
+ "Wallet integration",
84
+ "Disclose operations",
85
+ ],
86
+ },
87
+ {
88
+ name: "DEX (Decentralized Exchange)",
89
+ repository: "midnightntwrk/example-dex",
90
+ description: "Advanced DApp example showing token swaps and liquidity pools with privacy-preserving transactions.",
91
+ category: "dex",
92
+ complexity: "advanced",
93
+ mainFile: "contract/src/dex.compact",
94
+ features: [
95
+ "Token swaps",
96
+ "Liquidity pools",
97
+ "Privacy-preserving trades",
98
+ "Price calculations",
99
+ "Advanced state management",
100
+ ],
101
+ },
102
+ ];
103
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Repository handler functions
3
+ * Business logic for repository-related MCP tools
4
+ */
5
+ import type { GetFileInput, ListExamplesInput, GetLatestUpdatesInput, GetVersionInfoInput, CheckBreakingChangesInput, GetMigrationGuideInput, GetFileAtVersionInput, CompareSyntaxInput, GetLatestSyntaxInput } from "./schemas.js";
6
+ /**
7
+ * Resolve repository name alias to owner/repo
8
+ */
9
+ export declare function resolveRepo(repoName?: string): {
10
+ owner: string;
11
+ repo: string;
12
+ } | null;
13
+ /**
14
+ * Retrieve a specific file from Midnight repositories
15
+ */
16
+ export declare function getFile(input: GetFileInput): Promise<{
17
+ error: string;
18
+ suggestion: string;
19
+ repository?: undefined;
20
+ content?: undefined;
21
+ path?: undefined;
22
+ sha?: undefined;
23
+ size?: undefined;
24
+ url?: undefined;
25
+ } | {
26
+ error: string;
27
+ repository: string;
28
+ suggestion: string;
29
+ content?: undefined;
30
+ path?: undefined;
31
+ sha?: undefined;
32
+ size?: undefined;
33
+ url?: undefined;
34
+ } | {
35
+ content: string;
36
+ path: string;
37
+ repository: string;
38
+ sha: string;
39
+ size: number;
40
+ url: string;
41
+ error?: undefined;
42
+ suggestion?: undefined;
43
+ }>;
44
+ /**
45
+ * List available example contracts and DApps
46
+ */
47
+ export declare function listExamples(input: ListExamplesInput): Promise<{
48
+ examples: {
49
+ name: string;
50
+ repository: string;
51
+ description: string;
52
+ complexity: "beginner" | "intermediate" | "advanced";
53
+ mainFile: string;
54
+ features: string[];
55
+ githubUrl: string;
56
+ }[];
57
+ totalCount: number;
58
+ categories: string[];
59
+ }>;
60
+ /**
61
+ * Retrieve recent changes across Midnight repositories
62
+ */
63
+ export declare function getLatestUpdates(input: GetLatestUpdatesInput): Promise<{
64
+ summary: {
65
+ since: string;
66
+ totalCommits: number;
67
+ activeRepositories: number;
68
+ checkedRepositories: number;
69
+ };
70
+ updates: {
71
+ repository: string;
72
+ commitCount: number;
73
+ latestCommit: {
74
+ message: string;
75
+ date: string;
76
+ author: string;
77
+ url: string;
78
+ } | null;
79
+ recentCommits: {
80
+ message: string;
81
+ date: string;
82
+ sha: string;
83
+ }[];
84
+ }[];
85
+ }>;
86
+ /**
87
+ * Get version and release info for a repository
88
+ */
89
+ export declare function getVersionInfo(input: GetVersionInfoInput): Promise<{
90
+ repository: string;
91
+ latestVersion: string;
92
+ latestStableVersion: string;
93
+ publishedAt: string | null;
94
+ releaseNotes: string | null;
95
+ recentReleases: {
96
+ version: string;
97
+ date: string;
98
+ isPrerelease: boolean;
99
+ url: string;
100
+ }[];
101
+ recentBreakingChanges: string[];
102
+ versionContext: string;
103
+ }>;
104
+ /**
105
+ * Check for breaking changes since a specific version
106
+ */
107
+ export declare function checkBreakingChanges(input: CheckBreakingChangesInput): Promise<{
108
+ repository: string;
109
+ currentVersion: string;
110
+ latestVersion: string | null;
111
+ isOutdated: boolean;
112
+ versionsBehind: number;
113
+ hasBreakingChanges: boolean;
114
+ breakingChanges: string[];
115
+ recommendation: string;
116
+ }>;
117
+ /**
118
+ * Get migration guide between versions
119
+ */
120
+ export declare function getMigrationGuide(input: GetMigrationGuideInput): Promise<{
121
+ repository: string;
122
+ from: string;
123
+ to: string;
124
+ summary: {
125
+ breakingChangesCount: number;
126
+ deprecationsCount: number;
127
+ newFeaturesCount: number;
128
+ };
129
+ breakingChanges: string[];
130
+ deprecations: string[];
131
+ newFeatures: string[];
132
+ migrationSteps: string[];
133
+ migrationDifficulty: string;
134
+ }>;
135
+ /**
136
+ * Get a file at a specific version - critical for version-accurate recommendations
137
+ */
138
+ export declare function getFileAtVersion(input: GetFileAtVersionInput): Promise<{
139
+ repository: string;
140
+ path: string;
141
+ version: string;
142
+ content: string;
143
+ note: string;
144
+ }>;
145
+ /**
146
+ * Compare syntax between two versions - shows what changed
147
+ */
148
+ export declare function compareSyntax(input: CompareSyntaxInput): Promise<{
149
+ repository: string;
150
+ path: string;
151
+ oldVersion: string;
152
+ newVersion: string;
153
+ hasDifferences: boolean;
154
+ oldContent: string | null;
155
+ newContent: string | null;
156
+ recommendation: string;
157
+ }>;
158
+ /**
159
+ * Get the latest syntax reference for Compact language
160
+ * This is the source of truth for writing valid, compilable contracts
161
+ */
162
+ export declare function getLatestSyntax(input: GetLatestSyntaxInput): Promise<{
163
+ repository: string;
164
+ version: string;
165
+ warning: string;
166
+ syntaxFiles: never[];
167
+ examplePaths: string[];
168
+ note?: undefined;
169
+ } | {
170
+ repository: string;
171
+ version: string;
172
+ syntaxFiles: {
173
+ path: string;
174
+ content: string;
175
+ }[];
176
+ note: string;
177
+ warning?: undefined;
178
+ examplePaths?: undefined;
179
+ }>;
180
+ //# sourceMappingURL=handlers.d.ts.map