cache-overflow-mcp 0.3.5 → 0.3.7
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/dist/client.d.ts.map +1 -1
- package/dist/client.js +12 -1
- package/dist/client.js.map +1 -1
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +55 -1
- package/dist/prompts/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +18 -10
- package/dist/server.js.map +1 -1
- package/dist/services/config-service.d.ts +27 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +100 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/testing/mock-server.d.ts.map +1 -1
- package/dist/testing/mock-server.js +13 -5
- package/dist/testing/mock-server.js.map +1 -1
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +53 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +17 -1
- package/src/prompts/index.ts +67 -1
- package/src/server.ts +37 -19
- package/src/services/config-service.ts +119 -0
- package/src/testing/mock-server.ts +15 -7
- package/src/tools/index.ts +70 -1
- package/src/types.ts +48 -0
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIvE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqB;gBAE1B,MAAM,CAAC,EAAE,MAAM;YAKb,OAAO;IAyEf,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIvE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqB;gBAE1B,MAAM,CAAC,EAAE,MAAM;YAKb,OAAO;IAyEf,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAoBvE,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAIlE,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAO3B,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAMvB,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;CAK9B"}
|
package/dist/client.js
CHANGED
|
@@ -69,7 +69,18 @@ export class CacheOverflowClient {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
async findSolution(query) {
|
|
72
|
-
|
|
72
|
+
const result = await this.request('GET', `/solutions/search?query=${encodeURIComponent(query)}`);
|
|
73
|
+
// Map API response (uses 'id') to our interface (expects 'solution_id')
|
|
74
|
+
if (result.success) {
|
|
75
|
+
const mappedData = result.data.map(solution => ({
|
|
76
|
+
solution_id: solution.id,
|
|
77
|
+
query_title: solution.query_title,
|
|
78
|
+
solution_body: solution.solution_body,
|
|
79
|
+
human_verification_required: solution.human_verification_required,
|
|
80
|
+
}));
|
|
81
|
+
return { success: true, data: mappedData };
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
73
84
|
}
|
|
74
85
|
async unlockSolution(solutionId) {
|
|
75
86
|
return this.request('POST', `/solutions/${solutionId}/unlock`);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAS;IACf,SAAS,CAAqB;IAEtC,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAc,EACd,IAAY,EACZ,IAAc;QAEd,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;QACxD,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QAEpC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;aAC9C,CAAC,CAAC;YAEH,yDAAyD;YACzD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACzD,IAAI,IAA6B,CAAC;YAElC,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAA4B,CAAC;YAC7D,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,0DAA0D;gBAC1D,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,SAAkB,EAAE;oBACjE,MAAM;oBACN,IAAI;oBACJ,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,WAAW;oBACX,YAAY,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,sBAAsB;oBACpE,SAAS,EAAE,uBAAuB;iBACnC,CAAC,CAAC;gBAEH,sCAAsC;gBACtC,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,YAAY,IAAI,8BAA8B;iBACtD,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,YAAY,GAAI,IAAI,CAAC,KAAgB,IAAI,eAAe,CAAC;gBAC/D,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,SAAS,EAAE;oBAC5C,MAAM;oBACN,IAAI;oBACJ,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,YAAY;oBACZ,SAAS,EAAE,WAAW;iBACvB,CAAC,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;YACjD,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAS,EAAE,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAc,EAAE;gBACxE,MAAM;gBACN,IAAI;gBACJ,GAAG;gBACH,SAAS,EAAE,eAAe;aAC3B,CAAC,CAAC;YAEH,+DAA+D;YAC/D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -10,5 +10,11 @@ export interface PromptDefinition {
|
|
|
10
10
|
}
|
|
11
11
|
export declare const publishGuidancePrompt: PromptDefinition;
|
|
12
12
|
export declare const workflowGuidancePrompt: PromptDefinition;
|
|
13
|
+
export declare const FALLBACK_PROMPTS: PromptDefinition[];
|
|
14
|
+
/**
|
|
15
|
+
* Get prompts with definitions from the backend API.
|
|
16
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getPrompts(): Promise<PromptDefinition[]>;
|
|
13
19
|
export declare const prompts: PromptDefinition[];
|
|
14
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAKzE,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;QACjD,QAAQ,EAAE,KAAK,CAAC;YACd,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;YAC3B,OAAO,EAAE,WAAW,CAAC;SACtB,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ;AAED,eAAO,MAAM,qBAAqB,EAAE,gBA2FnC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,gBA4DpC,CAAC;AAGF,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,EAG9C,CAAC;AAmCF;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgB9D;AAID,eAAO,MAAM,OAAO,EAAE,gBAAgB,EAAqB,CAAC"}
|
package/dist/prompts/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { configService } from '../services/config-service.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
1
3
|
export const publishGuidancePrompt = {
|
|
2
4
|
definition: {
|
|
3
5
|
name: 'publish_solution_guidance',
|
|
@@ -149,5 +151,57 @@ Then call \`publish_solution\` to share it with other agents!
|
|
|
149
151
|
],
|
|
150
152
|
}),
|
|
151
153
|
};
|
|
152
|
-
|
|
154
|
+
// Fallback prompts used when backend is unavailable
|
|
155
|
+
export const FALLBACK_PROMPTS = [
|
|
156
|
+
publishGuidancePrompt,
|
|
157
|
+
workflowGuidancePrompt,
|
|
158
|
+
];
|
|
159
|
+
/**
|
|
160
|
+
* Convert a remote prompt definition to a local Prompt format
|
|
161
|
+
*/
|
|
162
|
+
function remoteToLocalPrompt(remote) {
|
|
163
|
+
return {
|
|
164
|
+
name: remote.name,
|
|
165
|
+
description: remote.description,
|
|
166
|
+
arguments: remote.arguments.map((arg) => ({
|
|
167
|
+
name: arg.name,
|
|
168
|
+
description: arg.description,
|
|
169
|
+
required: arg.required,
|
|
170
|
+
})),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Create a handler for a remote prompt definition.
|
|
175
|
+
* The handler returns the pre-defined messages from the remote config.
|
|
176
|
+
*/
|
|
177
|
+
function createRemotePromptHandler(remote) {
|
|
178
|
+
return async () => ({
|
|
179
|
+
messages: remote.messages.map((msg) => ({
|
|
180
|
+
role: msg.role,
|
|
181
|
+
content: {
|
|
182
|
+
type: msg.content.type,
|
|
183
|
+
text: msg.content.text,
|
|
184
|
+
},
|
|
185
|
+
})),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get prompts with definitions from the backend API.
|
|
190
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
191
|
+
*/
|
|
192
|
+
export async function getPrompts() {
|
|
193
|
+
const remoteConfig = await configService.fetchConfig();
|
|
194
|
+
if (!remoteConfig) {
|
|
195
|
+
logger.info('Using fallback prompt definitions');
|
|
196
|
+
return FALLBACK_PROMPTS;
|
|
197
|
+
}
|
|
198
|
+
const prompts = remoteConfig.prompts.map((remotePrompt) => ({
|
|
199
|
+
definition: remoteToLocalPrompt(remotePrompt),
|
|
200
|
+
handler: createRemotePromptHandler(remotePrompt),
|
|
201
|
+
}));
|
|
202
|
+
return prompts;
|
|
203
|
+
}
|
|
204
|
+
// Keep backward compatibility - export prompts array for existing code
|
|
205
|
+
// Note: This is the fallback, prefer using getPrompts() for dynamic loading
|
|
206
|
+
export const prompts = FALLBACK_PROMPTS;
|
|
153
207
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAaA,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAsB;;IAoBpC,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAaA,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAsB;;IAoBpC,OAAO,CAAC,aAAa;IA+Ef,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
|
package/dist/server.js
CHANGED
|
@@ -2,8 +2,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { CacheOverflowClient } from './client.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { getTools } from './tools/index.js';
|
|
6
|
+
import { getPrompts } from './prompts/index.js';
|
|
7
7
|
import { logger } from './logger.js';
|
|
8
8
|
export class CacheOverflowServer {
|
|
9
9
|
server;
|
|
@@ -23,16 +23,20 @@ export class CacheOverflowServer {
|
|
|
23
23
|
}
|
|
24
24
|
setupHandlers() {
|
|
25
25
|
// Tool handlers
|
|
26
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27
|
+
const tools = await getTools();
|
|
28
|
+
return {
|
|
29
|
+
tools: tools.map((t) => t.definition),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
29
32
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
33
|
+
const tools = await getTools();
|
|
30
34
|
const tool = tools.find((t) => t.definition.name === request.params.name);
|
|
31
35
|
if (!tool) {
|
|
32
36
|
const error = new Error(`Unknown tool: ${request.params.name}`);
|
|
33
37
|
logger.error('Unknown tool requested', error, {
|
|
34
38
|
toolName: request.params.name,
|
|
35
|
-
availableTools: tools.map(t => t.definition.name),
|
|
39
|
+
availableTools: tools.map((t) => t.definition.name),
|
|
36
40
|
});
|
|
37
41
|
throw error;
|
|
38
42
|
}
|
|
@@ -53,16 +57,20 @@ export class CacheOverflowServer {
|
|
|
53
57
|
}
|
|
54
58
|
});
|
|
55
59
|
// Prompt handlers
|
|
56
|
-
this.server.setRequestHandler(ListPromptsRequestSchema, async () =>
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
61
|
+
const prompts = await getPrompts();
|
|
62
|
+
return {
|
|
63
|
+
prompts: prompts.map((p) => p.definition),
|
|
64
|
+
};
|
|
65
|
+
});
|
|
59
66
|
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
67
|
+
const prompts = await getPrompts();
|
|
60
68
|
const prompt = prompts.find((p) => p.definition.name === request.params.name);
|
|
61
69
|
if (!prompt) {
|
|
62
70
|
const error = new Error(`Unknown prompt: ${request.params.name}`);
|
|
63
71
|
logger.error('Unknown prompt requested', error, {
|
|
64
72
|
promptName: request.params.name,
|
|
65
|
-
availablePrompts: prompts.map(p => p.definition.name),
|
|
73
|
+
availablePrompts: prompts.map((p) => p.definition.name),
|
|
66
74
|
});
|
|
67
75
|
throw error;
|
|
68
76
|
}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +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,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,
|
|
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,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAS;IACf,MAAM,CAAsB;IAEpC;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB;YACE,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,OAAO;SACjB,EACD;YACE,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,EAAE;aACZ;SACF,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACxC,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,gBAAgB;QAChB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,OAAO;gBACL,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;aACtC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACrE,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1E,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBAChE,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,EAAE;oBAC5C,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBAC7B,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;iBACpD,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;oBACpD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBAC7B,gEAAgE;oBAChE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;iBACrE,CAAC,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CACV,0BAA0B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAC/C,KAAc,EACd;oBACE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBAC7B,SAAS,EAAE,wBAAwB;iBACpC,CACF,CAAC;gBACF,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,kBAAkB;QAClB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;YACnC,OAAO;gBACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;aAC1C,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtE,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CACjD,CAAC;YACF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBAClE,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,EAAE;oBAC9C,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBAC/B,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;iBACxD,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CACV,4BAA4B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EACjD,KAAc,EACd;oBACE,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBAC/B,SAAS,EAAE,0BAA0B;iBACtC,CACF,CAAC;gBACF,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;YAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAc,EAAE;gBAC3D,SAAS,EAAE,oBAAoB;aAChC,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { McpConfigResponse } from '../types.js';
|
|
2
|
+
declare class ConfigService {
|
|
3
|
+
private cache;
|
|
4
|
+
/**
|
|
5
|
+
* Fetch MCP configuration from the backend API.
|
|
6
|
+
* Returns cached value if available and not expired.
|
|
7
|
+
* Falls back to null on failure (caller should use fallback).
|
|
8
|
+
*/
|
|
9
|
+
fetchConfig(): Promise<McpConfigResponse | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Check if the schema version is compatible.
|
|
12
|
+
* For now, we only support exact match.
|
|
13
|
+
* Later can implement semantic version comparison.
|
|
14
|
+
*/
|
|
15
|
+
private isSchemaVersionCompatible;
|
|
16
|
+
/**
|
|
17
|
+
* Return cached value if available, otherwise null.
|
|
18
|
+
*/
|
|
19
|
+
private getCachedOrNull;
|
|
20
|
+
/**
|
|
21
|
+
* Invalidate the cache, forcing a fresh fetch on next request.
|
|
22
|
+
*/
|
|
23
|
+
invalidateCache(): void;
|
|
24
|
+
}
|
|
25
|
+
export declare const configService: ConfigService;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=config-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.d.ts","sourceRoot":"","sources":["../../src/services/config-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAWrD,cAAM,aAAa;IACjB,OAAO,CAAC,KAAK,CAA6B;IAE1C;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAkEtD;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAOjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,eAAe,IAAI,IAAI;CAGxB;AAGD,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
4
|
+
const FETCH_TIMEOUT_MS = 5000; // 5 seconds
|
|
5
|
+
const SUPPORTED_SCHEMA_VERSION = '1.0.0';
|
|
6
|
+
class ConfigService {
|
|
7
|
+
cache = null;
|
|
8
|
+
/**
|
|
9
|
+
* Fetch MCP configuration from the backend API.
|
|
10
|
+
* Returns cached value if available and not expired.
|
|
11
|
+
* Falls back to null on failure (caller should use fallback).
|
|
12
|
+
*/
|
|
13
|
+
async fetchConfig() {
|
|
14
|
+
// Return cached value if still valid
|
|
15
|
+
if (this.cache && Date.now() - this.cache.fetchedAt < CACHE_TTL_MS) {
|
|
16
|
+
return this.cache.data;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const controller = new AbortController();
|
|
20
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
21
|
+
const response = await fetch(`${config.api.url}/mcp/config`, {
|
|
22
|
+
method: 'GET',
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'application/json',
|
|
25
|
+
},
|
|
26
|
+
signal: controller.signal,
|
|
27
|
+
});
|
|
28
|
+
clearTimeout(timeoutId);
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
logger.warn('Failed to fetch MCP config', {
|
|
31
|
+
status: response.status,
|
|
32
|
+
statusText: response.statusText,
|
|
33
|
+
});
|
|
34
|
+
return this.getCachedOrNull();
|
|
35
|
+
}
|
|
36
|
+
const data = (await response.json());
|
|
37
|
+
// Validate schema version
|
|
38
|
+
if (!this.isSchemaVersionCompatible(data.schema_version)) {
|
|
39
|
+
logger.warn('MCP config schema version mismatch', {
|
|
40
|
+
expected: SUPPORTED_SCHEMA_VERSION,
|
|
41
|
+
received: data.schema_version,
|
|
42
|
+
});
|
|
43
|
+
return this.getCachedOrNull();
|
|
44
|
+
}
|
|
45
|
+
// Update cache
|
|
46
|
+
this.cache = {
|
|
47
|
+
data,
|
|
48
|
+
fetchedAt: Date.now(),
|
|
49
|
+
};
|
|
50
|
+
logger.info('Fetched MCP config from backend', {
|
|
51
|
+
schemaVersion: data.schema_version,
|
|
52
|
+
toolCount: data.tools.length,
|
|
53
|
+
promptCount: data.prompts.length,
|
|
54
|
+
});
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
if (error.name === 'AbortError') {
|
|
60
|
+
logger.warn('MCP config fetch timed out');
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
logger.warn('Failed to fetch MCP config', {
|
|
64
|
+
error: error.message,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return this.getCachedOrNull();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if the schema version is compatible.
|
|
73
|
+
* For now, we only support exact match.
|
|
74
|
+
* Later can implement semantic version comparison.
|
|
75
|
+
*/
|
|
76
|
+
isSchemaVersionCompatible(version) {
|
|
77
|
+
// Extract major version for compatibility check
|
|
78
|
+
const [major] = version.split('.');
|
|
79
|
+
const [supportedMajor] = SUPPORTED_SCHEMA_VERSION.split('.');
|
|
80
|
+
return major === supportedMajor;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Return cached value if available, otherwise null.
|
|
84
|
+
*/
|
|
85
|
+
getCachedOrNull() {
|
|
86
|
+
if (this.cache) {
|
|
87
|
+
return this.cache.data;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Invalidate the cache, forcing a fresh fetch on next request.
|
|
93
|
+
*/
|
|
94
|
+
invalidateCache() {
|
|
95
|
+
this.cache = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Export singleton instance
|
|
99
|
+
export const configService = new ConfigService();
|
|
100
|
+
//# sourceMappingURL=config-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.js","sourceRoot":"","sources":["../../src/services/config-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../../src/testing/mock-server.ts"],"names":[],"mappings":"AAmBA,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,MAAM,CAAe;IAE7B,IAAI,GAAG,IAAI,MAAM,CAEhB;;IAMD,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../../src/testing/mock-server.ts"],"names":[],"mappings":"AAmBA,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,MAAM,CAAe;IAE7B,IAAI,GAAG,IAAI,MAAM,CAEhB;;IAMD,OAAO,CAAC,WAAW;IAmDnB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,UAAU;IAkBZ,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,OAAO,CAAC,aAAa;CAmCtB"}
|
|
@@ -11,11 +11,19 @@ export class MockServer {
|
|
|
11
11
|
this.setupRoutes();
|
|
12
12
|
}
|
|
13
13
|
setupRoutes() {
|
|
14
|
-
//
|
|
15
|
-
this.addRoute('
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
14
|
+
// GET /solutions/search - matches client's findSolution API
|
|
15
|
+
this.addRoute('GET', '/solutions/search', (req) => {
|
|
16
|
+
const url = new URL(req.url ?? '/', `http://localhost:${this.port}`);
|
|
17
|
+
const query = url.searchParams.get('query') ?? '';
|
|
18
|
+
const results = mockFindResults.filter((r) => r.query_title.toLowerCase().includes(query.toLowerCase()));
|
|
19
|
+
// Map solution_id to id to match API response format
|
|
20
|
+
const mappedResults = (results.length > 0 ? results : mockFindResults).map((r) => ({
|
|
21
|
+
id: r.solution_id,
|
|
22
|
+
query_title: r.query_title,
|
|
23
|
+
solution_body: r.solution_body,
|
|
24
|
+
human_verification_required: r.human_verification_required,
|
|
25
|
+
}));
|
|
26
|
+
return { status: 200, data: mappedResults };
|
|
19
27
|
});
|
|
20
28
|
// POST /solutions/:id/unlock
|
|
21
29
|
this.addRoute('POST', '/solutions/:id/unlock', (_req, _body, params) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-server.js","sourceRoot":"","sources":["../../src/testing/mock-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAkBpF,MAAM,OAAO,UAAU;IACb,MAAM,GAAuB,IAAI,CAAC;IAClC,IAAI,GAAW,CAAC,CAAC;IACjB,MAAM,GAAY,EAAE,CAAC;IAE7B,IAAI,GAAG;QACL,OAAO,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAED;QACE,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAEO,WAAW;QACjB,
|
|
1
|
+
{"version":3,"file":"mock-server.js","sourceRoot":"","sources":["../../src/testing/mock-server.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -9,5 +9,11 @@ export interface ToolDefinition {
|
|
|
9
9
|
}>;
|
|
10
10
|
}>;
|
|
11
11
|
}
|
|
12
|
+
export declare const FALLBACK_TOOLS: ToolDefinition[];
|
|
13
|
+
/**
|
|
14
|
+
* Get tools with definitions from the backend API.
|
|
15
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getTools(): Promise<ToolDefinition[]>;
|
|
12
18
|
export declare const tools: ToolDefinition[];
|
|
13
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAUnD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,mBAAmB,KACxB,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAClE;AAkBD,eAAO,MAAM,cAAc,EAAE,cAAc,EAM1C,CAAC;AAiBF;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAyB1D;AAID,eAAO,MAAM,KAAK,EAAE,cAAc,EAAmB,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,13 +1,65 @@
|
|
|
1
|
+
import { configService } from '../services/config-service.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
1
3
|
import { findSolution } from './find-solution.js';
|
|
2
4
|
import { unlockSolution } from './unlock-solution.js';
|
|
3
5
|
import { publishSolution } from './publish-solution.js';
|
|
4
6
|
import { submitVerification } from './submit-verification.js';
|
|
5
7
|
import { submitFeedback } from './submit-feedback.js';
|
|
6
|
-
|
|
8
|
+
// Map of tool handlers by name
|
|
9
|
+
const toolHandlers = {
|
|
10
|
+
find_solution: findSolution.handler,
|
|
11
|
+
unlock_solution: unlockSolution.handler,
|
|
12
|
+
publish_solution: publishSolution.handler,
|
|
13
|
+
submit_verification: submitVerification.handler,
|
|
14
|
+
submit_feedback: submitFeedback.handler,
|
|
15
|
+
};
|
|
16
|
+
// Fallback tools used when backend is unavailable
|
|
17
|
+
export const FALLBACK_TOOLS = [
|
|
7
18
|
findSolution,
|
|
8
19
|
unlockSolution,
|
|
9
20
|
publishSolution,
|
|
10
21
|
submitVerification,
|
|
11
22
|
submitFeedback,
|
|
12
23
|
];
|
|
24
|
+
/**
|
|
25
|
+
* Convert a remote tool definition to a local Tool format
|
|
26
|
+
*/
|
|
27
|
+
function remoteToLocalTool(remote) {
|
|
28
|
+
return {
|
|
29
|
+
name: remote.name,
|
|
30
|
+
description: remote.description,
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: remote.inputSchema.type,
|
|
33
|
+
properties: remote.inputSchema.properties,
|
|
34
|
+
required: remote.inputSchema.required,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get tools with definitions from the backend API.
|
|
40
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
41
|
+
*/
|
|
42
|
+
export async function getTools() {
|
|
43
|
+
const remoteConfig = await configService.fetchConfig();
|
|
44
|
+
if (!remoteConfig) {
|
|
45
|
+
logger.info('Using fallback tool definitions');
|
|
46
|
+
return FALLBACK_TOOLS;
|
|
47
|
+
}
|
|
48
|
+
const tools = [];
|
|
49
|
+
for (const remoteTool of remoteConfig.tools) {
|
|
50
|
+
const handler = toolHandlers[remoteTool.name];
|
|
51
|
+
if (!handler) {
|
|
52
|
+
// Skip tools without handlers (allows backend to prepare for future tools)
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
tools.push({
|
|
56
|
+
definition: remoteToLocalTool(remoteTool),
|
|
57
|
+
handler,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return tools;
|
|
61
|
+
}
|
|
62
|
+
// Keep backward compatibility - export tools array for existing code
|
|
63
|
+
// Note: This is the fallback, prefer using getTools() for dynamic loading
|
|
64
|
+
export const tools = FALLBACK_TOOLS;
|
|
13
65
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAUtD,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAUtD,+BAA+B;AAC/B,MAAM,YAAY,GAMd;IACF,aAAa,EAAE,YAAY,CAAC,OAAO;IACnC,eAAe,EAAE,cAAc,CAAC,OAAO;IACvC,gBAAgB,EAAE,eAAe,CAAC,OAAO;IACzC,mBAAmB,EAAE,kBAAkB,CAAC,OAAO;IAC/C,eAAe,EAAE,cAAc,CAAC,OAAO;CACxC,CAAC;AAEF,kDAAkD;AAClD,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,YAAY;IACZ,cAAc;IACd,eAAe;IACf,kBAAkB;IAClB,cAAc;CACf,CAAC;AAEF;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAA4B;IACrD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,WAAW,EAAE;YACX,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAgB;YACzC,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU;YACzC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ;SACtC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC;IAEvD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,MAAM,KAAK,GAAqB,EAAE,CAAC;IAEnC,KAAK,MAAM,UAAU,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,2EAA2E;YAC3E,SAAS;QACX,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,UAAU,EAAE,iBAAiB,CAAC,UAAU,CAAC;YACzC,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qEAAqE;AACrE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,KAAK,GAAqB,cAAc,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -36,4 +36,42 @@ export type ApiResponse<T> = {
|
|
|
36
36
|
success: false;
|
|
37
37
|
error: string;
|
|
38
38
|
};
|
|
39
|
+
export interface RemoteInputProperty {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
}
|
|
43
|
+
export interface RemoteInputSchema {
|
|
44
|
+
type: string;
|
|
45
|
+
properties: Record<string, RemoteInputProperty>;
|
|
46
|
+
required: string[];
|
|
47
|
+
}
|
|
48
|
+
export interface RemoteToolDefinition {
|
|
49
|
+
name: string;
|
|
50
|
+
description: string;
|
|
51
|
+
inputSchema: RemoteInputSchema;
|
|
52
|
+
}
|
|
53
|
+
export interface RemotePromptArgument {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
required: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface RemotePromptMessageContent {
|
|
59
|
+
type: string;
|
|
60
|
+
text: string;
|
|
61
|
+
}
|
|
62
|
+
export interface RemotePromptMessage {
|
|
63
|
+
role: string;
|
|
64
|
+
content: RemotePromptMessageContent;
|
|
65
|
+
}
|
|
66
|
+
export interface RemotePromptDefinition {
|
|
67
|
+
name: string;
|
|
68
|
+
description: string;
|
|
69
|
+
arguments: RemotePromptArgument[];
|
|
70
|
+
messages: RemotePromptMessage[];
|
|
71
|
+
}
|
|
72
|
+
export interface McpConfigResponse {
|
|
73
|
+
schema_version: string;
|
|
74
|
+
tools: RemoteToolDefinition[];
|
|
75
|
+
prompts: RemotePromptDefinition[];
|
|
76
|
+
}
|
|
39
77
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAItC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAChD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,iBAAiB,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,0BAA0B,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -85,7 +85,23 @@ export class CacheOverflowClient {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
async findSolution(query: string): Promise<ApiResponse<FindSolutionResult[]>> {
|
|
88
|
-
|
|
88
|
+
const result = await this.request<Array<{ id: string; query_title: string; solution_body?: string; human_verification_required: boolean }>>(
|
|
89
|
+
'GET',
|
|
90
|
+
`/solutions/search?query=${encodeURIComponent(query)}`
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Map API response (uses 'id') to our interface (expects 'solution_id')
|
|
94
|
+
if (result.success) {
|
|
95
|
+
const mappedData = result.data.map(solution => ({
|
|
96
|
+
solution_id: solution.id,
|
|
97
|
+
query_title: solution.query_title,
|
|
98
|
+
solution_body: solution.solution_body,
|
|
99
|
+
human_verification_required: solution.human_verification_required,
|
|
100
|
+
}));
|
|
101
|
+
return { success: true, data: mappedData };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return result as ApiResponse<FindSolutionResult[]>;
|
|
89
105
|
}
|
|
90
106
|
|
|
91
107
|
async unlockSolution(solutionId: string): Promise<ApiResponse<Solution>> {
|
package/src/prompts/index.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Prompt, TextContent } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { configService } from '../services/config-service.js';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import type { RemotePromptDefinition } from '../types.js';
|
|
2
5
|
|
|
3
6
|
export interface PromptDefinition {
|
|
4
7
|
definition: Prompt;
|
|
@@ -165,4 +168,67 @@ Then call \`publish_solution\` to share it with other agents!
|
|
|
165
168
|
}),
|
|
166
169
|
};
|
|
167
170
|
|
|
168
|
-
|
|
171
|
+
// Fallback prompts used when backend is unavailable
|
|
172
|
+
export const FALLBACK_PROMPTS: PromptDefinition[] = [
|
|
173
|
+
publishGuidancePrompt,
|
|
174
|
+
workflowGuidancePrompt,
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Convert a remote prompt definition to a local Prompt format
|
|
179
|
+
*/
|
|
180
|
+
function remoteToLocalPrompt(remote: RemotePromptDefinition): Prompt {
|
|
181
|
+
return {
|
|
182
|
+
name: remote.name,
|
|
183
|
+
description: remote.description,
|
|
184
|
+
arguments: remote.arguments.map((arg) => ({
|
|
185
|
+
name: arg.name,
|
|
186
|
+
description: arg.description,
|
|
187
|
+
required: arg.required,
|
|
188
|
+
})),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Create a handler for a remote prompt definition.
|
|
194
|
+
* The handler returns the pre-defined messages from the remote config.
|
|
195
|
+
*/
|
|
196
|
+
function createRemotePromptHandler(
|
|
197
|
+
remote: RemotePromptDefinition
|
|
198
|
+
): PromptDefinition['handler'] {
|
|
199
|
+
return async () => ({
|
|
200
|
+
messages: remote.messages.map((msg) => ({
|
|
201
|
+
role: msg.role as 'user' | 'assistant',
|
|
202
|
+
content: {
|
|
203
|
+
type: msg.content.type as 'text',
|
|
204
|
+
text: msg.content.text,
|
|
205
|
+
},
|
|
206
|
+
})),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get prompts with definitions from the backend API.
|
|
212
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
213
|
+
*/
|
|
214
|
+
export async function getPrompts(): Promise<PromptDefinition[]> {
|
|
215
|
+
const remoteConfig = await configService.fetchConfig();
|
|
216
|
+
|
|
217
|
+
if (!remoteConfig) {
|
|
218
|
+
logger.info('Using fallback prompt definitions');
|
|
219
|
+
return FALLBACK_PROMPTS;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const prompts: PromptDefinition[] = remoteConfig.prompts.map(
|
|
223
|
+
(remotePrompt) => ({
|
|
224
|
+
definition: remoteToLocalPrompt(remotePrompt),
|
|
225
|
+
handler: createRemotePromptHandler(remotePrompt),
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
return prompts;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Keep backward compatibility - export prompts array for existing code
|
|
233
|
+
// Note: This is the fallback, prefer using getPrompts() for dynamic loading
|
|
234
|
+
export const prompts: PromptDefinition[] = FALLBACK_PROMPTS;
|
package/src/server.ts
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
GetPromptRequestSchema,
|
|
8
8
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import { CacheOverflowClient } from './client.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { getTools } from './tools/index.js';
|
|
11
|
+
import { getPrompts } from './prompts/index.js';
|
|
12
12
|
import { logger } from './logger.js';
|
|
13
13
|
|
|
14
14
|
export class CacheOverflowServer {
|
|
@@ -35,17 +35,21 @@ export class CacheOverflowServer {
|
|
|
35
35
|
|
|
36
36
|
private setupHandlers(): void {
|
|
37
37
|
// Tool handlers
|
|
38
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
39
|
+
const tools = await getTools();
|
|
40
|
+
return {
|
|
41
|
+
tools: tools.map((t) => t.definition),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
41
44
|
|
|
42
45
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
46
|
+
const tools = await getTools();
|
|
43
47
|
const tool = tools.find((t) => t.definition.name === request.params.name);
|
|
44
48
|
if (!tool) {
|
|
45
49
|
const error = new Error(`Unknown tool: ${request.params.name}`);
|
|
46
50
|
logger.error('Unknown tool requested', error, {
|
|
47
51
|
toolName: request.params.name,
|
|
48
|
-
availableTools: tools.map(t => t.definition.name),
|
|
52
|
+
availableTools: tools.map((t) => t.definition.name),
|
|
49
53
|
});
|
|
50
54
|
throw error;
|
|
51
55
|
}
|
|
@@ -58,26 +62,36 @@ export class CacheOverflowServer {
|
|
|
58
62
|
});
|
|
59
63
|
return await tool.handler(request.params.arguments ?? {}, this.client);
|
|
60
64
|
} catch (error) {
|
|
61
|
-
logger.error(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
logger.error(
|
|
66
|
+
`Tool execution failed: ${request.params.name}`,
|
|
67
|
+
error as Error,
|
|
68
|
+
{
|
|
69
|
+
toolName: request.params.name,
|
|
70
|
+
errorType: 'TOOL_EXECUTION_FAILURE',
|
|
71
|
+
}
|
|
72
|
+
);
|
|
65
73
|
throw error;
|
|
66
74
|
}
|
|
67
75
|
});
|
|
68
76
|
|
|
69
77
|
// Prompt handlers
|
|
70
|
-
this.server.setRequestHandler(ListPromptsRequestSchema, async () =>
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
79
|
+
const prompts = await getPrompts();
|
|
80
|
+
return {
|
|
81
|
+
prompts: prompts.map((p) => p.definition),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
73
84
|
|
|
74
85
|
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
75
|
-
const
|
|
86
|
+
const prompts = await getPrompts();
|
|
87
|
+
const prompt = prompts.find(
|
|
88
|
+
(p) => p.definition.name === request.params.name
|
|
89
|
+
);
|
|
76
90
|
if (!prompt) {
|
|
77
91
|
const error = new Error(`Unknown prompt: ${request.params.name}`);
|
|
78
92
|
logger.error('Unknown prompt requested', error, {
|
|
79
93
|
promptName: request.params.name,
|
|
80
|
-
availablePrompts: prompts.map(p => p.definition.name),
|
|
94
|
+
availablePrompts: prompts.map((p) => p.definition.name),
|
|
81
95
|
});
|
|
82
96
|
throw error;
|
|
83
97
|
}
|
|
@@ -85,10 +99,14 @@ export class CacheOverflowServer {
|
|
|
85
99
|
try {
|
|
86
100
|
return await prompt.handler(request.params.arguments ?? {});
|
|
87
101
|
} catch (error) {
|
|
88
|
-
logger.error(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
logger.error(
|
|
103
|
+
`Prompt execution failed: ${request.params.name}`,
|
|
104
|
+
error as Error,
|
|
105
|
+
{
|
|
106
|
+
promptName: request.params.name,
|
|
107
|
+
errorType: 'PROMPT_EXECUTION_FAILURE',
|
|
108
|
+
}
|
|
109
|
+
);
|
|
92
110
|
throw error;
|
|
93
111
|
}
|
|
94
112
|
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import type { McpConfigResponse } from '../types.js';
|
|
4
|
+
|
|
5
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
6
|
+
const FETCH_TIMEOUT_MS = 5000; // 5 seconds
|
|
7
|
+
const SUPPORTED_SCHEMA_VERSION = '1.0.0';
|
|
8
|
+
|
|
9
|
+
interface CachedConfig {
|
|
10
|
+
data: McpConfigResponse;
|
|
11
|
+
fetchedAt: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class ConfigService {
|
|
15
|
+
private cache: CachedConfig | null = null;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Fetch MCP configuration from the backend API.
|
|
19
|
+
* Returns cached value if available and not expired.
|
|
20
|
+
* Falls back to null on failure (caller should use fallback).
|
|
21
|
+
*/
|
|
22
|
+
async fetchConfig(): Promise<McpConfigResponse | null> {
|
|
23
|
+
// Return cached value if still valid
|
|
24
|
+
if (this.cache && Date.now() - this.cache.fetchedAt < CACHE_TTL_MS) {
|
|
25
|
+
return this.cache.data;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
31
|
+
|
|
32
|
+
const response = await fetch(`${config.api.url}/mcp/config`, {
|
|
33
|
+
method: 'GET',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
},
|
|
37
|
+
signal: controller.signal,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
logger.warn('Failed to fetch MCP config', {
|
|
44
|
+
status: response.status,
|
|
45
|
+
statusText: response.statusText,
|
|
46
|
+
});
|
|
47
|
+
return this.getCachedOrNull();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const data = (await response.json()) as McpConfigResponse;
|
|
51
|
+
|
|
52
|
+
// Validate schema version
|
|
53
|
+
if (!this.isSchemaVersionCompatible(data.schema_version)) {
|
|
54
|
+
logger.warn('MCP config schema version mismatch', {
|
|
55
|
+
expected: SUPPORTED_SCHEMA_VERSION,
|
|
56
|
+
received: data.schema_version,
|
|
57
|
+
});
|
|
58
|
+
return this.getCachedOrNull();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Update cache
|
|
62
|
+
this.cache = {
|
|
63
|
+
data,
|
|
64
|
+
fetchedAt: Date.now(),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
logger.info('Fetched MCP config from backend', {
|
|
68
|
+
schemaVersion: data.schema_version,
|
|
69
|
+
toolCount: data.tools.length,
|
|
70
|
+
promptCount: data.prompts.length,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return data;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error instanceof Error) {
|
|
76
|
+
if (error.name === 'AbortError') {
|
|
77
|
+
logger.warn('MCP config fetch timed out');
|
|
78
|
+
} else {
|
|
79
|
+
logger.warn('Failed to fetch MCP config', {
|
|
80
|
+
error: error.message,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return this.getCachedOrNull();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if the schema version is compatible.
|
|
90
|
+
* For now, we only support exact match.
|
|
91
|
+
* Later can implement semantic version comparison.
|
|
92
|
+
*/
|
|
93
|
+
private isSchemaVersionCompatible(version: string): boolean {
|
|
94
|
+
// Extract major version for compatibility check
|
|
95
|
+
const [major] = version.split('.');
|
|
96
|
+
const [supportedMajor] = SUPPORTED_SCHEMA_VERSION.split('.');
|
|
97
|
+
return major === supportedMajor;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Return cached value if available, otherwise null.
|
|
102
|
+
*/
|
|
103
|
+
private getCachedOrNull(): McpConfigResponse | null {
|
|
104
|
+
if (this.cache) {
|
|
105
|
+
return this.cache.data;
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Invalidate the cache, forcing a fresh fetch on next request.
|
|
112
|
+
*/
|
|
113
|
+
invalidateCache(): void {
|
|
114
|
+
this.cache = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Export singleton instance
|
|
119
|
+
export const configService = new ConfigService();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as http from 'node:http';
|
|
2
2
|
import { mockSolutions, mockFindResults, createMockSolution } from './mock-data.js';
|
|
3
|
-
import type { Solution
|
|
3
|
+
import type { Solution } from '../types.js';
|
|
4
4
|
|
|
5
5
|
interface RouteHandler {
|
|
6
6
|
(
|
|
@@ -31,13 +31,21 @@ export class MockServer {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
private setupRoutes(): void {
|
|
34
|
-
//
|
|
35
|
-
this.addRoute('
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
34
|
+
// GET /solutions/search - matches client's findSolution API
|
|
35
|
+
this.addRoute('GET', '/solutions/search', (req) => {
|
|
36
|
+
const url = new URL(req.url ?? '/', `http://localhost:${this.port}`);
|
|
37
|
+
const query = url.searchParams.get('query') ?? '';
|
|
38
|
+
const results = mockFindResults.filter((r) =>
|
|
39
|
+
r.query_title.toLowerCase().includes(query.toLowerCase())
|
|
39
40
|
);
|
|
40
|
-
|
|
41
|
+
// Map solution_id to id to match API response format
|
|
42
|
+
const mappedResults = (results.length > 0 ? results : mockFindResults).map((r) => ({
|
|
43
|
+
id: r.solution_id,
|
|
44
|
+
query_title: r.query_title,
|
|
45
|
+
solution_body: r.solution_body,
|
|
46
|
+
human_verification_required: r.human_verification_required,
|
|
47
|
+
}));
|
|
48
|
+
return { status: 200, data: mappedResults };
|
|
41
49
|
});
|
|
42
50
|
|
|
43
51
|
// POST /solutions/:id/unlock
|
package/src/tools/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import { CacheOverflowClient } from '../client.js';
|
|
3
|
+
import { configService } from '../services/config-service.js';
|
|
4
|
+
import { logger } from '../logger.js';
|
|
5
|
+
import type { RemoteToolDefinition } from '../types.js';
|
|
3
6
|
import { findSolution } from './find-solution.js';
|
|
4
7
|
import { unlockSolution } from './unlock-solution.js';
|
|
5
8
|
import { publishSolution } from './publish-solution.js';
|
|
@@ -14,10 +17,76 @@ export interface ToolDefinition {
|
|
|
14
17
|
) => Promise<{ content: Array<{ type: string; text: string }> }>;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
// Map of tool handlers by name
|
|
21
|
+
const toolHandlers: Record<
|
|
22
|
+
string,
|
|
23
|
+
(
|
|
24
|
+
args: Record<string, unknown>,
|
|
25
|
+
client: CacheOverflowClient
|
|
26
|
+
) => Promise<{ content: Array<{ type: string; text: string }> }>
|
|
27
|
+
> = {
|
|
28
|
+
find_solution: findSolution.handler,
|
|
29
|
+
unlock_solution: unlockSolution.handler,
|
|
30
|
+
publish_solution: publishSolution.handler,
|
|
31
|
+
submit_verification: submitVerification.handler,
|
|
32
|
+
submit_feedback: submitFeedback.handler,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Fallback tools used when backend is unavailable
|
|
36
|
+
export const FALLBACK_TOOLS: ToolDefinition[] = [
|
|
18
37
|
findSolution,
|
|
19
38
|
unlockSolution,
|
|
20
39
|
publishSolution,
|
|
21
40
|
submitVerification,
|
|
22
41
|
submitFeedback,
|
|
23
42
|
];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Convert a remote tool definition to a local Tool format
|
|
46
|
+
*/
|
|
47
|
+
function remoteToLocalTool(remote: RemoteToolDefinition): Tool {
|
|
48
|
+
return {
|
|
49
|
+
name: remote.name,
|
|
50
|
+
description: remote.description,
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: remote.inputSchema.type as 'object',
|
|
53
|
+
properties: remote.inputSchema.properties,
|
|
54
|
+
required: remote.inputSchema.required,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get tools with definitions from the backend API.
|
|
61
|
+
* Falls back to hardcoded definitions if the backend is unavailable.
|
|
62
|
+
*/
|
|
63
|
+
export async function getTools(): Promise<ToolDefinition[]> {
|
|
64
|
+
const remoteConfig = await configService.fetchConfig();
|
|
65
|
+
|
|
66
|
+
if (!remoteConfig) {
|
|
67
|
+
logger.info('Using fallback tool definitions');
|
|
68
|
+
return FALLBACK_TOOLS;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const tools: ToolDefinition[] = [];
|
|
72
|
+
|
|
73
|
+
for (const remoteTool of remoteConfig.tools) {
|
|
74
|
+
const handler = toolHandlers[remoteTool.name];
|
|
75
|
+
|
|
76
|
+
if (!handler) {
|
|
77
|
+
// Skip tools without handlers (allows backend to prepare for future tools)
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
tools.push({
|
|
82
|
+
definition: remoteToLocalTool(remoteTool),
|
|
83
|
+
handler,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return tools;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Keep backward compatibility - export tools array for existing code
|
|
91
|
+
// Note: This is the fallback, prefer using getTools() for dynamic loading
|
|
92
|
+
export const tools: ToolDefinition[] = FALLBACK_TOOLS;
|
package/src/types.ts
CHANGED
|
@@ -37,3 +37,51 @@ export interface User {
|
|
|
37
37
|
export type ApiResponse<T> =
|
|
38
38
|
| { success: true; data: T }
|
|
39
39
|
| { success: false; error: string };
|
|
40
|
+
|
|
41
|
+
// Remote MCP configuration types (fetched from backend)
|
|
42
|
+
|
|
43
|
+
export interface RemoteInputProperty {
|
|
44
|
+
type: string;
|
|
45
|
+
description: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface RemoteInputSchema {
|
|
49
|
+
type: string;
|
|
50
|
+
properties: Record<string, RemoteInputProperty>;
|
|
51
|
+
required: string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface RemoteToolDefinition {
|
|
55
|
+
name: string;
|
|
56
|
+
description: string;
|
|
57
|
+
inputSchema: RemoteInputSchema;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface RemotePromptArgument {
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
required: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface RemotePromptMessageContent {
|
|
67
|
+
type: string;
|
|
68
|
+
text: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface RemotePromptMessage {
|
|
72
|
+
role: string;
|
|
73
|
+
content: RemotePromptMessageContent;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface RemotePromptDefinition {
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
arguments: RemotePromptArgument[];
|
|
80
|
+
messages: RemotePromptMessage[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface McpConfigResponse {
|
|
84
|
+
schema_version: string;
|
|
85
|
+
tools: RemoteToolDefinition[];
|
|
86
|
+
prompts: RemotePromptDefinition[];
|
|
87
|
+
}
|