midnight-mcp 0.0.1
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/LICENSE +21 -0
- package/README.md +136 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/vectorStore.d.ts +66 -0
- package/dist/db/vectorStore.d.ts.map +1 -0
- package/dist/db/vectorStore.js +196 -0
- package/dist/db/vectorStore.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/embeddings.d.ts +25 -0
- package/dist/pipeline/embeddings.d.ts.map +1 -0
- package/dist/pipeline/embeddings.js +103 -0
- package/dist/pipeline/embeddings.js.map +1 -0
- package/dist/pipeline/github.d.ts +67 -0
- package/dist/pipeline/github.d.ts.map +1 -0
- package/dist/pipeline/github.js +287 -0
- package/dist/pipeline/github.js.map +1 -0
- package/dist/pipeline/index.d.ts +11 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +6 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/indexer.d.ts +38 -0
- package/dist/pipeline/indexer.d.ts.map +1 -0
- package/dist/pipeline/indexer.js +222 -0
- package/dist/pipeline/indexer.js.map +1 -0
- package/dist/pipeline/parser.d.ts +46 -0
- package/dist/pipeline/parser.d.ts.map +1 -0
- package/dist/pipeline/parser.js +436 -0
- package/dist/pipeline/parser.js.map +1 -0
- package/dist/pipeline/releases.d.ts +112 -0
- package/dist/pipeline/releases.d.ts.map +1 -0
- package/dist/pipeline/releases.js +298 -0
- package/dist/pipeline/releases.js.map +1 -0
- package/dist/pipeline/repository.d.ts +372 -0
- package/dist/pipeline/repository.d.ts.map +1 -0
- package/dist/pipeline/repository.js +517 -0
- package/dist/pipeline/repository.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +2 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/templates.d.ts +26 -0
- package/dist/prompts/templates.d.ts.map +1 -0
- package/dist/prompts/templates.js +353 -0
- package/dist/prompts/templates.js.map +1 -0
- package/dist/resources/code.d.ts +16 -0
- package/dist/resources/code.d.ts.map +1 -0
- package/dist/resources/code.js +630 -0
- package/dist/resources/code.js.map +1 -0
- package/dist/resources/docs.d.ts +16 -0
- package/dist/resources/docs.d.ts.map +1 -0
- package/dist/resources/docs.js +989 -0
- package/dist/resources/docs.js.map +1 -0
- package/dist/resources/index.d.ts +6 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +13 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/schemas.d.ts +16 -0
- package/dist/resources/schemas.d.ts.map +1 -0
- package/dist/resources/schemas.js +407 -0
- package/dist/resources/schemas.js.map +1 -0
- package/dist/scripts/index-repos.d.ts +12 -0
- package/dist/scripts/index-repos.d.ts.map +1 -0
- package/dist/scripts/index-repos.js +53 -0
- package/dist/scripts/index-repos.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +231 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analyze.d.ts +140 -0
- package/dist/tools/analyze.d.ts.map +1 -0
- package/dist/tools/analyze.js +270 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/index.d.ts +392 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/repository.d.ts +537 -0
- package/dist/tools/repository.d.ts.map +1 -0
- package/dist/tools/repository.js +654 -0
- package/dist/tools/repository.js.map +1 -0
- package/dist/tools/search.d.ts +204 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +210 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/utils/config.d.ts +66 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +161 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +64 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
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, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
import { logger } 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
|
+
// Server information
|
|
10
|
+
const SERVER_INFO = {
|
|
11
|
+
name: "midnight-mcp",
|
|
12
|
+
version: "1.0.0",
|
|
13
|
+
description: "MCP Server for Midnight Blockchain Development",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Create and configure the MCP server
|
|
17
|
+
*/
|
|
18
|
+
export function createServer() {
|
|
19
|
+
const server = new Server(SERVER_INFO, {
|
|
20
|
+
capabilities: {
|
|
21
|
+
tools: {},
|
|
22
|
+
resources: {
|
|
23
|
+
subscribe: true,
|
|
24
|
+
listChanged: true,
|
|
25
|
+
},
|
|
26
|
+
prompts: {
|
|
27
|
+
listChanged: true,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
// Register tool handlers
|
|
32
|
+
registerToolHandlers(server);
|
|
33
|
+
// Register resource handlers
|
|
34
|
+
registerResourceHandlers(server);
|
|
35
|
+
// Register prompt handlers
|
|
36
|
+
registerPromptHandlers(server);
|
|
37
|
+
return server;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Register tool handlers
|
|
41
|
+
*/
|
|
42
|
+
function registerToolHandlers(server) {
|
|
43
|
+
// List available tools
|
|
44
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
45
|
+
logger.debug("Listing tools");
|
|
46
|
+
return {
|
|
47
|
+
tools: allTools.map((tool) => ({
|
|
48
|
+
name: tool.name,
|
|
49
|
+
description: tool.description,
|
|
50
|
+
inputSchema: tool.inputSchema,
|
|
51
|
+
})),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
// Handle tool calls
|
|
55
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
56
|
+
const { name, arguments: args } = request.params;
|
|
57
|
+
logger.info(`Tool called: ${name}`, { args });
|
|
58
|
+
const tool = allTools.find((t) => t.name === name);
|
|
59
|
+
if (!tool) {
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: `Unknown tool: ${name}`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
isError: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const result = await tool.handler(args);
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: JSON.stringify(result, null, 2),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logger.error(`Tool error: ${name}`, { error: String(error) });
|
|
83
|
+
return {
|
|
84
|
+
content: [
|
|
85
|
+
{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: `Error executing ${name}: ${error}`,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
isError: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Register resource handlers
|
|
97
|
+
*/
|
|
98
|
+
function registerResourceHandlers(server) {
|
|
99
|
+
// List available resources
|
|
100
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
101
|
+
logger.debug("Listing resources");
|
|
102
|
+
return {
|
|
103
|
+
resources: allResources.map((resource) => ({
|
|
104
|
+
uri: resource.uri,
|
|
105
|
+
name: resource.name,
|
|
106
|
+
description: resource.description,
|
|
107
|
+
mimeType: resource.mimeType,
|
|
108
|
+
})),
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
// Read resource content
|
|
112
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
113
|
+
const { uri } = request.params;
|
|
114
|
+
logger.info(`Resource requested: ${uri}`);
|
|
115
|
+
try {
|
|
116
|
+
let content = null;
|
|
117
|
+
let mimeType = "text/plain";
|
|
118
|
+
if (uri.startsWith("midnight://docs/")) {
|
|
119
|
+
content = await getDocumentation(uri);
|
|
120
|
+
mimeType = "text/markdown";
|
|
121
|
+
}
|
|
122
|
+
else if (uri.startsWith("midnight://code/")) {
|
|
123
|
+
content = await getCode(uri);
|
|
124
|
+
mimeType = "text/x-compact";
|
|
125
|
+
}
|
|
126
|
+
else if (uri.startsWith("midnight://schema/")) {
|
|
127
|
+
const schema = getSchema(uri);
|
|
128
|
+
content = schema ? JSON.stringify(schema, null, 2) : null;
|
|
129
|
+
mimeType = "application/json";
|
|
130
|
+
}
|
|
131
|
+
if (!content) {
|
|
132
|
+
return {
|
|
133
|
+
contents: [
|
|
134
|
+
{
|
|
135
|
+
uri,
|
|
136
|
+
mimeType: "text/plain",
|
|
137
|
+
text: `Resource not found: ${uri}`,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
contents: [
|
|
144
|
+
{
|
|
145
|
+
uri,
|
|
146
|
+
mimeType,
|
|
147
|
+
text: content,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
logger.error(`Resource error: ${uri}`, { error: String(error) });
|
|
154
|
+
return {
|
|
155
|
+
contents: [
|
|
156
|
+
{
|
|
157
|
+
uri,
|
|
158
|
+
mimeType: "text/plain",
|
|
159
|
+
text: `Error reading resource: ${error}`,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Register prompt handlers
|
|
168
|
+
*/
|
|
169
|
+
function registerPromptHandlers(server) {
|
|
170
|
+
// List available prompts
|
|
171
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
172
|
+
logger.debug("Listing prompts");
|
|
173
|
+
return {
|
|
174
|
+
prompts: promptDefinitions.map((prompt) => ({
|
|
175
|
+
name: prompt.name,
|
|
176
|
+
description: prompt.description,
|
|
177
|
+
arguments: prompt.arguments,
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
// Get prompt content
|
|
182
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
183
|
+
const { name, arguments: args } = request.params;
|
|
184
|
+
logger.info(`Prompt requested: ${name}`, { args });
|
|
185
|
+
const prompt = promptDefinitions.find((p) => p.name === name);
|
|
186
|
+
if (!prompt) {
|
|
187
|
+
return {
|
|
188
|
+
description: `Unknown prompt: ${name}`,
|
|
189
|
+
messages: [],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const messages = generatePrompt(name, args || {});
|
|
193
|
+
return {
|
|
194
|
+
description: prompt.description,
|
|
195
|
+
messages: messages.map((m) => ({
|
|
196
|
+
role: m.role,
|
|
197
|
+
content: m.content,
|
|
198
|
+
})),
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Initialize the server and vector store
|
|
204
|
+
*/
|
|
205
|
+
export async function initializeServer() {
|
|
206
|
+
logger.info("Initializing Midnight MCP Server...");
|
|
207
|
+
// Initialize vector store
|
|
208
|
+
try {
|
|
209
|
+
await vectorStore.initialize();
|
|
210
|
+
logger.info("Vector store initialized");
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
logger.warn("Vector store initialization failed, continuing without it", {
|
|
214
|
+
error: String(error),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Create and return server
|
|
218
|
+
const server = createServer();
|
|
219
|
+
logger.info("Server created successfully");
|
|
220
|
+
return server;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Start the server with stdio transport
|
|
224
|
+
*/
|
|
225
|
+
export async function startServer() {
|
|
226
|
+
const server = await initializeServer();
|
|
227
|
+
const transport = new StdioServerTransport();
|
|
228
|
+
await server.connect(transport);
|
|
229
|
+
logger.info("Midnight MCP Server running on stdio");
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEvE,qBAAqB;AACrB,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,gDAAgD;CAC9D,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE;QACrC,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,SAAS,EAAE;gBACT,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,IAAI;aAClB;YACD,OAAO,EAAE;gBACP,WAAW,EAAE,IAAI;aAClB;SACF;KACF,CAAC,CAAC;IAEH,yBAAyB;IACzB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,6BAA6B;IAC7B,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAEjC,2BAA2B;IAC3B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,MAAc;IAC1C,uBAAuB;IACvB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC9B,OAAO;YACL,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,oBAAoB;IACpB,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,iBAAiB,IAAI,EAAE;qBAC9B;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAa,CAAC,CAAC;YACjD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9D,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mBAAmB,IAAI,KAAK,KAAK,EAAE;qBAC1C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,MAAc;IAC9C,2BAA2B;IAC3B,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClC,OAAO;YACL,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACzC,GAAG,EAAE,QAAQ,CAAC,GAAG;gBACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;aAC5B,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACpE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,IAAI,OAAO,GAAkB,IAAI,CAAC;YAClC,IAAI,QAAQ,GAAG,YAAY,CAAC;YAE5B,IAAI,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACvC,OAAO,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBACtC,QAAQ,GAAG,eAAe,CAAC;YAC7B,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC9C,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC7B,QAAQ,GAAG,gBAAgB,CAAC;YAC9B,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;gBAChD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC9B,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC1D,QAAQ,GAAG,kBAAkB,CAAC;YAChC,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG;4BACH,QAAQ,EAAE,YAAY;4BACtB,IAAI,EAAE,uBAAuB,GAAG,EAAE;yBACnC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ;wBACR,IAAI,EAAE,OAAO;qBACd;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,mBAAmB,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjE,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,YAAY;wBACtB,IAAI,EAAE,2BAA2B,KAAK,EAAE;qBACzC;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,MAAc;IAC5C,yBAAyB;IACzB,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,qBAAqB;IACrB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,WAAW,EAAE,mBAAmB,IAAI,EAAE;gBACtC,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAElD,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAEnD,0BAA0B;IAC1B,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,2DAA2D,EAAE;YACvE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B;IAC3B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAE3C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const AnalyzeContractInputSchema: z.ZodObject<{
|
|
3
|
+
code: z.ZodString;
|
|
4
|
+
checkSecurity: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
code: string;
|
|
7
|
+
checkSecurity: boolean;
|
|
8
|
+
}, {
|
|
9
|
+
code: string;
|
|
10
|
+
checkSecurity?: boolean | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const ExplainCircuitInputSchema: z.ZodObject<{
|
|
13
|
+
circuitCode: z.ZodString;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
circuitCode: string;
|
|
16
|
+
}, {
|
|
17
|
+
circuitCode: string;
|
|
18
|
+
}>;
|
|
19
|
+
export type AnalyzeContractInput = z.infer<typeof AnalyzeContractInputSchema>;
|
|
20
|
+
export type ExplainCircuitInput = z.infer<typeof ExplainCircuitInputSchema>;
|
|
21
|
+
interface SecurityFinding {
|
|
22
|
+
severity: "info" | "warning" | "error";
|
|
23
|
+
message: string;
|
|
24
|
+
line?: number;
|
|
25
|
+
suggestion?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Analyze a Compact smart contract for structure, patterns, and potential issues
|
|
29
|
+
*/
|
|
30
|
+
export declare function analyzeContract(input: AnalyzeContractInput): Promise<{
|
|
31
|
+
summary: {
|
|
32
|
+
hasLedger: boolean;
|
|
33
|
+
hasCircuits: boolean;
|
|
34
|
+
hasWitnesses: boolean;
|
|
35
|
+
totalLines: number;
|
|
36
|
+
publicCircuits: number;
|
|
37
|
+
privateCircuits: number;
|
|
38
|
+
publicState: number;
|
|
39
|
+
privateState: number;
|
|
40
|
+
};
|
|
41
|
+
structure: {
|
|
42
|
+
imports: string[];
|
|
43
|
+
exports: string[];
|
|
44
|
+
ledger: {
|
|
45
|
+
name: string;
|
|
46
|
+
type: string | undefined;
|
|
47
|
+
isPrivate: boolean;
|
|
48
|
+
}[];
|
|
49
|
+
circuits: {
|
|
50
|
+
name: string;
|
|
51
|
+
isPublic: boolean;
|
|
52
|
+
parameters: {
|
|
53
|
+
name: string;
|
|
54
|
+
type: string;
|
|
55
|
+
}[] | undefined;
|
|
56
|
+
returnType: string | undefined;
|
|
57
|
+
}[];
|
|
58
|
+
witnesses: {
|
|
59
|
+
name: string;
|
|
60
|
+
parameters: {
|
|
61
|
+
name: string;
|
|
62
|
+
type: string;
|
|
63
|
+
}[] | undefined;
|
|
64
|
+
returnType: string | undefined;
|
|
65
|
+
}[];
|
|
66
|
+
types: {
|
|
67
|
+
name: string;
|
|
68
|
+
definition: string | undefined;
|
|
69
|
+
}[];
|
|
70
|
+
};
|
|
71
|
+
securityFindings: SecurityFinding[];
|
|
72
|
+
recommendations: (string | undefined)[];
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Explain what a specific circuit does in plain language
|
|
76
|
+
*/
|
|
77
|
+
export declare function explainCircuit(input: ExplainCircuitInput): Promise<{
|
|
78
|
+
error: string;
|
|
79
|
+
suggestion: string;
|
|
80
|
+
circuitName?: undefined;
|
|
81
|
+
isPublic?: undefined;
|
|
82
|
+
parameters?: undefined;
|
|
83
|
+
returnType?: undefined;
|
|
84
|
+
explanation?: undefined;
|
|
85
|
+
operations?: undefined;
|
|
86
|
+
zkImplications?: undefined;
|
|
87
|
+
privacyConsiderations?: undefined;
|
|
88
|
+
} | {
|
|
89
|
+
circuitName: string;
|
|
90
|
+
isPublic: boolean;
|
|
91
|
+
parameters: {
|
|
92
|
+
name: string;
|
|
93
|
+
type: string;
|
|
94
|
+
}[] | undefined;
|
|
95
|
+
returnType: string | undefined;
|
|
96
|
+
explanation: string;
|
|
97
|
+
operations: string[];
|
|
98
|
+
zkImplications: string[];
|
|
99
|
+
privacyConsiderations: string[];
|
|
100
|
+
error?: undefined;
|
|
101
|
+
suggestion?: undefined;
|
|
102
|
+
}>;
|
|
103
|
+
export declare const analyzeTools: ({
|
|
104
|
+
name: string;
|
|
105
|
+
description: string;
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: "object";
|
|
108
|
+
properties: {
|
|
109
|
+
code: {
|
|
110
|
+
type: string;
|
|
111
|
+
description: string;
|
|
112
|
+
};
|
|
113
|
+
checkSecurity: {
|
|
114
|
+
type: string;
|
|
115
|
+
description: string;
|
|
116
|
+
};
|
|
117
|
+
circuitCode?: undefined;
|
|
118
|
+
};
|
|
119
|
+
required: string[];
|
|
120
|
+
};
|
|
121
|
+
handler: typeof analyzeContract;
|
|
122
|
+
} | {
|
|
123
|
+
name: string;
|
|
124
|
+
description: string;
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: "object";
|
|
127
|
+
properties: {
|
|
128
|
+
circuitCode: {
|
|
129
|
+
type: string;
|
|
130
|
+
description: string;
|
|
131
|
+
};
|
|
132
|
+
code?: undefined;
|
|
133
|
+
checkSecurity?: undefined;
|
|
134
|
+
};
|
|
135
|
+
required: string[];
|
|
136
|
+
};
|
|
137
|
+
handler: typeof explainCircuit;
|
|
138
|
+
})[];
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=analyze.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/tools/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,0BAA0B;;;;;;;;;EAOrC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;EAEpC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+HhE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;GA6E9D;AAmED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqCxB,CAAC"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { parseCompactFile } from "../pipeline/index.js";
|
|
3
|
+
import { logger } from "../utils/index.js";
|
|
4
|
+
// Schema definitions
|
|
5
|
+
export const AnalyzeContractInputSchema = z.object({
|
|
6
|
+
code: z.string().describe("Compact contract source code"),
|
|
7
|
+
checkSecurity: z
|
|
8
|
+
.boolean()
|
|
9
|
+
.optional()
|
|
10
|
+
.default(true)
|
|
11
|
+
.describe("Run security analysis"),
|
|
12
|
+
});
|
|
13
|
+
export const ExplainCircuitInputSchema = z.object({
|
|
14
|
+
circuitCode: z.string().describe("Circuit definition from Compact"),
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Analyze a Compact smart contract for structure, patterns, and potential issues
|
|
18
|
+
*/
|
|
19
|
+
export async function analyzeContract(input) {
|
|
20
|
+
logger.debug("Analyzing Compact contract");
|
|
21
|
+
const parsed = parseCompactFile("contract.compact", input.code);
|
|
22
|
+
const findings = [];
|
|
23
|
+
// Extract structured information
|
|
24
|
+
const ledgerFields = parsed.codeUnits.filter((u) => u.type === "ledger");
|
|
25
|
+
const circuits = parsed.codeUnits.filter((u) => u.type === "circuit");
|
|
26
|
+
const witnesses = parsed.codeUnits.filter((u) => u.type === "witness");
|
|
27
|
+
const types = parsed.codeUnits.filter((u) => u.type === "type");
|
|
28
|
+
// Security analysis
|
|
29
|
+
if (input.checkSecurity) {
|
|
30
|
+
// Check for private state exposure
|
|
31
|
+
const privateFields = ledgerFields.filter((f) => f.isPrivate);
|
|
32
|
+
for (const field of privateFields) {
|
|
33
|
+
// Check if private field is used in a public circuit without proper protection
|
|
34
|
+
for (const circuit of circuits) {
|
|
35
|
+
if (circuit.isPublic && circuit.code.includes(field.name)) {
|
|
36
|
+
if (!circuit.code.includes("disclose") &&
|
|
37
|
+
!circuit.code.includes("commit")) {
|
|
38
|
+
findings.push({
|
|
39
|
+
severity: "warning",
|
|
40
|
+
message: `Private field '${field.name}' used in public circuit '${circuit.name}' without disclose/commit`,
|
|
41
|
+
suggestion: "Consider using disclose() or commit() to properly handle private data",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Check for missing access control on state-modifying circuits
|
|
48
|
+
for (const circuit of circuits) {
|
|
49
|
+
if (circuit.isPublic) {
|
|
50
|
+
const modifiesState = circuit.code.includes(".insert") ||
|
|
51
|
+
circuit.code.includes(".increment") ||
|
|
52
|
+
circuit.code.includes(".decrement") ||
|
|
53
|
+
circuit.code.includes("=");
|
|
54
|
+
if (modifiesState && !circuit.code.includes("assert")) {
|
|
55
|
+
findings.push({
|
|
56
|
+
severity: "info",
|
|
57
|
+
message: `Public circuit '${circuit.name}' modifies state without assertions`,
|
|
58
|
+
suggestion: "Consider adding assertions to validate inputs and permissions",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Check for unused witnesses
|
|
64
|
+
for (const witness of witnesses) {
|
|
65
|
+
let isUsed = false;
|
|
66
|
+
for (const circuit of circuits) {
|
|
67
|
+
if (circuit.code.includes(witness.name)) {
|
|
68
|
+
isUsed = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!isUsed) {
|
|
73
|
+
findings.push({
|
|
74
|
+
severity: "info",
|
|
75
|
+
message: `Witness '${witness.name}' is defined but not used in any circuit`,
|
|
76
|
+
suggestion: "Remove unused witnesses or implement their usage",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Check for common patterns
|
|
81
|
+
if (!parsed.imports.includes("std")) {
|
|
82
|
+
findings.push({
|
|
83
|
+
severity: "info",
|
|
84
|
+
message: "Standard library not imported",
|
|
85
|
+
suggestion: "Consider adding 'include \"std\";' for common utilities",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Generate summary
|
|
90
|
+
const summary = {
|
|
91
|
+
hasLedger: parsed.metadata.hasLedger,
|
|
92
|
+
hasCircuits: parsed.metadata.hasCircuits,
|
|
93
|
+
hasWitnesses: parsed.metadata.hasWitnesses,
|
|
94
|
+
totalLines: parsed.metadata.lineCount,
|
|
95
|
+
publicCircuits: circuits.filter((c) => c.isPublic).length,
|
|
96
|
+
privateCircuits: circuits.filter((c) => !c.isPublic).length,
|
|
97
|
+
publicState: ledgerFields.filter((f) => !f.isPrivate).length,
|
|
98
|
+
privateState: ledgerFields.filter((f) => f.isPrivate).length,
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
summary,
|
|
102
|
+
structure: {
|
|
103
|
+
imports: parsed.imports,
|
|
104
|
+
exports: parsed.exports,
|
|
105
|
+
ledger: ledgerFields.map((f) => ({
|
|
106
|
+
name: f.name,
|
|
107
|
+
type: f.returnType,
|
|
108
|
+
isPrivate: f.isPrivate,
|
|
109
|
+
})),
|
|
110
|
+
circuits: circuits.map((c) => ({
|
|
111
|
+
name: c.name,
|
|
112
|
+
isPublic: c.isPublic,
|
|
113
|
+
parameters: c.parameters,
|
|
114
|
+
returnType: c.returnType,
|
|
115
|
+
})),
|
|
116
|
+
witnesses: witnesses.map((w) => ({
|
|
117
|
+
name: w.name,
|
|
118
|
+
parameters: w.parameters,
|
|
119
|
+
returnType: w.returnType,
|
|
120
|
+
})),
|
|
121
|
+
types: types.map((t) => ({
|
|
122
|
+
name: t.name,
|
|
123
|
+
definition: t.returnType,
|
|
124
|
+
})),
|
|
125
|
+
},
|
|
126
|
+
securityFindings: findings,
|
|
127
|
+
recommendations: findings.length === 0
|
|
128
|
+
? ["Contract structure looks good! No issues found."]
|
|
129
|
+
: findings.map((f) => f.suggestion).filter(Boolean),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Explain what a specific circuit does in plain language
|
|
134
|
+
*/
|
|
135
|
+
export async function explainCircuit(input) {
|
|
136
|
+
logger.debug("Explaining circuit");
|
|
137
|
+
const parsed = parseCompactFile("circuit.compact", input.circuitCode);
|
|
138
|
+
const circuit = parsed.codeUnits.find((u) => u.type === "circuit");
|
|
139
|
+
if (!circuit) {
|
|
140
|
+
return {
|
|
141
|
+
error: "No circuit definition found in the provided code",
|
|
142
|
+
suggestion: "Make sure to provide a complete circuit definition including 'circuit' keyword",
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Analyze the circuit
|
|
146
|
+
const operations = [];
|
|
147
|
+
const zkImplications = [];
|
|
148
|
+
// Detect common operations
|
|
149
|
+
if (circuit.code.includes("disclose")) {
|
|
150
|
+
operations.push("Reveals private data selectively (disclose)");
|
|
151
|
+
zkImplications.push("Data revealed via disclose() will be visible on-chain while proving possession of private data");
|
|
152
|
+
}
|
|
153
|
+
if (circuit.code.includes("commit")) {
|
|
154
|
+
operations.push("Creates cryptographic commitments (commit)");
|
|
155
|
+
zkImplications.push("Commitments allow hiding data while proving properties about it");
|
|
156
|
+
}
|
|
157
|
+
if (circuit.code.includes("hash")) {
|
|
158
|
+
operations.push("Computes cryptographic hashes (hash)");
|
|
159
|
+
zkImplications.push("Hashes are computed in-circuit and can be verified without revealing preimages");
|
|
160
|
+
}
|
|
161
|
+
if (circuit.code.includes("assert")) {
|
|
162
|
+
operations.push("Validates constraints (assert)");
|
|
163
|
+
zkImplications.push("Assertions create ZK constraints - the proof will fail if any assertion fails");
|
|
164
|
+
}
|
|
165
|
+
if (circuit.code.includes(".insert")) {
|
|
166
|
+
operations.push("Inserts data into ledger storage");
|
|
167
|
+
}
|
|
168
|
+
if (circuit.code.includes(".increment")) {
|
|
169
|
+
operations.push("Increments a counter value");
|
|
170
|
+
}
|
|
171
|
+
if (circuit.code.includes(".decrement")) {
|
|
172
|
+
operations.push("Decrements a counter value");
|
|
173
|
+
}
|
|
174
|
+
// Build explanation
|
|
175
|
+
const explanation = buildCircuitExplanation(circuit, operations);
|
|
176
|
+
return {
|
|
177
|
+
circuitName: circuit.name,
|
|
178
|
+
isPublic: circuit.isPublic,
|
|
179
|
+
parameters: circuit.parameters,
|
|
180
|
+
returnType: circuit.returnType,
|
|
181
|
+
explanation,
|
|
182
|
+
operations,
|
|
183
|
+
zkImplications: zkImplications.length > 0
|
|
184
|
+
? zkImplications
|
|
185
|
+
: [
|
|
186
|
+
"This circuit generates a zero-knowledge proof that the computation was performed correctly",
|
|
187
|
+
],
|
|
188
|
+
privacyConsiderations: getPrivacyConsiderations(circuit),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function buildCircuitExplanation(circuit, operations) {
|
|
192
|
+
let explanation = `The circuit '${circuit.name}' is a `;
|
|
193
|
+
if (circuit.isPublic) {
|
|
194
|
+
explanation += "public (exported) function that can be called by anyone. ";
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
explanation += "private (internal) function used by other circuits. ";
|
|
198
|
+
}
|
|
199
|
+
if (circuit.parameters && circuit.parameters.length > 0) {
|
|
200
|
+
explanation += `It takes ${circuit.parameters.length} parameter(s): `;
|
|
201
|
+
explanation += circuit.parameters
|
|
202
|
+
.map((p) => `${p.name} (${p.type})`)
|
|
203
|
+
.join(", ");
|
|
204
|
+
explanation += ". ";
|
|
205
|
+
}
|
|
206
|
+
if (circuit.returnType && circuit.returnType !== "Void") {
|
|
207
|
+
explanation += `It returns a value of type ${circuit.returnType}. `;
|
|
208
|
+
}
|
|
209
|
+
if (operations.length > 0) {
|
|
210
|
+
explanation += `\n\nKey operations performed:\n`;
|
|
211
|
+
operations.forEach((op, i) => {
|
|
212
|
+
explanation += `${i + 1}. ${op}\n`;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return explanation;
|
|
216
|
+
}
|
|
217
|
+
function getPrivacyConsiderations(circuit) {
|
|
218
|
+
const considerations = [];
|
|
219
|
+
if (circuit.code.includes("disclose")) {
|
|
220
|
+
considerations.push("Uses disclose() - some private data will be revealed on-chain");
|
|
221
|
+
}
|
|
222
|
+
if (circuit.isPublic) {
|
|
223
|
+
considerations.push("Public circuit - anyone can call this and generate proofs");
|
|
224
|
+
}
|
|
225
|
+
if (circuit.code.includes("@private") || circuit.code.includes("witness")) {
|
|
226
|
+
considerations.push("Accesses private state or witnesses - ensure sensitive data is handled correctly");
|
|
227
|
+
}
|
|
228
|
+
if (considerations.length === 0) {
|
|
229
|
+
considerations.push("No specific privacy concerns identified in this circuit");
|
|
230
|
+
}
|
|
231
|
+
return considerations;
|
|
232
|
+
}
|
|
233
|
+
// Tool definitions for MCP
|
|
234
|
+
export const analyzeTools = [
|
|
235
|
+
{
|
|
236
|
+
name: "midnight-analyze-contract",
|
|
237
|
+
description: "Analyze a Compact smart contract for structure, patterns, and potential security issues. Returns detailed breakdown of circuits, witnesses, ledger state, and recommendations.",
|
|
238
|
+
inputSchema: {
|
|
239
|
+
type: "object",
|
|
240
|
+
properties: {
|
|
241
|
+
code: {
|
|
242
|
+
type: "string",
|
|
243
|
+
description: "Compact contract source code to analyze",
|
|
244
|
+
},
|
|
245
|
+
checkSecurity: {
|
|
246
|
+
type: "boolean",
|
|
247
|
+
description: "Run security analysis (default: true)",
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
required: ["code"],
|
|
251
|
+
},
|
|
252
|
+
handler: analyzeContract,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
name: "midnight-explain-circuit",
|
|
256
|
+
description: "Explain what a specific Compact circuit does in plain language, including its zero-knowledge proof implications and privacy considerations.",
|
|
257
|
+
inputSchema: {
|
|
258
|
+
type: "object",
|
|
259
|
+
properties: {
|
|
260
|
+
circuitCode: {
|
|
261
|
+
type: "string",
|
|
262
|
+
description: "Circuit definition from Compact to explain",
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
required: ["circuitCode"],
|
|
266
|
+
},
|
|
267
|
+
handler: explainCircuit,
|
|
268
|
+
},
|
|
269
|
+
];
|
|
270
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/tools/analyze.ts"],"names":[],"mappings":"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"}
|