midnight-mcp 0.2.21 → 0.3.0

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
@@ -1,5 +1,14 @@
1
1
  # Midnight MCP Server
2
2
 
3
+ > ## ⚠️ Deprecated — use Kapa + Midnight Expert
4
+ >
5
+ > **midnight-mcp is being wound down.** Midnight has standardised on two official tools:
6
+ >
7
+ > - **Kapa MCP** (docs Q&A / search): `claude mcp add --transport http midnight https://midnight.mcp.kapa.ai`
8
+ > - **Midnight Expert** (hands-on dev, Claude Code plugins): `curl -fsSL https://midnightntwrk.expert/install.sh | bash`
9
+ >
10
+ > **Migration guide → https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert**
11
+
3
12
  [![npm version](https://badge.fury.io/js/midnight-mcp.svg)](https://www.npmjs.com/package/midnight-mcp)
4
13
  [![npm downloads](https://img.shields.io/npm/dm/midnight-mcp)](https://npm-stat.com/charts.html?package=midnight-mcp)
5
14
  [![License](https://img.shields.io/npm/l/midnight-mcp)](./LICENSE)
package/dist/bin.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  startHttpServer,
4
4
  startServer
5
- } from "./chunk-T2CXHJAO.js";
5
+ } from "./chunk-VBZPDFKP.js";
6
6
  import {
7
7
  setOutputFormat
8
- } from "./chunk-YDH6CRK3.js";
8
+ } from "./chunk-KRDOSQPS.js";
9
9
 
10
10
  // src/bin.ts
11
11
  import { config } from "dotenv";
@@ -13,7 +13,7 @@ import { resolve } from "path";
13
13
  import yargs from "yargs";
14
14
  import { hideBin } from "yargs/helpers";
15
15
  config({ path: resolve(process.cwd(), ".env") });
16
- var CURRENT_VERSION = "0.2.21";
16
+ var CURRENT_VERSION = "0.3.0";
17
17
  process.on("uncaughtException", (error) => {
18
18
  console.error("Uncaught exception:", error);
19
19
  process.exit(1);
@@ -10,8 +10,16 @@ var ConfigSchema = z.object({
10
10
  mode: z.enum(["hosted", "local"]).default("hosted"),
11
11
  // Hosted API URL (used when mode is 'hosted')
12
12
  hostedApiUrl: z.string().default("https://midnight-mcp-api.midnightmcp.workers.dev"),
13
+ // Optional bearer token sent to the hosted API. Needed when pointing
14
+ // MIDNIGHT_API_URL at a private/self-hosted backend that requires auth.
15
+ hostedApiToken: z.string().optional(),
13
16
  // GitHub
14
17
  githubToken: z.string().optional(),
18
+ // Extra GitHub repo owners allowed for the resolveRepo() org/repo
19
+ // fall-through, on top of the built-in vetted list. Comma-separated via
20
+ // MIDNIGHT_MCP_ALLOWED_REPO_OWNERS. Lets local users add their own repos
21
+ // without reopening arbitrary-repo access.
22
+ allowedRepoOwners: z.array(z.string()).default([]),
15
23
  // Vector Database (only needed for local mode)
16
24
  chromaUrl: z.string().default("http://localhost:8000"),
17
25
  // Embeddings (only needed for local mode)
@@ -31,7 +39,9 @@ function loadConfig() {
31
39
  const rawConfig = {
32
40
  mode: isLocalMode2 ? "local" : "hosted",
33
41
  hostedApiUrl: process.env.MIDNIGHT_API_URL,
42
+ hostedApiToken: process.env.MIDNIGHT_API_TOKEN,
34
43
  githubToken: process.env.GITHUB_TOKEN,
44
+ allowedRepoOwners: process.env.MIDNIGHT_MCP_ALLOWED_REPO_OWNERS ? process.env.MIDNIGHT_MCP_ALLOWED_REPO_OWNERS.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
35
45
  chromaUrl: process.env.CHROMA_URL,
36
46
  openaiApiKey: process.env.OPENAI_API_KEY,
37
47
  embeddingModel: process.env.EMBEDDING_MODEL,
@@ -1624,7 +1634,7 @@ var releaseTracker = new ReleaseTracker();
1624
1634
 
1625
1635
  // src/utils/health.ts
1626
1636
  var startTime = Date.now();
1627
- var VERSION = "0.2.21";
1637
+ var VERSION = "0.3.0";
1628
1638
  async function checkGitHubAPI() {
1629
1639
  const start = Date.now();
1630
1640
  try {
@@ -1652,7 +1662,7 @@ async function checkGitHubAPI() {
1652
1662
  }
1653
1663
  async function checkVectorStore() {
1654
1664
  try {
1655
- const { vectorStore: vectorStore2 } = await import("./db-5GTR4PCW.js");
1665
+ const { vectorStore: vectorStore2 } = await import("./db-3WSIJCLE.js");
1656
1666
  if (vectorStore2) {
1657
1667
  return {
1658
1668
  status: "pass",
@@ -1999,6 +2009,9 @@ async function makeRequest(url, endpoint, options) {
1999
2009
  headers: {
2000
2010
  "Content-Type": "application/json",
2001
2011
  "User-Agent": "midnight-mcp",
2012
+ // Send bearer auth when the backend requires it (private/self-hosted
2013
+ // deployments that set MIDNIGHT_API_TOKEN).
2014
+ ...config.hostedApiToken ? { Authorization: `Bearer ${config.hostedApiToken}` } : {},
2002
2015
  ...options.headers
2003
2016
  }
2004
2017
  });
@@ -2118,7 +2131,7 @@ function serialize(data) {
2118
2131
  }
2119
2132
 
2120
2133
  // src/utils/version.ts
2121
- var CURRENT_VERSION = "0.2.21";
2134
+ var CURRENT_VERSION = "0.3.0";
2122
2135
 
2123
2136
  // src/db/vectorStore.ts
2124
2137
  var VectorStore = class {
@@ -2313,6 +2326,7 @@ var VectorStore = class {
2313
2326
  var vectorStore = new VectorStore();
2314
2327
 
2315
2328
  export {
2329
+ config,
2316
2330
  isHostedMode,
2317
2331
  DEFAULT_REPOSITORIES,
2318
2332
  setMCPLogCallback,
@@ -2340,4 +2354,4 @@ export {
2340
2354
  serialize,
2341
2355
  CURRENT_VERSION
2342
2356
  };
2343
- //# sourceMappingURL=chunk-YDH6CRK3.js.map
2357
+ //# sourceMappingURL=chunk-KRDOSQPS.js.map
@@ -2,6 +2,7 @@ import {
2
2
  CURRENT_VERSION,
3
3
  DEFAULT_REPOSITORIES,
4
4
  SelfCorrectionHints,
5
+ config,
5
6
  createCacheKey,
6
7
  fileCache,
7
8
  formatErrorResponse,
@@ -24,7 +25,7 @@ import {
24
25
  validateNumber,
25
26
  validateQuery,
26
27
  vectorStore
27
- } from "./chunk-YDH6CRK3.js";
28
+ } from "./chunk-KRDOSQPS.js";
28
29
 
29
30
  // src/tools/search/schemas.ts
30
31
  import { z } from "zod";
@@ -170,43 +171,43 @@ function finalizeResponse(response, cacheKey, warnings) {
170
171
  });
171
172
  return finalResponse;
172
173
  }
173
- async function performSearch(query, limit, config) {
174
+ async function performSearch(query, limit, config2) {
174
175
  const validation = validateSearchInput(query, limit);
175
176
  if (!validation.success) {
176
177
  return validation.error;
177
178
  }
178
179
  const { sanitizedQuery, limit: validatedLimit, warnings } = validation.context;
179
- logger.debug(`Searching ${config.searchType}`, {
180
+ logger.debug(`Searching ${config2.searchType}`, {
180
181
  query: sanitizedQuery,
181
182
  mode: isHostedMode() ? "hosted" : "local"
182
183
  });
183
184
  const cacheKey = createCacheKey(
184
- config.searchType,
185
+ config2.searchType,
185
186
  sanitizedQuery,
186
187
  validatedLimit,
187
- ...config.cacheKeyExtra
188
+ ...config2.cacheKeyExtra
188
189
  );
189
190
  const cached = checkSearchCache(cacheKey);
190
191
  if (cached) return cached;
191
192
  const hostedResult = await tryHostedSearch(
192
- config.searchType,
193
- () => config.hostedSearchFn(sanitizedQuery, validatedLimit),
193
+ config2.searchType,
194
+ () => config2.hostedSearchFn(sanitizedQuery, validatedLimit),
194
195
  cacheKey,
195
196
  warnings
196
197
  );
197
198
  if (hostedResult) {
198
- return { ...hostedResult.result, ...config.hostedResultExtra };
199
+ return { ...hostedResult.result, ...config2.hostedResultExtra };
199
200
  }
200
- const filter = config.buildFilter();
201
+ const filter = config2.buildFilter();
201
202
  let results = await vectorStore.search(sanitizedQuery, validatedLimit, filter);
202
- if (config.postFilter) {
203
- results = config.postFilter(results);
203
+ if (config2.postFilter) {
204
+ results = config2.postFilter(results);
204
205
  }
205
206
  const response = {
206
- results: results.map(config.transformResult),
207
+ results: results.map(config2.transformResult),
207
208
  totalResults: results.length,
208
209
  query: sanitizedQuery,
209
- ...config.extraFields
210
+ ...config2.extraFields
210
211
  };
211
212
  return finalizeResponse(response, cacheKey, warnings);
212
213
  }
@@ -719,7 +720,10 @@ var CompileContractInputSchema = z2.object({
719
720
  });
720
721
 
721
722
  // src/services/compiler.ts
722
- var COMPILER_API_URL = process.env.COMPACT_COMPILER_URL || "https://compact-playground.up.railway.app";
723
+ function getConfiguredCompilerUrl() {
724
+ const url = process.env.COMPACT_COMPILER_URL?.trim();
725
+ return url ? url : void 0;
726
+ }
723
727
  var COMPILER_TIMEOUT = 3e4;
724
728
  var MAX_CODE_SIZE = 100 * 1024;
725
729
  async function compileContract(code, options = {}) {
@@ -739,6 +743,15 @@ async function compileContract(code, options = {}) {
739
743
  serviceAvailable: true
740
744
  };
741
745
  }
746
+ const url = getConfiguredCompilerUrl();
747
+ if (!url) {
748
+ return {
749
+ success: false,
750
+ message: "No compiler service configured. Set COMPACT_COMPILER_URL to a compiler you run yourself to enable compilation; contract source is not sent to any third-party by default.",
751
+ error: "COMPILER_NOT_CONFIGURED",
752
+ serviceAvailable: false
753
+ };
754
+ }
742
755
  const controller = new AbortController();
743
756
  const timeoutId = setTimeout(() => controller.abort(), COMPILER_TIMEOUT);
744
757
  try {
@@ -754,7 +767,7 @@ async function compileContract(code, options = {}) {
754
767
  codeLength: code.length,
755
768
  options: requestBody.options
756
769
  });
757
- const response = await fetch(`${COMPILER_API_URL}/compile`, {
770
+ const response = await fetch(`${url}/compile`, {
758
771
  method: "POST",
759
772
  headers: {
760
773
  "Content-Type": "application/json"
@@ -857,7 +870,7 @@ async function compileContract(code, options = {}) {
857
870
  }
858
871
  }
859
872
  function getCompilerUrl() {
860
- return COMPILER_API_URL;
873
+ return getConfiguredCompilerUrl();
861
874
  }
862
875
 
863
876
  // src/tools/analyze/handlers.ts
@@ -6407,38 +6420,7 @@ var versionCheckResult = {
6407
6420
  var toolCallCount = 0;
6408
6421
  var VERSION_CHECK_INTERVAL = 10;
6409
6422
  async function checkForUpdates() {
6410
- try {
6411
- const controller = new AbortController();
6412
- const timeoutId = setTimeout(() => controller.abort(), 5e3);
6413
- const response = await fetch(
6414
- "https://registry.npmjs.org/midnight-mcp/latest",
6415
- { signal: controller.signal }
6416
- );
6417
- clearTimeout(timeoutId);
6418
- if (!response.ok) return;
6419
- const data = await response.json();
6420
- const latestVersion = data.version;
6421
- if (latestVersion !== CURRENT_VERSION) {
6422
- versionCheckResult = {
6423
- isOutdated: true,
6424
- latestVersion,
6425
- lastChecked: Date.now(),
6426
- updateMessage: `\u{1F6A8} UPDATE AVAILABLE: v${latestVersion} (you have v${CURRENT_VERSION})`
6427
- };
6428
- logger.warn(
6429
- `Outdated version detected: v${CURRENT_VERSION} -> v${latestVersion}`
6430
- );
6431
- } else {
6432
- versionCheckResult = {
6433
- ...versionCheckResult,
6434
- lastChecked: Date.now()
6435
- };
6436
- }
6437
- } catch (error) {
6438
- logger.debug("Version check failed (non-blocking)", {
6439
- error: error instanceof Error ? error.message : String(error)
6440
- });
6441
- }
6423
+ return;
6442
6424
  }
6443
6425
  function maybeCheckForUpdates() {
6444
6426
  toolCallCount++;
@@ -6663,13 +6645,14 @@ function registerCompletionsHandler(server) {
6663
6645
  };
6664
6646
  });
6665
6647
  }
6648
+ var DEPRECATION_PREFIX = "[DEPRECATED] midnight-mcp is being retired \u2014 use Kapa (docs Q&A) + Midnight Expert (dev): https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert \u2014 ";
6666
6649
  function registerToolHandlers(server) {
6667
6650
  server.setRequestHandler(ListToolsRequestSchema, async () => {
6668
6651
  logger.debug("Listing tools");
6669
6652
  return {
6670
6653
  tools: allTools.map((tool) => ({
6671
6654
  name: tool.name,
6672
- description: tool.description,
6655
+ description: DEPRECATION_PREFIX + tool.description,
6673
6656
  inputSchema: tool.inputSchema,
6674
6657
  // Include output schema if defined
6675
6658
  ...tool.outputSchema && { outputSchema: tool.outputSchema },
@@ -7866,19 +7849,29 @@ async function extractContractStructure(input) {
7866
7849
  }
7867
7850
 
7868
7851
  // src/tools/repository/handlers.ts
7852
+ var ALLOWED_REPO_OWNERS = new Set(
7853
+ [
7854
+ ...Object.values(REPO_ALIASES).map((a) => a.owner),
7855
+ ...DEFAULT_REPOSITORIES.map((r) => r.owner),
7856
+ ...config.allowedRepoOwners
7857
+ ].map((owner) => owner.toLowerCase())
7858
+ );
7869
7859
  function resolveRepo(repoName) {
7870
7860
  const name = repoName || "compact";
7871
7861
  const normalized = name.toLowerCase().replace(/^midnightntwrk\//, "");
7872
7862
  const alias = REPO_ALIASES[normalized];
7873
7863
  if (alias) return alias;
7874
- for (const config of DEFAULT_REPOSITORIES) {
7875
- if (config.repo.toLowerCase() === normalized) {
7876
- return { owner: config.owner, repo: config.repo };
7864
+ for (const config2 of DEFAULT_REPOSITORIES) {
7865
+ if (config2.repo.toLowerCase() === normalized) {
7866
+ return { owner: config2.owner, repo: config2.repo };
7877
7867
  }
7878
7868
  }
7879
7869
  if (name.includes("/")) {
7880
7870
  const [owner, repo] = name.split("/");
7881
- return { owner, repo };
7871
+ if (owner && repo && ALLOWED_REPO_OWNERS.has(owner.toLowerCase())) {
7872
+ return { owner, repo };
7873
+ }
7874
+ return null;
7882
7875
  }
7883
7876
  return null;
7884
7877
  }
@@ -9453,6 +9446,17 @@ async function getStatus(_input) {
9453
9446
  }
9454
9447
  };
9455
9448
  }
9449
+ function isNewerVersion(candidate, base) {
9450
+ const a = candidate.split(".").map((n) => parseInt(n, 10) || 0);
9451
+ const b = base.split(".").map((n) => parseInt(n, 10) || 0);
9452
+ for (let i = 0; i < 3; i++) {
9453
+ const x = a[i] ?? 0;
9454
+ const y = b[i] ?? 0;
9455
+ if (x > y) return true;
9456
+ if (x < y) return false;
9457
+ }
9458
+ return false;
9459
+ }
9456
9460
  async function checkVersion(_input) {
9457
9461
  try {
9458
9462
  const response = await fetch(
@@ -9469,24 +9473,22 @@ async function checkVersion(_input) {
9469
9473
  }
9470
9474
  const data = await response.json();
9471
9475
  const latestVersion = data.version;
9472
- const isUpToDate = CURRENT_VERSION === latestVersion;
9476
+ const isUpToDate = !isNewerVersion(latestVersion, CURRENT_VERSION);
9473
9477
  const result = {
9474
9478
  currentVersion: CURRENT_VERSION,
9475
9479
  latestVersion,
9476
9480
  isUpToDate,
9477
- message: isUpToDate ? "\u2705 You are running the latest version!" : `\u26A0\uFE0F UPDATE AVAILABLE: v${latestVersion} (you have v${CURRENT_VERSION})`
9481
+ message: isUpToDate ? "\u2705 You are running the latest published version. Note: midnight-mcp is deprecated \u2014 migrate to Kapa (docs Q&A) + Midnight Expert (dev): https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert" : `\u26A0\uFE0F A newer version (v${latestVersion}) exists, but midnight-mcp is deprecated \u2014 migrate to Kapa (docs Q&A) + Midnight Expert (dev): https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert`
9478
9482
  };
9479
9483
  if (!isUpToDate) {
9480
9484
  result.updateInstructions = {
9481
- step1: "Clear npx cache: rm -rf ~/.npm/_npx (macOS/Linux) or del /s /q %LocalAppData%\\npm-cache\\_npx (Windows)",
9482
- step2: "Restart Claude Desktop completely (Cmd+Q / Alt+F4, then reopen)",
9483
- step3: "Or update config to use: npx -y midnight-mcp@latest (forces latest)",
9484
- alternative: "You can also install globally: npm install -g midnight-mcp@latest"
9485
+ note: "midnight-mcp is deprecated; updating is not recommended.",
9486
+ kapa: "claude mcp add --transport http midnight https://midnight.mcp.kapa.ai",
9487
+ midnightExpert: "curl -fsSL https://midnightntwrk.expert/install.sh | bash",
9488
+ guide: "https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert"
9485
9489
  };
9486
9490
  result.newFeatures = [
9487
- "Auto-update config tool - AI agents update your config automatically",
9488
- "midnight-extract-contract-structure - Static analysis with 10 pre-compilation checks",
9489
- "MCP Logging, Progress, Completions capabilities"
9491
+ "midnight-mcp is deprecated \u2014 see the migration guide for the official replacements."
9490
9492
  ];
9491
9493
  }
9492
9494
  return result;
@@ -11239,7 +11241,7 @@ var suggestToolOutputSchema = {
11239
11241
  var metaTools = [
11240
11242
  {
11241
11243
  name: "midnight-list-tool-categories",
11242
- description: "\u{1F4CB} DISCOVERY TOOL: List available tool categories for progressive exploration. Use this FIRST to understand what capabilities are available, then drill into specific categories with midnight-list-category-tools. Reduces cognitive load by organizing 28 tools into 7 logical groups.",
11244
+ description: "\u{1F4CB} DISCOVERY TOOL: List available tool categories for progressive exploration. Use this FIRST to understand what capabilities are available, then drill into specific categories with midnight-list-category-tools. Reduces cognitive load by organizing the available tools into logical groups.",
11243
11245
  inputSchema: {
11244
11246
  type: "object",
11245
11247
  properties: {
@@ -11332,8 +11334,44 @@ USAGE GUIDANCE:
11332
11334
  ];
11333
11335
  setMetaTools(metaTools);
11334
11336
 
11337
+ // src/tools/deprecation/index.ts
11338
+ var BLOG_URL = "https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert";
11339
+ var deprecationTools = [
11340
+ {
11341
+ name: "midnight-new-mcp",
11342
+ description: "Show where midnight-mcp has moved. midnight-mcp is deprecated; Midnight now uses the official Kapa MCP (docs Q&A) and Midnight Expert (hands-on dev). Call this for the install commands and the migration guide.",
11343
+ inputSchema: {
11344
+ type: "object",
11345
+ properties: {}
11346
+ },
11347
+ annotations: {
11348
+ readOnlyHint: true,
11349
+ idempotentHint: true,
11350
+ title: "\u27A1\uFE0F Migrate off midnight-mcp",
11351
+ category: "health"
11352
+ },
11353
+ handler: async () => ({
11354
+ status: "deprecated",
11355
+ message: "midnight-mcp is being retired. Midnight has two official replacements.",
11356
+ kapa: {
11357
+ purpose: "Docs Q&A / search",
11358
+ install: "claude mcp add --transport http midnight https://midnight.mcp.kapa.ai",
11359
+ url: "https://midnight.mcp.kapa.ai"
11360
+ },
11361
+ midnightExpert: {
11362
+ purpose: "Hands-on dev (Claude Code plugins)",
11363
+ install: "curl -fsSL https://midnightntwrk.expert/install.sh | bash",
11364
+ url: "https://midnightntwrk.expert"
11365
+ },
11366
+ guide: BLOG_URL
11367
+ })
11368
+ }
11369
+ ];
11370
+
11335
11371
  // src/tools/index.ts
11336
11372
  var allTools = [
11373
+ ...deprecationTools,
11374
+ // Redirect to the official replacements, surfaced first
11337
11375
  ...metaTools,
11338
11376
  // Discovery tools first for visibility
11339
11377
  ...searchTools,
@@ -11355,4 +11393,4 @@ export {
11355
11393
  startServer,
11356
11394
  startHttpServer
11357
11395
  };
11358
- //# sourceMappingURL=chunk-T2CXHJAO.js.map
11396
+ //# sourceMappingURL=chunk-VBZPDFKP.js.map
@@ -0,0 +1,7 @@
1
+ import {
2
+ vectorStore
3
+ } from "./chunk-KRDOSQPS.js";
4
+ export {
5
+ vectorStore
6
+ };
7
+ //# sourceMappingURL=db-3WSIJCLE.js.map
package/dist/index.js CHANGED
@@ -9,10 +9,10 @@ import {
9
9
  promptDefinitions,
10
10
  startHttpServer,
11
11
  startServer
12
- } from "./chunk-T2CXHJAO.js";
12
+ } from "./chunk-VBZPDFKP.js";
13
13
  import {
14
14
  logger
15
- } from "./chunk-YDH6CRK3.js";
15
+ } from "./chunk-KRDOSQPS.js";
16
16
  export {
17
17
  allResources,
18
18
  allTools,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.2.21",
4
- "description": "Model Context Protocol Server for Midnight Blockchain Development",
3
+ "version": "0.3.0",
4
+ "description": "[DEPRECATED — migrate to Kapa + Midnight Expert: https://docs.midnight.network/blog/migrating-to-kapa-and-midnight-expert] Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -1,7 +0,0 @@
1
- import {
2
- vectorStore
3
- } from "./chunk-YDH6CRK3.js";
4
- export {
5
- vectorStore
6
- };
7
- //# sourceMappingURL=db-5GTR4PCW.js.map