cache-overflow-mcp 0.3.6 → 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.
@@ -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;AAEzE,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;AAEF,eAAO,MAAM,OAAO,EAAE,gBAAgB,EAAoD,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"}
@@ -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
- export const prompts = [publishGuidancePrompt, workflowGuidancePrompt];
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":"AAYA,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,UAAU,EAAE;QACV,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,qEAAqE;QACvE,SAAS,EAAE,EAAE;KACd;IACD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACpB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,qDAAqD;iBAC5D;aACF;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAkEoD;iBAC3D;aACF;SACF;KACF,CAAC;CACH,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,UAAU,EAAE;QACV,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EACT,2GAA2G;QAC7G,SAAS,EAAE,EAAE;KACd;IACD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACpB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,wCAAwC;iBAC/C;aACF;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CAmC4B;iBACnC;aACF;SACF;KACF,CAAC;CACH,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAuB,CAAC,qBAAqB,EAAE,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
@@ -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;IA6Df,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
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 { tools } from './tools/index.js';
6
- import { prompts } from './prompts/index.js';
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
- tools: tools.map((t) => t.definition),
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
- prompts: prompts.map((p) => p.definition),
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -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;IA2CnB,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"}
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
- // POST /solutions/find
15
- this.addRoute('POST', '/solutions/find', (_req, body) => {
16
- const { query } = body;
17
- const results = mockFindResults.filter((r) => r.query_title.toLowerCase().includes((query ?? '').toLowerCase()));
18
- return { status: 200, data: results.length > 0 ? results : mockFindResults };
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":"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"}
1
+ {"version":3,"file":"mock-server.js","sourceRoot":"","sources":["../../src/testing/mock-server.ts"],"names":[],"mappings":"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"}
@@ -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;AAOnD,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;AAED,eAAO,MAAM,KAAK,EAAE,cAAc,EAMjC,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"}
@@ -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
- export const tools = [
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
@@ -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,KAAK,GAAqB;IACrC,YAAY;IACZ,cAAc;IACd,eAAe;IACf,kBAAkB;IAClB,cAAc;CACf,CAAC"}
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
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cache-overflow-mcp",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "description": "MCP server for cache.overflow - AI agents sharing knowledge with AI agents",
6
6
  "main": "dist/index.js",
@@ -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
- export const prompts: PromptDefinition[] = [publishGuidancePrompt, workflowGuidancePrompt];
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 { tools } from './tools/index.js';
11
- import { prompts } from './prompts/index.js';
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
- tools: tools.map((t) => t.definition),
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(`Tool execution failed: ${request.params.name}`, error as Error, {
62
- toolName: request.params.name,
63
- errorType: 'TOOL_EXECUTION_FAILURE',
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
- prompts: prompts.map((p) => p.definition),
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 prompt = prompts.find((p) => p.definition.name === request.params.name);
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(`Prompt execution failed: ${request.params.name}`, error as Error, {
89
- promptName: request.params.name,
90
- errorType: 'PROMPT_EXECUTION_FAILURE',
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, FindSolutionResult } from '../types.js';
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
- // POST /solutions/find
35
- this.addRoute('POST', '/solutions/find', (_req, body) => {
36
- const { query } = body as { query: string };
37
- const results: FindSolutionResult[] = mockFindResults.filter((r) =>
38
- r.query_title.toLowerCase().includes((query ?? '').toLowerCase())
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
- return { status: 200, data: results.length > 0 ? results : mockFindResults };
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
@@ -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
- export const tools: ToolDefinition[] = [
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
+ }