midnight-mcp 0.1.8 → 0.1.10
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 +60 -197
- package/dist/tools/analyze.js +2 -0
- package/dist/tools/generation.js +3 -0
- package/dist/tools/health.js +2 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +3 -0
- package/dist/tools/meta.d.ts +61 -0
- package/dist/tools/meta.js +281 -0
- package/dist/tools/repository/handlers.d.ts +73 -15
- package/dist/tools/repository/handlers.js +229 -28
- package/dist/tools/repository/schemas.d.ts +25 -0
- package/dist/tools/repository/schemas.js +18 -0
- package/dist/tools/repository/tools.js +121 -1
- package/dist/tools/search.js +1 -0
- package/dist/types/mcp.d.ts +20 -0
- package/dist/utils/errors.d.ts +66 -0
- package/dist/utils/errors.js +70 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meta-tools for progressive disclosure and tool discovery
|
|
3
|
+
* These tools help AI agents efficiently discover and use available capabilities
|
|
4
|
+
*/
|
|
5
|
+
// Import all tool arrays to build the index
|
|
6
|
+
import { searchTools } from "./search.js";
|
|
7
|
+
import { analyzeTools } from "./analyze.js";
|
|
8
|
+
import { repositoryTools } from "./repository.js";
|
|
9
|
+
import { healthTools } from "./health.js";
|
|
10
|
+
import { generationTools } from "./generation.js";
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Tool Category Descriptions
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const CATEGORY_INFO = {
|
|
15
|
+
search: {
|
|
16
|
+
description: "Semantic search across Midnight codebase - find code by meaning, not keywords",
|
|
17
|
+
useCases: [
|
|
18
|
+
"Find example implementations",
|
|
19
|
+
"Search for patterns",
|
|
20
|
+
"Discover relevant code",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
analyze: {
|
|
24
|
+
description: "Static analysis of Compact contracts - security, structure, patterns",
|
|
25
|
+
useCases: [
|
|
26
|
+
"Security audit",
|
|
27
|
+
"Code review",
|
|
28
|
+
"Understand contract structure",
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
repository: {
|
|
32
|
+
description: "Access repository files, examples, and recent updates",
|
|
33
|
+
useCases: [
|
|
34
|
+
"Get specific files",
|
|
35
|
+
"List examples",
|
|
36
|
+
"Track repository changes",
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
versioning: {
|
|
40
|
+
description: "Version management, breaking changes, and migration assistance",
|
|
41
|
+
useCases: [
|
|
42
|
+
"Check for updates",
|
|
43
|
+
"Plan upgrades",
|
|
44
|
+
"Compare versions",
|
|
45
|
+
"Get migration guides",
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
generation: {
|
|
49
|
+
description: "AI-powered code generation, review, and documentation (requires sampling)",
|
|
50
|
+
useCases: ["Generate contracts", "Review code", "Generate documentation"],
|
|
51
|
+
},
|
|
52
|
+
health: {
|
|
53
|
+
description: "Server health checks and status monitoring",
|
|
54
|
+
useCases: ["Check API status", "Monitor rate limits", "Debug connectivity"],
|
|
55
|
+
},
|
|
56
|
+
compound: {
|
|
57
|
+
description: "Multi-step operations in a single call - saves tokens and reduces latency",
|
|
58
|
+
useCases: [
|
|
59
|
+
"Full upgrade analysis",
|
|
60
|
+
"Get complete repo context",
|
|
61
|
+
"One-shot operations",
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const listCategoriesOutputSchema = {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
categories: {
|
|
69
|
+
type: "array",
|
|
70
|
+
description: "Available tool categories",
|
|
71
|
+
items: {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
name: { type: "string", description: "Category identifier" },
|
|
75
|
+
description: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "What the category does",
|
|
78
|
+
},
|
|
79
|
+
toolCount: { type: "number", description: "Number of tools" },
|
|
80
|
+
useCases: {
|
|
81
|
+
type: "array",
|
|
82
|
+
description: "When to use this category",
|
|
83
|
+
items: { type: "string" },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
totalTools: { type: "number", description: "Total tool count" },
|
|
89
|
+
recommendation: {
|
|
90
|
+
type: "string",
|
|
91
|
+
description: "Suggested starting point",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ["categories", "totalTools"],
|
|
95
|
+
description: "Tool categories for progressive discovery",
|
|
96
|
+
};
|
|
97
|
+
const listCategoryToolsOutputSchema = {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
category: { type: "string", description: "Category name" },
|
|
101
|
+
tools: {
|
|
102
|
+
type: "array",
|
|
103
|
+
description: "Tools in this category",
|
|
104
|
+
items: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
name: { type: "string", description: "Tool name" },
|
|
108
|
+
description: { type: "string", description: "What the tool does" },
|
|
109
|
+
title: { type: "string", description: "Human-readable title" },
|
|
110
|
+
isCompound: {
|
|
111
|
+
type: "boolean",
|
|
112
|
+
description: "Whether this is a compound tool",
|
|
113
|
+
},
|
|
114
|
+
requiresSampling: {
|
|
115
|
+
type: "boolean",
|
|
116
|
+
description: "Requires client sampling capability",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
suggestion: { type: "string", description: "Usage suggestion" },
|
|
122
|
+
},
|
|
123
|
+
required: ["category", "tools"],
|
|
124
|
+
description: "Tools within a specific category",
|
|
125
|
+
};
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// Handler Functions
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Build tool index by category
|
|
130
|
+
function getToolsByCategory() {
|
|
131
|
+
const allTools = [
|
|
132
|
+
...searchTools,
|
|
133
|
+
...analyzeTools,
|
|
134
|
+
...repositoryTools,
|
|
135
|
+
...healthTools,
|
|
136
|
+
...generationTools,
|
|
137
|
+
];
|
|
138
|
+
const byCategory = new Map();
|
|
139
|
+
for (const tool of allTools) {
|
|
140
|
+
const category = tool.annotations?.category || "repository";
|
|
141
|
+
if (!byCategory.has(category)) {
|
|
142
|
+
byCategory.set(category, []);
|
|
143
|
+
}
|
|
144
|
+
byCategory.get(category).push(tool);
|
|
145
|
+
}
|
|
146
|
+
return byCategory;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* List available tool categories
|
|
150
|
+
* Use this first to understand what's available before drilling into specific tools
|
|
151
|
+
*/
|
|
152
|
+
export async function listToolCategories(_input) {
|
|
153
|
+
const toolsByCategory = getToolsByCategory();
|
|
154
|
+
const categories = Object.entries(CATEGORY_INFO).map(([name, info]) => ({
|
|
155
|
+
name,
|
|
156
|
+
description: info.description,
|
|
157
|
+
toolCount: toolsByCategory.get(name)?.length || 0,
|
|
158
|
+
useCases: info.useCases,
|
|
159
|
+
}));
|
|
160
|
+
// Filter out empty categories
|
|
161
|
+
const nonEmptyCategories = categories.filter((c) => c.toolCount > 0);
|
|
162
|
+
const totalTools = nonEmptyCategories.reduce((sum, c) => sum + c.toolCount, 0);
|
|
163
|
+
return {
|
|
164
|
+
categories: nonEmptyCategories,
|
|
165
|
+
totalTools,
|
|
166
|
+
recommendation: "Start with 'compound' category for efficient multi-step operations, or 'search' to find relevant code.",
|
|
167
|
+
tip: "Use midnight-list-category-tools to see tools within a specific category.",
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* List tools within a specific category
|
|
172
|
+
* Progressive disclosure: drill into a category to see its tools
|
|
173
|
+
*/
|
|
174
|
+
export async function listCategoryTools(input) {
|
|
175
|
+
const toolsByCategory = getToolsByCategory();
|
|
176
|
+
const tools = toolsByCategory.get(input.category) || [];
|
|
177
|
+
if (tools.length === 0) {
|
|
178
|
+
return {
|
|
179
|
+
error: `Unknown or empty category: ${input.category}`,
|
|
180
|
+
availableCategories: Object.keys(CATEGORY_INFO),
|
|
181
|
+
suggestion: "Use midnight-list-tool-categories to see available categories.",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const categoryInfo = CATEGORY_INFO[input.category];
|
|
185
|
+
return {
|
|
186
|
+
category: input.category,
|
|
187
|
+
description: categoryInfo.description,
|
|
188
|
+
tools: tools.map((t) => ({
|
|
189
|
+
name: t.name,
|
|
190
|
+
description: t.description.split("\n")[0], // First line only
|
|
191
|
+
title: t.annotations?.title || t.name,
|
|
192
|
+
isCompound: t.annotations?.category === "compound",
|
|
193
|
+
requiresSampling: t.annotations?.longRunningHint &&
|
|
194
|
+
t.annotations?.category === "generation",
|
|
195
|
+
...(input.includeSchemas && {
|
|
196
|
+
inputSchema: t.inputSchema,
|
|
197
|
+
outputSchema: t.outputSchema,
|
|
198
|
+
}),
|
|
199
|
+
})),
|
|
200
|
+
suggestion: generateCategorySuggestion(input.category),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function generateCategorySuggestion(category) {
|
|
204
|
+
switch (category) {
|
|
205
|
+
case "compound":
|
|
206
|
+
return "🚀 Compound tools save 50-70% tokens. Use midnight-upgrade-check or midnight-get-repo-context for efficient operations.";
|
|
207
|
+
case "search":
|
|
208
|
+
return "💡 Search tools use semantic matching - describe what you want in natural language.";
|
|
209
|
+
case "generation":
|
|
210
|
+
return "⚠️ Generation tools require sampling capability. They use the client's LLM for AI-powered operations.";
|
|
211
|
+
case "versioning":
|
|
212
|
+
return "📦 For version checks, prefer midnight-upgrade-check (compound) over individual version tools.";
|
|
213
|
+
case "analyze":
|
|
214
|
+
return "🔍 Analyze tools work on Compact code. Provide the contract source code directly.";
|
|
215
|
+
default:
|
|
216
|
+
return `Use these tools for ${CATEGORY_INFO[category]?.useCases[0] || "related operations"}.`;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// ============================================================================
|
|
220
|
+
// Tool Definitions
|
|
221
|
+
// ============================================================================
|
|
222
|
+
export const metaTools = [
|
|
223
|
+
{
|
|
224
|
+
name: "midnight-list-tool-categories",
|
|
225
|
+
description: "📋 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 21 tools into 7 logical groups.",
|
|
226
|
+
inputSchema: {
|
|
227
|
+
type: "object",
|
|
228
|
+
properties: {
|
|
229
|
+
includeToolCounts: {
|
|
230
|
+
type: "boolean",
|
|
231
|
+
description: "Include number of tools per category (default: true)",
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
required: [],
|
|
235
|
+
},
|
|
236
|
+
outputSchema: listCategoriesOutputSchema,
|
|
237
|
+
annotations: {
|
|
238
|
+
readOnlyHint: true,
|
|
239
|
+
idempotentHint: true,
|
|
240
|
+
title: "📋 List Tool Categories",
|
|
241
|
+
category: "health",
|
|
242
|
+
},
|
|
243
|
+
handler: listToolCategories,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: "midnight-list-category-tools",
|
|
247
|
+
description: "📋 DISCOVERY TOOL: List tools within a specific category. Use after midnight-list-tool-categories to see detailed tool information for a category of interest. Supports progressive disclosure pattern.",
|
|
248
|
+
inputSchema: {
|
|
249
|
+
type: "object",
|
|
250
|
+
properties: {
|
|
251
|
+
category: {
|
|
252
|
+
type: "string",
|
|
253
|
+
enum: [
|
|
254
|
+
"search",
|
|
255
|
+
"analyze",
|
|
256
|
+
"repository",
|
|
257
|
+
"versioning",
|
|
258
|
+
"generation",
|
|
259
|
+
"health",
|
|
260
|
+
"compound",
|
|
261
|
+
],
|
|
262
|
+
description: "Category to list tools for",
|
|
263
|
+
},
|
|
264
|
+
includeSchemas: {
|
|
265
|
+
type: "boolean",
|
|
266
|
+
description: "Include input/output schemas (default: false)",
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
required: ["category"],
|
|
270
|
+
},
|
|
271
|
+
outputSchema: listCategoryToolsOutputSchema,
|
|
272
|
+
annotations: {
|
|
273
|
+
readOnlyHint: true,
|
|
274
|
+
idempotentHint: true,
|
|
275
|
+
title: "📋 List Category Tools",
|
|
276
|
+
category: "health",
|
|
277
|
+
},
|
|
278
|
+
handler: listCategoryTools,
|
|
279
|
+
},
|
|
280
|
+
];
|
|
281
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Repository handler functions
|
|
3
3
|
* Business logic for repository-related MCP tools
|
|
4
4
|
*/
|
|
5
|
-
import type { GetFileInput, ListExamplesInput, GetLatestUpdatesInput, GetVersionInfoInput, CheckBreakingChangesInput, GetMigrationGuideInput, GetFileAtVersionInput, CompareSyntaxInput, GetLatestSyntaxInput } from "./schemas.js";
|
|
5
|
+
import type { GetFileInput, ListExamplesInput, GetLatestUpdatesInput, GetVersionInfoInput, CheckBreakingChangesInput, GetMigrationGuideInput, GetFileAtVersionInput, CompareSyntaxInput, GetLatestSyntaxInput, UpgradeCheckInput, FullRepoContextInput } from "./schemas.js";
|
|
6
6
|
/**
|
|
7
7
|
* Resolve repository name alias to owner/repo
|
|
8
8
|
*/
|
|
@@ -15,22 +15,21 @@ export declare function resolveRepo(repoName?: string): {
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function getFile(input: GetFileInput): Promise<{
|
|
17
17
|
error: string;
|
|
18
|
+
code: "UNKNOWN_REPOSITORY";
|
|
18
19
|
suggestion: string;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
url?: undefined;
|
|
20
|
+
correction: {
|
|
21
|
+
invalidValue: string;
|
|
22
|
+
validValues: string[];
|
|
23
|
+
parameterName: string;
|
|
24
|
+
};
|
|
25
25
|
} | {
|
|
26
26
|
error: string;
|
|
27
|
-
|
|
27
|
+
code: "RESOURCE_NOT_FOUND";
|
|
28
28
|
suggestion: string;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
url?: undefined;
|
|
29
|
+
correction: {
|
|
30
|
+
suggestions?: string[] | undefined;
|
|
31
|
+
invalidPath: string;
|
|
32
|
+
};
|
|
34
33
|
} | {
|
|
35
34
|
content: string;
|
|
36
35
|
path: string;
|
|
@@ -38,8 +37,6 @@ export declare function getFile(input: GetFileInput): Promise<{
|
|
|
38
37
|
sha: string;
|
|
39
38
|
size: number;
|
|
40
39
|
url: string;
|
|
41
|
-
error?: undefined;
|
|
42
|
-
suggestion?: undefined;
|
|
43
40
|
}>;
|
|
44
41
|
/**
|
|
45
42
|
* List available example contracts and DApps
|
|
@@ -177,4 +174,65 @@ export declare function getLatestSyntax(input: GetLatestSyntaxInput): Promise<{
|
|
|
177
174
|
warning?: undefined;
|
|
178
175
|
examplePaths?: undefined;
|
|
179
176
|
}>;
|
|
177
|
+
/**
|
|
178
|
+
* Compound tool: Full upgrade check
|
|
179
|
+
* Combines: getVersionInfo + checkBreakingChanges + getMigrationGuide
|
|
180
|
+
* Reduces 3 tool calls to 1, saving ~60% tokens
|
|
181
|
+
*/
|
|
182
|
+
export declare function upgradeCheck(input: UpgradeCheckInput): Promise<{
|
|
183
|
+
repository: string;
|
|
184
|
+
currentVersion: string;
|
|
185
|
+
version: {
|
|
186
|
+
latest: string;
|
|
187
|
+
latestStable: string;
|
|
188
|
+
publishedAt: string | null;
|
|
189
|
+
isOutdated: boolean;
|
|
190
|
+
versionsBehind: number;
|
|
191
|
+
};
|
|
192
|
+
breakingChanges: {
|
|
193
|
+
count: number;
|
|
194
|
+
hasBreakingChanges: boolean;
|
|
195
|
+
items: string[];
|
|
196
|
+
};
|
|
197
|
+
migration: {
|
|
198
|
+
steps: string[];
|
|
199
|
+
deprecations: string[];
|
|
200
|
+
newFeatures: string[];
|
|
201
|
+
} | null;
|
|
202
|
+
urgency: "none" | "low" | "medium" | "high" | "critical";
|
|
203
|
+
recommendation: string;
|
|
204
|
+
}>;
|
|
205
|
+
/**
|
|
206
|
+
* Compound tool: Full repository context
|
|
207
|
+
* Combines: getVersionInfo + getLatestSyntax + listExamples (filtered)
|
|
208
|
+
* Provides everything needed to start working with a repo
|
|
209
|
+
*/
|
|
210
|
+
export declare function getFullRepoContext(input: FullRepoContextInput): Promise<{
|
|
211
|
+
repository: string;
|
|
212
|
+
quickStart: {
|
|
213
|
+
version: string;
|
|
214
|
+
installCommand: string;
|
|
215
|
+
docsUrl: string;
|
|
216
|
+
};
|
|
217
|
+
version: {
|
|
218
|
+
current: string;
|
|
219
|
+
stable: string | null;
|
|
220
|
+
publishedAt: string | null;
|
|
221
|
+
recentReleases: {
|
|
222
|
+
tag: string;
|
|
223
|
+
date: string;
|
|
224
|
+
}[];
|
|
225
|
+
};
|
|
226
|
+
syntax: {
|
|
227
|
+
version: string;
|
|
228
|
+
files: string[];
|
|
229
|
+
primaryReference: string | null;
|
|
230
|
+
} | null;
|
|
231
|
+
examples: {
|
|
232
|
+
name: string;
|
|
233
|
+
description: string;
|
|
234
|
+
complexity: string;
|
|
235
|
+
}[];
|
|
236
|
+
note: string;
|
|
237
|
+
}>;
|
|
180
238
|
//# sourceMappingURL=handlers.d.ts.map
|