midnight-mcp 0.1.41 → 0.2.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 (103) hide show
  1. package/README.md +32 -1
  2. package/dist/bin.d.ts +1 -0
  3. package/dist/bin.js +60 -0
  4. package/dist/chunk-HOWO4K5A.js +2197 -0
  5. package/dist/chunk-S7G4OHA4.js +8306 -0
  6. package/dist/db-YDGUWI5K.js +7 -0
  7. package/dist/index.d.ts +205 -3
  8. package/dist/index.js +28 -16
  9. package/package.json +16 -6
  10. package/dist/config/compact-version.d.ts +0 -183
  11. package/dist/config/compact-version.js +0 -423
  12. package/dist/db/index.d.ts +0 -3
  13. package/dist/db/index.js +0 -2
  14. package/dist/db/vectorStore.d.ts +0 -69
  15. package/dist/db/vectorStore.js +0 -196
  16. package/dist/pipeline/embeddings.d.ts +0 -25
  17. package/dist/pipeline/embeddings.js +0 -103
  18. package/dist/pipeline/github.d.ts +0 -84
  19. package/dist/pipeline/github.js +0 -399
  20. package/dist/pipeline/index.d.ts +0 -11
  21. package/dist/pipeline/index.js +0 -6
  22. package/dist/pipeline/indexer.d.ts +0 -41
  23. package/dist/pipeline/indexer.js +0 -254
  24. package/dist/pipeline/parser.d.ts +0 -46
  25. package/dist/pipeline/parser.js +0 -436
  26. package/dist/pipeline/releases.d.ts +0 -112
  27. package/dist/pipeline/releases.js +0 -298
  28. package/dist/pipeline/repository.d.ts +0 -372
  29. package/dist/pipeline/repository.js +0 -520
  30. package/dist/prompts/index.d.ts +0 -3
  31. package/dist/prompts/index.js +0 -2
  32. package/dist/prompts/templates.d.ts +0 -26
  33. package/dist/prompts/templates.js +0 -443
  34. package/dist/resources/code.d.ts +0 -15
  35. package/dist/resources/code.js +0 -122
  36. package/dist/resources/content/code-content.d.ts +0 -6
  37. package/dist/resources/content/code-content.js +0 -802
  38. package/dist/resources/content/docs-content.d.ts +0 -14
  39. package/dist/resources/content/docs-content.js +0 -1202
  40. package/dist/resources/content/index.d.ts +0 -6
  41. package/dist/resources/content/index.js +0 -6
  42. package/dist/resources/docs.d.ts +0 -15
  43. package/dist/resources/docs.js +0 -98
  44. package/dist/resources/index.d.ts +0 -6
  45. package/dist/resources/index.js +0 -13
  46. package/dist/resources/schemas.d.ts +0 -16
  47. package/dist/resources/schemas.js +0 -407
  48. package/dist/scripts/index-repos.d.ts +0 -12
  49. package/dist/scripts/index-repos.js +0 -53
  50. package/dist/server.d.ts +0 -43
  51. package/dist/server.js +0 -696
  52. package/dist/services/index.d.ts +0 -6
  53. package/dist/services/index.js +0 -6
  54. package/dist/services/sampling.d.ts +0 -62
  55. package/dist/services/sampling.js +0 -277
  56. package/dist/tools/analyze.d.ts +0 -106
  57. package/dist/tools/analyze.js +0 -431
  58. package/dist/tools/generation.d.ts +0 -9
  59. package/dist/tools/generation.js +0 -285
  60. package/dist/tools/health.d.ts +0 -120
  61. package/dist/tools/health.js +0 -365
  62. package/dist/tools/index.d.ts +0 -14
  63. package/dist/tools/index.js +0 -22
  64. package/dist/tools/meta.d.ts +0 -61
  65. package/dist/tools/meta.js +0 -282
  66. package/dist/tools/repository/constants.d.ts +0 -19
  67. package/dist/tools/repository/constants.js +0 -324
  68. package/dist/tools/repository/handlers.d.ts +0 -373
  69. package/dist/tools/repository/handlers.js +0 -724
  70. package/dist/tools/repository/index.d.ts +0 -9
  71. package/dist/tools/repository/index.js +0 -13
  72. package/dist/tools/repository/schemas.d.ts +0 -153
  73. package/dist/tools/repository/schemas.js +0 -106
  74. package/dist/tools/repository/tools.d.ts +0 -7
  75. package/dist/tools/repository/tools.js +0 -484
  76. package/dist/tools/repository/validation.d.ts +0 -106
  77. package/dist/tools/repository/validation.js +0 -820
  78. package/dist/tools/repository.d.ts +0 -6
  79. package/dist/tools/repository.js +0 -7
  80. package/dist/tools/search.d.ts +0 -76
  81. package/dist/tools/search.js +0 -423
  82. package/dist/types/index.d.ts +0 -2
  83. package/dist/types/index.js +0 -2
  84. package/dist/types/mcp.d.ts +0 -187
  85. package/dist/types/mcp.js +0 -6
  86. package/dist/utils/cache.d.ts +0 -77
  87. package/dist/utils/cache.js +0 -172
  88. package/dist/utils/config.d.ts +0 -70
  89. package/dist/utils/config.js +0 -294
  90. package/dist/utils/errors.d.ts +0 -111
  91. package/dist/utils/errors.js +0 -165
  92. package/dist/utils/health.d.ts +0 -29
  93. package/dist/utils/health.js +0 -132
  94. package/dist/utils/hosted-api.d.ts +0 -67
  95. package/dist/utils/hosted-api.js +0 -119
  96. package/dist/utils/index.d.ts +0 -16
  97. package/dist/utils/index.js +0 -15
  98. package/dist/utils/logger.d.ts +0 -48
  99. package/dist/utils/logger.js +0 -124
  100. package/dist/utils/rate-limit.d.ts +0 -61
  101. package/dist/utils/rate-limit.js +0 -148
  102. package/dist/utils/validation.d.ts +0 -52
  103. package/dist/utils/validation.js +0 -255
package/dist/server.js DELETED
@@ -1,696 +0,0 @@
1
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourceTemplatesRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, SetLevelRequestSchema, CompleteRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
- import { logger, formatErrorResponse, setMCPLogCallback, trackToolCall, } from "./utils/index.js";
5
- import { vectorStore } from "./db/index.js";
6
- import { allTools } from "./tools/index.js";
7
- import { allResources, getDocumentation, getCode, getSchema, } from "./resources/index.js";
8
- import { promptDefinitions, generatePrompt } from "./prompts/index.js";
9
- import { registerSamplingCallback } from "./services/index.js";
10
- import { createRequire } from "module";
11
- // Read version from package.json (single source of truth)
12
- const require = createRequire(import.meta.url);
13
- const packageJson = require("../package.json");
14
- const CURRENT_VERSION = packageJson.version;
15
- const SERVER_INFO = {
16
- name: "midnight-mcp",
17
- version: CURRENT_VERSION,
18
- description: "MCP Server for Midnight Blockchain Development",
19
- };
20
- // Version check state
21
- let versionCheckResult = {
22
- isOutdated: false,
23
- latestVersion: CURRENT_VERSION,
24
- updateMessage: null,
25
- };
26
- /**
27
- * Check for updates against npm registry (runs at startup)
28
- */
29
- async function checkForUpdates() {
30
- try {
31
- const controller = new AbortController();
32
- const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
33
- const response = await fetch("https://registry.npmjs.org/midnight-mcp/latest", { signal: controller.signal });
34
- clearTimeout(timeoutId);
35
- if (!response.ok)
36
- return;
37
- const data = (await response.json());
38
- const latestVersion = data.version;
39
- if (latestVersion !== CURRENT_VERSION) {
40
- versionCheckResult = {
41
- isOutdated: true,
42
- latestVersion,
43
- updateMessage: `⚠️ UPDATE AVAILABLE: v${latestVersion} (you have v${CURRENT_VERSION}). ` +
44
- `Run: rm -rf ~/.npm/_npx && restart Claude Desktop. ` +
45
- `Or update config to use: "midnight-mcp@latest"`,
46
- };
47
- logger.warn(`Outdated version detected: v${CURRENT_VERSION} -> v${latestVersion}`);
48
- }
49
- }
50
- catch {
51
- // Silently ignore version check failures (offline, timeout, etc.)
52
- }
53
- }
54
- /**
55
- * Get update warning if outdated (to include in responses)
56
- */
57
- export function getUpdateWarning() {
58
- return versionCheckResult.updateMessage;
59
- }
60
- // Resource subscriptions tracking
61
- const resourceSubscriptions = new Set();
62
- /**
63
- * Clear all subscriptions (useful for server restart/testing)
64
- */
65
- export function clearSubscriptions() {
66
- resourceSubscriptions.clear();
67
- logger.debug("Subscriptions cleared");
68
- }
69
- // Resource templates for parameterized resources (RFC 6570 URI Templates)
70
- const resourceTemplates = [
71
- {
72
- uriTemplate: "midnight://code/{owner}/{repo}/{path}",
73
- name: "Repository Code",
74
- title: "📄 Repository Code Files",
75
- description: "Access code files from any Midnight repository by specifying owner, repo, and file path",
76
- mimeType: "text/plain",
77
- },
78
- {
79
- uriTemplate: "midnight://docs/{section}/{topic}",
80
- name: "Documentation",
81
- title: "📚 Documentation Sections",
82
- description: "Access documentation by section (guides, api, concepts) and topic",
83
- mimeType: "text/markdown",
84
- },
85
- {
86
- uriTemplate: "midnight://examples/{category}/{name}",
87
- name: "Example Contracts",
88
- title: "📝 Example Contracts",
89
- description: "Access example contracts by category (counter, bboard, token, voting) and name",
90
- mimeType: "text/x-compact",
91
- },
92
- {
93
- uriTemplate: "midnight://schema/{type}",
94
- name: "Schema Definitions",
95
- title: "🔧 Schema Definitions",
96
- description: "Access JSON schemas for contract AST, transactions, and proofs",
97
- mimeType: "application/json",
98
- },
99
- ];
100
- /**
101
- * Create and configure the MCP server
102
- */
103
- // Current MCP logging level (controlled by client)
104
- let mcpLogLevel = "info";
105
- // Server instance for sending notifications
106
- let serverInstance = null;
107
- // Track if server is connected (can send notifications)
108
- let isConnected = false;
109
- /**
110
- * Mark server as connected (safe to send notifications)
111
- */
112
- export function setServerConnected(connected) {
113
- isConnected = connected;
114
- }
115
- /**
116
- * Send a log message to the MCP client
117
- * This allows clients to see server logs for debugging
118
- */
119
- export function sendLogToClient(level, loggerName, data) {
120
- // Only send if server exists AND is connected
121
- if (!serverInstance || !isConnected)
122
- return;
123
- // Map levels to numeric values for comparison
124
- const levelValues = {
125
- debug: 0,
126
- info: 1,
127
- notice: 2,
128
- warning: 3,
129
- error: 4,
130
- critical: 5,
131
- alert: 6,
132
- emergency: 7,
133
- };
134
- // Only send if level meets threshold
135
- if (levelValues[level] < levelValues[mcpLogLevel])
136
- return;
137
- try {
138
- serverInstance.notification({
139
- method: "notifications/message",
140
- params: {
141
- level,
142
- logger: loggerName,
143
- data,
144
- },
145
- });
146
- }
147
- catch {
148
- // Ignore notification errors
149
- }
150
- }
151
- /**
152
- * Send a progress notification to the MCP client
153
- * Used for long-running operations like compound tools
154
- */
155
- export function sendProgressNotification(progressToken, progress, total, message) {
156
- if (!serverInstance)
157
- return;
158
- try {
159
- serverInstance.notification({
160
- method: "notifications/progress",
161
- params: {
162
- progressToken,
163
- progress,
164
- ...(total !== undefined && { total }),
165
- ...(message && { message }),
166
- },
167
- });
168
- }
169
- catch {
170
- // Ignore notification errors
171
- }
172
- }
173
- export function createServer() {
174
- const server = new Server(SERVER_INFO, {
175
- capabilities: {
176
- tools: {
177
- listChanged: true,
178
- },
179
- resources: {
180
- subscribe: true,
181
- listChanged: true,
182
- },
183
- prompts: {
184
- listChanged: true,
185
- },
186
- logging: {},
187
- completions: {},
188
- },
189
- });
190
- // Store server instance for logging notifications
191
- serverInstance = server;
192
- // Wire up MCP logging - send logger output to client
193
- setMCPLogCallback((level, loggerName, data) => {
194
- sendLogToClient(level, loggerName, data);
195
- });
196
- // Register tool handlers
197
- registerToolHandlers(server);
198
- // Register resource handlers
199
- registerResourceHandlers(server);
200
- // Register prompt handlers
201
- registerPromptHandlers(server);
202
- // Register subscription handlers
203
- registerSubscriptionHandlers(server);
204
- // Register logging handler
205
- registerLoggingHandler(server);
206
- // Register completions handler
207
- registerCompletionsHandler(server);
208
- // Setup sampling callback if available
209
- setupSampling(server);
210
- return server;
211
- }
212
- /**
213
- * Register logging handler for MCP logging capability
214
- */
215
- function registerLoggingHandler(server) {
216
- server.setRequestHandler(SetLevelRequestSchema, async (request) => {
217
- const { level } = request.params;
218
- mcpLogLevel = level;
219
- logger.info(`MCP log level set to: ${level}`);
220
- sendLogToClient("info", "midnight-mcp", {
221
- message: `Log level changed to ${level}`,
222
- });
223
- return {};
224
- });
225
- }
226
- // Completion suggestions for prompt arguments
227
- const COMPLETION_VALUES = {
228
- "midnight:create-contract": {
229
- contractType: [
230
- "token",
231
- "voting",
232
- "credential",
233
- "auction",
234
- "escrow",
235
- "custom",
236
- ],
237
- privacyLevel: ["full", "partial", "public"],
238
- complexity: ["beginner", "intermediate", "advanced"],
239
- },
240
- "midnight:review-contract": {
241
- focusAreas: [
242
- "security",
243
- "performance",
244
- "privacy",
245
- "readability",
246
- "gas-optimization",
247
- ],
248
- },
249
- "midnight:explain-concept": {
250
- concept: [
251
- "zk-proofs",
252
- "circuits",
253
- "witnesses",
254
- "ledger",
255
- "state-management",
256
- "privacy-model",
257
- "token-transfers",
258
- "merkle-trees",
259
- ],
260
- level: ["beginner", "intermediate", "advanced"],
261
- },
262
- "midnight:compare-approaches": {
263
- approaches: [
264
- "token-standards",
265
- "state-management",
266
- "privacy-patterns",
267
- "circuit-design",
268
- ],
269
- },
270
- "midnight:debug-contract": {
271
- errorType: [
272
- "compilation",
273
- "runtime",
274
- "logic",
275
- "privacy-leak",
276
- "state-corruption",
277
- ],
278
- },
279
- };
280
- /**
281
- * Register completions handler for argument autocompletion
282
- */
283
- function registerCompletionsHandler(server) {
284
- server.setRequestHandler(CompleteRequestSchema, async (request) => {
285
- const { ref, argument } = request.params;
286
- if (ref.type !== "ref/prompt") {
287
- return { completion: { values: [], hasMore: false } };
288
- }
289
- const promptName = ref.name;
290
- const argName = argument.name;
291
- const currentValue = argument.value?.toLowerCase() || "";
292
- // Get completion values for this prompt/argument
293
- const promptCompletions = COMPLETION_VALUES[promptName];
294
- if (!promptCompletions) {
295
- return { completion: { values: [], hasMore: false } };
296
- }
297
- const argValues = promptCompletions[argName];
298
- if (!argValues) {
299
- return { completion: { values: [], hasMore: false } };
300
- }
301
- // Filter by current input
302
- const filtered = argValues.filter((v) => v.toLowerCase().includes(currentValue));
303
- return {
304
- completion: {
305
- values: filtered.slice(0, 20),
306
- total: filtered.length,
307
- hasMore: filtered.length > 20,
308
- },
309
- };
310
- });
311
- }
312
- /**
313
- * Register tool handlers
314
- */
315
- function registerToolHandlers(server) {
316
- // List available tools with annotations and output schemas
317
- server.setRequestHandler(ListToolsRequestSchema, async () => {
318
- logger.debug("Listing tools");
319
- return {
320
- tools: allTools.map((tool) => ({
321
- name: tool.name,
322
- description: tool.description,
323
- inputSchema: tool.inputSchema,
324
- // Include output schema if defined
325
- ...(tool.outputSchema && { outputSchema: tool.outputSchema }),
326
- // Include annotations if defined
327
- ...(tool.annotations && { annotations: tool.annotations }),
328
- })),
329
- };
330
- });
331
- // Handle tool calls
332
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
333
- const { name, arguments: args } = request.params;
334
- logger.info(`Tool called: ${name}`, { args });
335
- const startTime = Date.now();
336
- const tool = allTools.find((t) => t.name === name);
337
- if (!tool) {
338
- const availableTools = allTools
339
- .map((t) => t.name)
340
- .slice(0, 5)
341
- .join(", ");
342
- // Track failed tool call (unknown tool)
343
- trackToolCall(name, false, Date.now() - startTime, CURRENT_VERSION);
344
- return {
345
- content: [
346
- {
347
- type: "text",
348
- text: JSON.stringify({
349
- error: `Unknown tool: ${name}`,
350
- suggestion: `Available tools include: ${availableTools}...`,
351
- hint: "Use ListTools to see all available tools",
352
- }, null, 2),
353
- },
354
- ],
355
- isError: true,
356
- };
357
- }
358
- try {
359
- const result = await tool.handler(args);
360
- const durationMs = Date.now() - startTime;
361
- // Track successful tool call (fire-and-forget, won't block response)
362
- trackToolCall(name, true, durationMs, CURRENT_VERSION);
363
- // Include prominent update prompt in ALL responses when outdated
364
- const updateWarning = getUpdateWarning();
365
- if (updateWarning && versionCheckResult.isOutdated) {
366
- // Prepend update notice with MANUAL instructions (auto-update not possible in sandbox)
367
- const updatePrompt = {
368
- "🚨 UPDATE AVAILABLE": {
369
- message: `You are using v${CURRENT_VERSION} but v${versionCheckResult.latestVersion} is available.`,
370
- userAction: {
371
- instruction: "Tell the user to update manually. Auto-update is NOT possible because you run in a sandboxed environment without access to local files.",
372
- steps: [
373
- "1. Edit config file to use 'midnight-mcp@latest' instead of 'midnight-mcp'",
374
- "2. Run: rm -rf ~/.npm/_npx (to clear npm cache)",
375
- "3. Restart the editor completely (Cmd+Q on Mac, then reopen)",
376
- ],
377
- configLocations: {
378
- claudeDesktop: "~/Library/Application Support/Claude/claude_desktop_config.json",
379
- cursor: ".cursor/mcp.json",
380
- vscode: ".vscode/mcp.json",
381
- windsurf: "~/.codeium/windsurf/mcp_config.json",
382
- },
383
- },
384
- note: "If user already has @latest in config, they just need to clear cache (rm -rf ~/.npm/_npx) and restart.",
385
- },
386
- result,
387
- };
388
- return {
389
- content: [
390
- {
391
- type: "text",
392
- text: JSON.stringify(updatePrompt, null, 2),
393
- },
394
- ],
395
- };
396
- }
397
- return {
398
- content: [
399
- {
400
- type: "text",
401
- text: JSON.stringify(result, null, 2),
402
- },
403
- ],
404
- // Include structured content for machine-readable responses
405
- // This allows clients to parse results without JSON.parse()
406
- structuredContent: result,
407
- };
408
- }
409
- catch (error) {
410
- const durationMs = Date.now() - startTime;
411
- logger.error(`Tool error: ${name}`, { error: String(error) });
412
- // Track failed tool call
413
- trackToolCall(name, false, durationMs, CURRENT_VERSION);
414
- const errorResponse = formatErrorResponse(error, `tool:${name}`);
415
- return {
416
- content: [
417
- {
418
- type: "text",
419
- text: JSON.stringify(errorResponse, null, 2),
420
- },
421
- ],
422
- isError: true,
423
- };
424
- }
425
- });
426
- }
427
- /**
428
- * Register resource handlers
429
- */
430
- function registerResourceHandlers(server) {
431
- // List available resources
432
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
433
- logger.debug("Listing resources");
434
- return {
435
- resources: allResources.map((resource) => ({
436
- uri: resource.uri,
437
- name: resource.name,
438
- description: resource.description,
439
- mimeType: resource.mimeType,
440
- })),
441
- };
442
- });
443
- // List resource templates (RFC 6570 URI Templates)
444
- server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
445
- logger.debug("Listing resource templates");
446
- return {
447
- resourceTemplates: resourceTemplates.map((template) => ({
448
- uriTemplate: template.uriTemplate,
449
- name: template.name,
450
- title: template.title,
451
- description: template.description,
452
- mimeType: template.mimeType,
453
- })),
454
- };
455
- });
456
- // Read resource content
457
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
458
- const { uri } = request.params;
459
- logger.info(`Resource requested: ${uri}`);
460
- try {
461
- let content = null;
462
- let mimeType = "text/plain";
463
- if (uri.startsWith("midnight://docs/")) {
464
- content = await getDocumentation(uri);
465
- mimeType = "text/markdown";
466
- }
467
- else if (uri.startsWith("midnight://code/")) {
468
- content = await getCode(uri);
469
- mimeType = "text/x-compact";
470
- }
471
- else if (uri.startsWith("midnight://schema/")) {
472
- const schema = getSchema(uri);
473
- content = schema ? JSON.stringify(schema, null, 2) : null;
474
- mimeType = "application/json";
475
- }
476
- if (!content) {
477
- const resourceTypes = [
478
- "midnight://docs/",
479
- "midnight://code/",
480
- "midnight://schema/",
481
- ];
482
- const validPrefix = resourceTypes.find((p) => uri.startsWith(p));
483
- return {
484
- contents: [
485
- {
486
- uri,
487
- mimeType: "application/json",
488
- text: JSON.stringify({
489
- error: `Resource not found: ${uri}`,
490
- suggestion: validPrefix
491
- ? `Check the resource path after '${validPrefix}'`
492
- : `Valid resource prefixes: ${resourceTypes.join(", ")}`,
493
- hint: "Use ListResources to see all available resources",
494
- }, null, 2),
495
- },
496
- ],
497
- };
498
- }
499
- return {
500
- contents: [
501
- {
502
- uri,
503
- mimeType,
504
- text: content,
505
- },
506
- ],
507
- };
508
- }
509
- catch (error) {
510
- logger.error(`Resource error: ${uri}`, { error: String(error) });
511
- const errorResponse = formatErrorResponse(error, `resource:${uri}`);
512
- return {
513
- contents: [
514
- {
515
- uri,
516
- mimeType: "application/json",
517
- text: JSON.stringify(errorResponse, null, 2),
518
- },
519
- ],
520
- };
521
- }
522
- });
523
- }
524
- /**
525
- * Register prompt handlers
526
- */
527
- function registerPromptHandlers(server) {
528
- // List available prompts
529
- server.setRequestHandler(ListPromptsRequestSchema, async () => {
530
- logger.debug("Listing prompts");
531
- return {
532
- prompts: promptDefinitions.map((prompt) => ({
533
- name: prompt.name,
534
- description: prompt.description,
535
- arguments: prompt.arguments,
536
- })),
537
- };
538
- });
539
- // Get prompt content
540
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
541
- const { name, arguments: args } = request.params;
542
- logger.info(`Prompt requested: ${name}`, { args });
543
- const prompt = promptDefinitions.find((p) => p.name === name);
544
- if (!prompt) {
545
- return {
546
- description: `Unknown prompt: ${name}`,
547
- messages: [],
548
- };
549
- }
550
- const messages = generatePrompt(name, args || {});
551
- return {
552
- description: prompt.description,
553
- messages: messages.map((m) => ({
554
- role: m.role,
555
- content: m.content,
556
- })),
557
- };
558
- });
559
- }
560
- /**
561
- * Register resource subscription handlers
562
- */
563
- function registerSubscriptionHandlers(server) {
564
- // Handle subscribe requests
565
- server.setRequestHandler(SubscribeRequestSchema, async (request) => {
566
- const { uri } = request.params;
567
- logger.info(`Subscribing to resource: ${uri}`);
568
- // Validate that the URI is a valid resource
569
- const validPrefixes = [
570
- "midnight://docs/",
571
- "midnight://code/",
572
- "midnight://schema/",
573
- ];
574
- const isValid = validPrefixes.some((prefix) => uri.startsWith(prefix));
575
- if (!isValid) {
576
- logger.warn(`Invalid subscription URI: ${uri}`);
577
- throw new Error(`Invalid subscription URI: ${uri}. Valid prefixes: ${validPrefixes.join(", ")}`);
578
- }
579
- resourceSubscriptions.add(uri);
580
- logger.debug(`Active subscriptions: ${resourceSubscriptions.size}`);
581
- return {};
582
- });
583
- // Handle unsubscribe requests
584
- server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
585
- const { uri } = request.params;
586
- logger.info(`Unsubscribing from resource: ${uri}`);
587
- resourceSubscriptions.delete(uri);
588
- logger.debug(`Active subscriptions: ${resourceSubscriptions.size}`);
589
- return {};
590
- });
591
- }
592
- /**
593
- * Notify subscribers when a resource changes
594
- * Call this when re-indexing or when docs are updated
595
- */
596
- export function notifyResourceUpdate(server, uri) {
597
- if (resourceSubscriptions.has(uri)) {
598
- logger.info(`Notifying subscribers of update: ${uri}`);
599
- // Send notification via the server
600
- server.notification({
601
- method: "notifications/resources/updated",
602
- params: { uri },
603
- });
604
- }
605
- }
606
- /**
607
- * Get the list of active subscriptions
608
- */
609
- export function getActiveSubscriptions() {
610
- return Array.from(resourceSubscriptions);
611
- }
612
- /**
613
- * Setup sampling capability
614
- * Registers a callback that allows the server to request LLM completions
615
- */
616
- function setupSampling(server) {
617
- // Create a sampling callback that uses the server's request method
618
- const samplingCallback = async (request) => {
619
- logger.debug("Requesting sampling from client", {
620
- messageCount: request.messages.length,
621
- maxTokens: request.maxTokens,
622
- });
623
- try {
624
- // Request completion from the client
625
- const response = await server.request({
626
- method: "sampling/createMessage",
627
- params: {
628
- messages: request.messages,
629
- systemPrompt: request.systemPrompt,
630
- maxTokens: request.maxTokens || 2048,
631
- temperature: request.temperature,
632
- modelPreferences: request.modelPreferences,
633
- },
634
- },
635
- // Use a schema that matches the expected response
636
- {
637
- parse: (data) => {
638
- const response = data;
639
- // Basic validation of expected response structure
640
- if (!response || typeof response !== "object") {
641
- throw new Error("Invalid sampling response: expected object");
642
- }
643
- if (!response.content || typeof response.content !== "object") {
644
- throw new Error("Invalid sampling response: missing content");
645
- }
646
- return response;
647
- },
648
- _def: { typeName: "SamplingResponse" },
649
- });
650
- return response;
651
- }
652
- catch (error) {
653
- logger.error("Sampling request failed", { error: String(error) });
654
- throw error;
655
- }
656
- };
657
- // Register the callback
658
- registerSamplingCallback(samplingCallback);
659
- logger.info("Sampling capability configured");
660
- }
661
- /**
662
- * Initialize the server and vector store
663
- */
664
- export async function initializeServer() {
665
- logger.info("Initializing Midnight MCP Server...");
666
- // Check for updates in background (non-blocking)
667
- checkForUpdates().catch(() => {
668
- // Ignore errors - version check is best-effort
669
- });
670
- // Initialize vector store
671
- try {
672
- await vectorStore.initialize();
673
- logger.info("Vector store initialized");
674
- }
675
- catch (error) {
676
- logger.warn("Vector store initialization failed, continuing without it", {
677
- error: String(error),
678
- });
679
- }
680
- // Create and return server
681
- const server = createServer();
682
- logger.info(`Server v${CURRENT_VERSION} created successfully`);
683
- return server;
684
- }
685
- /**
686
- * Start the server with stdio transport
687
- */
688
- export async function startServer() {
689
- const server = await initializeServer();
690
- const transport = new StdioServerTransport();
691
- await server.connect(transport);
692
- // Now safe to send notifications
693
- setServerConnected(true);
694
- logger.info("Midnight MCP Server running on stdio");
695
- }
696
- //# sourceMappingURL=server.js.map
@@ -1,6 +0,0 @@
1
- /**
2
- * Services index
3
- * Export all service modules
4
- */
5
- export { isSamplingAvailable, registerSamplingCallback, requestCompletion, generateContract, reviewContract, generateDocumentation, } from "./sampling.js";
6
- //# sourceMappingURL=index.d.ts.map