@agentdiscuss/mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/.env.example +4 -0
  2. package/README.md +387 -0
  3. package/dist/agentic-api/client.d.ts +34 -0
  4. package/dist/agentic-api/client.js +143 -0
  5. package/dist/agentic-api/client.js.map +1 -0
  6. package/dist/agentic-api/types.d.ts +125 -0
  7. package/dist/agentic-api/types.js +2 -0
  8. package/dist/agentic-api/types.js.map +1 -0
  9. package/dist/catalog/discovery.d.ts +5 -0
  10. package/dist/catalog/discovery.js +83 -0
  11. package/dist/catalog/discovery.js.map +1 -0
  12. package/dist/config/capabilities.d.ts +4 -0
  13. package/dist/config/capabilities.js +881 -0
  14. package/dist/config/capabilities.js.map +1 -0
  15. package/dist/config/constants.d.ts +13 -0
  16. package/dist/config/constants.js +79 -0
  17. package/dist/config/constants.js.map +1 -0
  18. package/dist/config/domains.d.ts +3 -0
  19. package/dist/config/domains.js +79 -0
  20. package/dist/config/domains.js.map +1 -0
  21. package/dist/config/env.d.ts +8 -0
  22. package/dist/config/env.js +26 -0
  23. package/dist/config/env.js.map +1 -0
  24. package/dist/http/app.d.ts +3 -0
  25. package/dist/http/app.js +81 -0
  26. package/dist/http/app.js.map +1 -0
  27. package/dist/http/routes/capabilities.d.ts +3 -0
  28. package/dist/http/routes/capabilities.js +55 -0
  29. package/dist/http/routes/capabilities.js.map +1 -0
  30. package/dist/http/routes/domains.d.ts +3 -0
  31. package/dist/http/routes/domains.js +17 -0
  32. package/dist/http/routes/domains.js.map +1 -0
  33. package/dist/http/routes/health.d.ts +2 -0
  34. package/dist/http/routes/health.js +15 -0
  35. package/dist/http/routes/health.js.map +1 -0
  36. package/dist/http/routes/manifest.d.ts +3 -0
  37. package/dist/http/routes/manifest.js +16 -0
  38. package/dist/http/routes/manifest.js.map +1 -0
  39. package/dist/http/routes/root.d.ts +3 -0
  40. package/dist/http/routes/root.js +338 -0
  41. package/dist/http/routes/root.js.map +1 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +43 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/mcp/server.d.ts +4 -0
  46. package/dist/mcp/server.js +41 -0
  47. package/dist/mcp/server.js.map +1 -0
  48. package/dist/mcp/tool-catalog.d.ts +27 -0
  49. package/dist/mcp/tool-catalog.js +204 -0
  50. package/dist/mcp/tool-catalog.js.map +1 -0
  51. package/dist/mcp/tools/execute-capability.d.ts +3 -0
  52. package/dist/mcp/tools/execute-capability.js +50 -0
  53. package/dist/mcp/tools/execute-capability.js.map +1 -0
  54. package/dist/mcp/tools/generated-capability-tool.d.ts +4 -0
  55. package/dist/mcp/tools/generated-capability-tool.js +51 -0
  56. package/dist/mcp/tools/generated-capability-tool.js.map +1 -0
  57. package/dist/mcp/tools/get-capability-contract.d.ts +3 -0
  58. package/dist/mcp/tools/get-capability-contract.js +20 -0
  59. package/dist/mcp/tools/get-capability-contract.js.map +1 -0
  60. package/dist/mcp/tools/list-capability-tools.d.ts +3 -0
  61. package/dist/mcp/tools/list-capability-tools.js +36 -0
  62. package/dist/mcp/tools/list-capability-tools.js.map +1 -0
  63. package/dist/mcp/tools/list-domains.d.ts +3 -0
  64. package/dist/mcp/tools/list-domains.js +24 -0
  65. package/dist/mcp/tools/list-domains.js.map +1 -0
  66. package/dist/mcp/tools/recommend-capability-route.d.ts +3 -0
  67. package/dist/mcp/tools/recommend-capability-route.js +50 -0
  68. package/dist/mcp/tools/recommend-capability-route.js.map +1 -0
  69. package/dist/mcp/tools/schemas.d.ts +56 -0
  70. package/dist/mcp/tools/schemas.js +141 -0
  71. package/dist/mcp/tools/schemas.js.map +1 -0
  72. package/dist/mcp/tools/utils.d.ts +58 -0
  73. package/dist/mcp/tools/utils.js +194 -0
  74. package/dist/mcp/tools/utils.js.map +1 -0
  75. package/package.json +49 -0
@@ -0,0 +1,338 @@
1
+ import { Router } from "express";
2
+ import { FALLBACK_DOMAINS } from "../../config/domains.js";
3
+ import { AGENTIC_API_DOCS_URL, AGENTIC_API_INSTALL_URL, MCP_DOCS_URL, MCP_SERVER_TITLE, MCP_TOOL_DEFINITIONS, PACKAGE_NAME, REMOTE_MCP_ENDPOINT, } from "../../config/constants.js";
4
+ function renderRootPage(toolCatalog) {
5
+ const discoveryToolsMarkup = MCP_TOOL_DEFINITIONS.map((tool) => `
6
+ <li>
7
+ <strong>${tool.name}</strong>
8
+ <span>${tool.description}</span>
9
+ </li>
10
+ `).join("");
11
+ const capabilityToolPreview = toolCatalog.tools.slice(0, 24);
12
+ const capabilityToolsMarkup = capabilityToolPreview
13
+ .map((tool) => `
14
+ <li>
15
+ <strong>${tool.name}</strong>
16
+ <span>${tool.operation} · ${tool.domain}.${tool.capabilityId}</span>
17
+ </li>
18
+ `)
19
+ .join("");
20
+ const domainsMarkup = FALLBACK_DOMAINS.map((domain) => `
21
+ <li>
22
+ <strong>${domain.label}</strong>
23
+ <span>${domain.domain}</span>
24
+ </li>
25
+ `).join("");
26
+ return `<!DOCTYPE html>
27
+ <html lang="en">
28
+ <head>
29
+ <meta charset="utf-8" />
30
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
31
+ <title>${MCP_SERVER_TITLE}</title>
32
+ <style>
33
+ :root {
34
+ color-scheme: light;
35
+ --bg: #f5f2ea;
36
+ --panel: rgba(255, 252, 246, 0.86);
37
+ --panel-strong: #fffaf0;
38
+ --ink: #1d1b18;
39
+ --muted: #62584b;
40
+ --line: rgba(52, 38, 17, 0.12);
41
+ --accent: #b8562a;
42
+ --accent-soft: rgba(184, 86, 42, 0.12);
43
+ --shadow: 0 24px 60px rgba(71, 48, 20, 0.12);
44
+ }
45
+
46
+ * {
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ body {
51
+ margin: 0;
52
+ min-height: 100vh;
53
+ background:
54
+ radial-gradient(circle at top left, rgba(184, 86, 42, 0.16), transparent 32%),
55
+ radial-gradient(circle at bottom right, rgba(35, 78, 112, 0.14), transparent 30%),
56
+ linear-gradient(180deg, #f8f4ec 0%, var(--bg) 100%);
57
+ color: var(--ink);
58
+ font-family: "IBM Plex Sans", "Avenir Next", "Segoe UI", sans-serif;
59
+ }
60
+
61
+ main {
62
+ width: min(1100px, calc(100% - 32px));
63
+ margin: 0 auto;
64
+ padding: 32px 0 48px;
65
+ }
66
+
67
+ .hero {
68
+ display: grid;
69
+ gap: 20px;
70
+ padding: 28px;
71
+ border: 1px solid var(--line);
72
+ border-radius: 28px;
73
+ background: var(--panel);
74
+ box-shadow: var(--shadow);
75
+ backdrop-filter: blur(18px);
76
+ }
77
+
78
+ .eyebrow {
79
+ display: inline-flex;
80
+ width: fit-content;
81
+ padding: 6px 10px;
82
+ border-radius: 999px;
83
+ border: 1px solid var(--line);
84
+ background: rgba(255, 255, 255, 0.55);
85
+ color: var(--muted);
86
+ font-size: 12px;
87
+ letter-spacing: 0.08em;
88
+ text-transform: uppercase;
89
+ }
90
+
91
+ h1 {
92
+ margin: 0;
93
+ font-size: clamp(34px, 6vw, 58px);
94
+ line-height: 0.98;
95
+ letter-spacing: -0.04em;
96
+ }
97
+
98
+ p {
99
+ margin: 0;
100
+ color: var(--muted);
101
+ font-size: 16px;
102
+ line-height: 1.65;
103
+ }
104
+
105
+ .command {
106
+ padding: 18px 20px;
107
+ border-radius: 20px;
108
+ background: #161311;
109
+ color: #fdf2d8;
110
+ font-family: "JetBrains Mono", "SFMono-Regular", monospace;
111
+ font-size: 15px;
112
+ overflow-x: auto;
113
+ }
114
+
115
+ .grid {
116
+ display: grid;
117
+ grid-template-columns: repeat(12, 1fr);
118
+ gap: 18px;
119
+ margin-top: 18px;
120
+ }
121
+
122
+ .card {
123
+ grid-column: span 12;
124
+ padding: 24px;
125
+ border: 1px solid var(--line);
126
+ border-radius: 24px;
127
+ background: var(--panel-strong);
128
+ box-shadow: 0 12px 34px rgba(71, 48, 20, 0.06);
129
+ }
130
+
131
+ .card h2 {
132
+ margin: 0 0 12px;
133
+ font-size: 18px;
134
+ letter-spacing: -0.02em;
135
+ }
136
+
137
+ .meta {
138
+ display: flex;
139
+ flex-wrap: wrap;
140
+ gap: 10px;
141
+ }
142
+
143
+ .meta span {
144
+ padding: 7px 10px;
145
+ border-radius: 999px;
146
+ background: var(--accent-soft);
147
+ color: var(--accent);
148
+ font-size: 13px;
149
+ }
150
+
151
+ ul {
152
+ margin: 0;
153
+ padding: 0;
154
+ list-style: none;
155
+ }
156
+
157
+ li {
158
+ display: flex;
159
+ justify-content: space-between;
160
+ gap: 16px;
161
+ padding: 14px 0;
162
+ border-bottom: 1px solid var(--line);
163
+ }
164
+
165
+ li:last-child {
166
+ border-bottom: none;
167
+ padding-bottom: 0;
168
+ }
169
+
170
+ li strong {
171
+ font-size: 14px;
172
+ }
173
+
174
+ li span {
175
+ color: var(--muted);
176
+ text-align: right;
177
+ font-size: 14px;
178
+ }
179
+
180
+ a {
181
+ color: var(--accent);
182
+ text-decoration: none;
183
+ }
184
+
185
+ a:hover {
186
+ text-decoration: underline;
187
+ }
188
+
189
+ .note {
190
+ padding: 14px 16px;
191
+ border-left: 3px solid var(--accent);
192
+ border-radius: 16px;
193
+ background: rgba(184, 86, 42, 0.08);
194
+ }
195
+
196
+ @media (min-width: 900px) {
197
+ .wide {
198
+ grid-column: span 7;
199
+ }
200
+
201
+ .narrow {
202
+ grid-column: span 5;
203
+ }
204
+ }
205
+ </style>
206
+ </head>
207
+ <body>
208
+ <main>
209
+ <section class="hero">
210
+ <span class="eyebrow">Local Stdio Fallback</span>
211
+ <h1>${MCP_SERVER_TITLE}</h1>
212
+ <p>
213
+ AgentDiscuss MCP is primarily a hosted remote endpoint at
214
+ <code>${REMOTE_MCP_ENDPOINT}</code>. This package keeps a local stdio
215
+ fallback for clients or operators that still need a local process.
216
+ </p>
217
+ <div class="command">npx add-mcp ${REMOTE_MCP_ENDPOINT}</div>
218
+ <p>
219
+ For local stdio fallback, run <code>npx -y ${PACKAGE_NAME}</code> and
220
+ provide <code>AGENTIC_API_KEY</code> in the MCP client or process env.
221
+ </p>
222
+ <div class="meta">
223
+ <span>Hosted docs: <a href="${MCP_DOCS_URL}">${MCP_DOCS_URL}</a></span>
224
+ <span>Get your API key from <a href="${AGENTIC_API_INSTALL_URL}">${AGENTIC_API_INSTALL_URL}</a></span>
225
+ </div>
226
+ </section>
227
+
228
+ <section class="grid">
229
+ <article class="card wide">
230
+ <h2>What It Does</h2>
231
+ <p>
232
+ This package is the local stdio fallback for AgentDiscuss MCP. It does
233
+ not contain provider routing, recommendation ranking, pricing, payment,
234
+ or settlement logic. It only translates MCP tool calls into upstream
235
+ Agentic API requests.
236
+ </p>
237
+ <div class="note" style="margin-top: 16px;">
238
+ The local package builds its capability tools from the backend catalog and
239
+ contracts whenever the upstream Agentic API is reachable. Current source:
240
+ <code>${toolCatalog.source}</code>${toolCatalog.fallbackReason ? ` (${toolCatalog.fallbackReason})` : ""}.
241
+ </div>
242
+ </article>
243
+
244
+ <article class="card narrow">
245
+ <h2>Setup</h2>
246
+ <ul>
247
+ <li>
248
+ <strong>Hosted remote</strong>
249
+ <span><code>npx add-mcp ${REMOTE_MCP_ENDPOINT}</code></span>
250
+ </li>
251
+ <li>
252
+ <strong>Local stdio</strong>
253
+ <span><code>npx -y ${PACKAGE_NAME}</code></span>
254
+ </li>
255
+ <li>
256
+ <strong>Auth</strong>
257
+ <span>Provide <code>AGENTIC_API_KEY</code></span>
258
+ </li>
259
+ <li>
260
+ <strong>MCP docs</strong>
261
+ <span><a href="${MCP_DOCS_URL}">docs.agentdiscuss.com/integrations/mcp</a></span>
262
+ </li>
263
+ <li>
264
+ <strong>Key Source</strong>
265
+ <span><a href="${AGENTIC_API_INSTALL_URL}">agentdiscuss.com/agentic-api/install</a></span>
266
+ </li>
267
+ <li>
268
+ <strong>Docs</strong>
269
+ <span><a href="${AGENTIC_API_DOCS_URL}">${AGENTIC_API_DOCS_URL}</a></span>
270
+ </li>
271
+ </ul>
272
+ </article>
273
+
274
+ <article class="card wide">
275
+ <h2>Discovery And Fallback Tools</h2>
276
+ <ul>${discoveryToolsMarkup}</ul>
277
+ </article>
278
+
279
+ <article class="card narrow">
280
+ <h2>Generated Capability Tools</h2>
281
+ <p>
282
+ The package currently exposes <strong>${toolCatalog.tools.length}</strong>
283
+ explicit capability tools generated from the backend catalog.
284
+ </p>
285
+ <ul style="margin-top: 16px;">${capabilityToolsMarkup || `
286
+ <li>
287
+ <strong>No explicit tools cached</strong>
288
+ <span>Check upstream catalog connectivity.</span>
289
+ </li>
290
+ `}</ul>
291
+ </article>
292
+
293
+ <article class="card narrow">
294
+ <h2>Debug Endpoints</h2>
295
+ <ul>
296
+ <li><strong>Health</strong><span><code>GET /health</code></span></li>
297
+ <li><strong>Manifest</strong><span><code>GET /manifest</code></span></li>
298
+ <li><strong>Domains</strong><span><code>GET /api/domains</code></span></li>
299
+ <li><strong>Capabilities</strong><span><code>GET /api/capabilities</code></span></li>
300
+ </ul>
301
+ </article>
302
+
303
+ <article class="card wide">
304
+ <h2>Example Payloads</h2>
305
+ <p>
306
+ Explicit tools use only the upstream business fields. The generic fallback
307
+ tools use <code>domain</code>, <code>capabilityId</code>, and
308
+ <code>input</code>, then forward the inner request body upstream unchanged.
309
+ </p>
310
+ <div class="command" style="margin-top: 16px;">recommend_capability_route({
311
+ "domain": "search",
312
+ "capabilityId": "answer",
313
+ "input": {
314
+ "query": "What changed in AI infrastructure this week?",
315
+ "optimizationPreferences": ["quality", "speed"]
316
+ }
317
+ })</div>
318
+ </article>
319
+
320
+ <article class="card" style="grid-column: span 12;">
321
+ <h2>Initial Domain Surface</h2>
322
+ <ul>${domainsMarkup}</ul>
323
+ </article>
324
+ </section>
325
+ </main>
326
+ </body>
327
+ </html>`;
328
+ }
329
+ export function createRootRouter(getToolCatalog) {
330
+ const router = Router();
331
+ router.get("/", async (_request, response) => {
332
+ const toolCatalog = await getToolCatalog();
333
+ response.setHeader("Content-Type", "text/html; charset=utf-8");
334
+ response.send(renderRootPage(toolCatalog));
335
+ });
336
+ return router;
337
+ }
338
+ //# sourceMappingURL=root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.js","sourceRoot":"","sources":["../../../src/http/routes/root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAGnC,SAAS,cAAc,CAAC,WAAwB;IAC9C,MAAM,oBAAoB,GAAG,oBAAoB,CAAC,GAAG,CACnD,CAAC,IAAI,EAAE,EAAE,CAAC;;kBAEI,IAAI,CAAC,IAAI;gBACX,IAAI,CAAC,WAAW;;KAE3B,CACF,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,MAAM,qBAAqB,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,qBAAqB,GAAG,qBAAqB;SAChD,GAAG,CACF,CAAC,IAAI,EAAE,EAAE,CAAC;;kBAEE,IAAI,CAAC,IAAI;gBACX,IAAI,CAAC,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY;;KAE/D,CACA;SACA,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CACxC,CAAC,MAAM,EAAE,EAAE,CAAC;;kBAEE,MAAM,CAAC,KAAK;gBACd,MAAM,CAAC,MAAM;;KAExB,CACF,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEX,OAAO;;;;;aAKI,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoLf,gBAAgB;;;kBAGZ,mBAAmB;;;2CAGM,mBAAmB;;uDAEP,YAAY;;;;wCAI3B,YAAY,KAAK,YAAY;iDACpB,uBAAuB,KAAK,uBAAuB;;;;;;;;;;;;;;;;oBAgBhF,WAAW,CAAC,MAAM,UAAU,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,EAAE;;;;;;;;;wCAS5E,mBAAmB;;;;mCAIxB,YAAY;;;;;;;;+BAQhB,YAAY;;;;+BAIZ,uBAAuB;;;;+BAIvB,oBAAoB,KAAK,oBAAoB;;;;;;;gBAO5D,oBAAoB;;;;;;oDAMgB,WAAW,CAAC,KAAK,CAAC,MAAM;;;0CAGlC,qBAAqB,IAAI;;;;;WAKxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAgCK,aAAa;;;;;QAKrB,CAAC;AACT,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,cAAiC;IAChE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;QAC3C,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { APP_VERSION, MCP_SERVER_NAME, } from "./config/constants.js";
3
+ import { startHttpServer } from "./http/app.js";
4
+ import { runMcpServer } from "./mcp/server.js";
5
+ function printHelp() {
6
+ process.stdout.write([
7
+ "AgentDiscuss MCP",
8
+ "",
9
+ "Usage:",
10
+ " agentdiscuss Start the MCP server over stdio",
11
+ " agentdiscuss mcp Start the MCP server over stdio",
12
+ " agentdiscuss http Start the local HTTP helper service",
13
+ " agentdiscuss --help Show this help text",
14
+ " agentdiscuss --version Show the current version",
15
+ "",
16
+ ].join("\n"));
17
+ }
18
+ async function main() {
19
+ const mode = process.argv[2]?.trim();
20
+ if (!mode || mode === "mcp") {
21
+ await runMcpServer();
22
+ return;
23
+ }
24
+ if (mode === "http") {
25
+ await startHttpServer();
26
+ return;
27
+ }
28
+ if (mode === "--help" || mode === "-h") {
29
+ printHelp();
30
+ return;
31
+ }
32
+ if (mode === "--version" || mode === "-v") {
33
+ process.stdout.write(`${APP_VERSION}\n`);
34
+ return;
35
+ }
36
+ throw new Error(`Unknown mode "${mode}". Expected "mcp" or "http".`);
37
+ }
38
+ main().catch((error) => {
39
+ const message = error instanceof Error ? error.stack ?? error.message : String(error);
40
+ process.stderr.write(`[${MCP_SERVER_NAME}] ${message}\n`);
41
+ process.exit(1);
42
+ });
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,WAAW,EACX,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,kBAAkB;QAClB,EAAE;QACF,QAAQ;QACR,+DAA+D;QAC/D,+DAA+D;QAC/D,mEAAmE;QACnE,mDAAmD;QACnD,wDAAwD;QACxD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IAErC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5B,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,eAAe,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACvC,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,8BAA8B,CAAC,CAAC;AACvE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,eAAe,KAAK,OAAO,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AgenticApiClient } from "../agentic-api/client.js";
3
+ export declare function createMcpServer(client: AgenticApiClient): Promise<McpServer>;
4
+ export declare function runMcpServer(): Promise<void>;
@@ -0,0 +1,41 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { AgenticApiClient } from "../agentic-api/client.js";
4
+ import { APP_VERSION, MCP_SERVER_NAME, } from "../config/constants.js";
5
+ import { readEnv } from "../config/env.js";
6
+ import { createToolCatalogLoader } from "./tool-catalog.js";
7
+ import { registerExecuteCapabilityTool } from "./tools/execute-capability.js";
8
+ import { registerGeneratedCapabilityTool } from "./tools/generated-capability-tool.js";
9
+ import { registerGetCapabilityContractTool } from "./tools/get-capability-contract.js";
10
+ import { registerListCapabilityToolsTool } from "./tools/list-capability-tools.js";
11
+ import { registerListDomainsTool } from "./tools/list-domains.js";
12
+ import { registerRecommendCapabilityRouteTool } from "./tools/recommend-capability-route.js";
13
+ export async function createMcpServer(client) {
14
+ const getToolCatalog = createToolCatalogLoader(client);
15
+ const toolCatalog = await getToolCatalog();
16
+ const server = new McpServer({
17
+ name: MCP_SERVER_NAME,
18
+ version: APP_VERSION,
19
+ });
20
+ registerListDomainsTool(server, client);
21
+ registerListCapabilityToolsTool(server, getToolCatalog);
22
+ registerGetCapabilityContractTool(server, client);
23
+ registerRecommendCapabilityRouteTool(server, client);
24
+ registerExecuteCapabilityTool(server, client);
25
+ for (const tool of toolCatalog.tools) {
26
+ registerGeneratedCapabilityTool(server, client, tool);
27
+ }
28
+ return server;
29
+ }
30
+ export async function runMcpServer() {
31
+ const env = readEnv();
32
+ const client = new AgenticApiClient({
33
+ baseUrl: env.agenticApiBaseUrl,
34
+ apiKey: env.agenticApiKey,
35
+ });
36
+ const server = await createMcpServer(client);
37
+ const transport = new StdioServerTransport();
38
+ await server.connect(transport);
39
+ process.stderr.write(`[${MCP_SERVER_NAME}] MCP server connected over stdio.\n`);
40
+ }
41
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oCAAoC,EAAE,MAAM,uCAAuC,CAAC;AAE7F,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAwB;IAC5D,MAAM,cAAc,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,WAAW;KACrB,CAAC,CAAC;IAEH,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,+BAA+B,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxD,iCAAiC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,oCAAoC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,6BAA6B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACrC,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC;QAClC,OAAO,EAAE,GAAG,CAAC,iBAAiB;QAC9B,MAAM,EAAE,GAAG,CAAC,aAAa;KAC1B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,eAAe,sCAAsC,CAC1D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ import { AgenticApiClient } from "../agentic-api/client.js";
3
+ import type { CapabilityContract, CapabilityOperationContract, DiscoverySource } from "../agentic-api/types.js";
4
+ export type CapabilityToolDefinition = {
5
+ kind: "capability";
6
+ name: string;
7
+ title: string;
8
+ description: string;
9
+ inputSchema: z.ZodTypeAny;
10
+ domain: string;
11
+ capabilityId: string;
12
+ capabilityKey: string;
13
+ operation: "recommend" | "execute";
14
+ docsUrl?: string | null;
15
+ contract?: CapabilityContract | null;
16
+ operationContract?: CapabilityOperationContract | null;
17
+ };
18
+ export type ToolCatalog = {
19
+ builtAt: number;
20
+ source: DiscoverySource;
21
+ fallbackReason?: string;
22
+ tools: CapabilityToolDefinition[];
23
+ byName: Map<string, CapabilityToolDefinition>;
24
+ };
25
+ export type ToolCatalogLoader = () => Promise<ToolCatalog>;
26
+ export declare function createToolCatalogLoader(client: AgenticApiClient): ToolCatalogLoader;
27
+ export declare function buildToolCatalog(client: AgenticApiClient): Promise<ToolCatalog>;
@@ -0,0 +1,204 @@
1
+ import { z } from "zod";
2
+ import { AgenticApiClient } from "../agentic-api/client.js";
3
+ import { discoverAllCapabilities } from "../catalog/discovery.js";
4
+ const TOOL_BUILD_CONCURRENCY = 12;
5
+ export function createToolCatalogLoader(client) {
6
+ let cachedPromise = null;
7
+ return () => {
8
+ cachedPromise ??= buildToolCatalog(client);
9
+ return cachedPromise;
10
+ };
11
+ }
12
+ export async function buildToolCatalog(client) {
13
+ const discoveredCapabilities = await discoverAllCapabilities(client);
14
+ const liveCapabilities = discoveredCapabilities.items.filter((capability) => capability.status !== "planned");
15
+ const toolEntries = await mapWithConcurrency(liveCapabilities, TOOL_BUILD_CONCURRENCY, async (capability) => buildCapabilityTools(client, capability));
16
+ const tools = toolEntries.flat();
17
+ return {
18
+ builtAt: Date.now(),
19
+ source: discoveredCapabilities.source,
20
+ fallbackReason: discoveredCapabilities.fallbackReason,
21
+ tools,
22
+ byName: new Map(tools.map((tool) => [tool.name, tool])),
23
+ };
24
+ }
25
+ async function buildCapabilityTools(client, capability) {
26
+ if (!capability.recommendEndpoint && !capability.executeEndpoint) {
27
+ return [];
28
+ }
29
+ const contract = await safeGetCapabilityContract(client, capability.domain, capability.capability);
30
+ const tools = [];
31
+ if (capability.recommendEndpoint) {
32
+ tools.push(buildCapabilityTool(capability, contract, "recommend"));
33
+ }
34
+ if (capability.executeEndpoint) {
35
+ tools.push(buildCapabilityTool(capability, contract, "execute"));
36
+ }
37
+ return tools;
38
+ }
39
+ function buildCapabilityTool(capability, contract, operation) {
40
+ const capabilityKey = capability.key ?? `${capability.domain}.${capability.capability}`;
41
+ const operationContract = operation === "recommend" ? contract?.recommend ?? null : contract?.execute ?? null;
42
+ return {
43
+ kind: "capability",
44
+ name: `${normalizeToolName(capabilityKey)}_${operation}`,
45
+ title: `${capability.label ?? humanizeIdentifier(capability.capability)} ${capitalize(operation)}`,
46
+ description: [
47
+ capability.description ?? `${humanizeIdentifier(capability.capability)} in ${capability.domain}.`,
48
+ operation === "recommend"
49
+ ? "Use this tool to choose the best AgentDiscuss route before execution."
50
+ : "Use this tool to run the AgentDiscuss capability.",
51
+ capability.docsUrl ? `Docs: ${capability.docsUrl}.` : null,
52
+ ]
53
+ .filter(Boolean)
54
+ .join(" "),
55
+ inputSchema: buildOperationInputSchema(operationContract),
56
+ domain: capability.domain,
57
+ capabilityId: capability.capability,
58
+ capabilityKey,
59
+ operation,
60
+ docsUrl: capability.docsUrl,
61
+ contract,
62
+ operationContract,
63
+ };
64
+ }
65
+ function buildOperationInputSchema(operationContract) {
66
+ if (!operationContract || operationContract.fields.length === 0) {
67
+ const fallbackSchema = z.object({}).catchall(z.unknown());
68
+ return operationContract?.requestExample
69
+ ? fallbackSchema.meta({
70
+ examples: [operationContract.requestExample],
71
+ })
72
+ : fallbackSchema.describe("The upstream AgentDiscuss capability catalog has not published a field-level contract for this operation yet.");
73
+ }
74
+ const shape = {};
75
+ for (const field of operationContract.fields) {
76
+ const fieldSchema = buildFieldSchema(field);
77
+ shape[field.name] = field.required ? fieldSchema : fieldSchema.optional();
78
+ }
79
+ let schema = z.object(shape).strict();
80
+ if (operationContract.notes.length > 0) {
81
+ schema = schema.describe(operationContract.notes.join(" "));
82
+ }
83
+ if (operationContract.requestExample) {
84
+ schema = schema.meta({
85
+ examples: [operationContract.requestExample],
86
+ });
87
+ }
88
+ return schema;
89
+ }
90
+ function buildFieldSchema(field) {
91
+ let schema;
92
+ if (field.enumValues?.length) {
93
+ schema = z.enum(field.enumValues);
94
+ }
95
+ else {
96
+ switch (field.type) {
97
+ case "string":
98
+ schema = z.string();
99
+ break;
100
+ case "number":
101
+ schema = z.number();
102
+ break;
103
+ case "integer":
104
+ schema = z.number().int();
105
+ break;
106
+ case "boolean":
107
+ schema = z.boolean();
108
+ break;
109
+ case "array":
110
+ schema = z.array(buildArrayItemSchema(field));
111
+ break;
112
+ case "object": {
113
+ const shape = {};
114
+ for (const nestedField of field.fields ?? []) {
115
+ const nestedSchema = buildFieldSchema(nestedField);
116
+ shape[nestedField.name] = nestedField.required
117
+ ? nestedSchema
118
+ : nestedSchema.optional();
119
+ }
120
+ schema = z.object(shape).strict();
121
+ break;
122
+ }
123
+ default:
124
+ schema = z.unknown();
125
+ break;
126
+ }
127
+ }
128
+ if (field.type === "string" && typeof field.maxLength === "number") {
129
+ schema = schema.max(field.maxLength);
130
+ }
131
+ if ((field.type === "number" || field.type === "integer") &&
132
+ typeof field.min === "number") {
133
+ schema = schema.min(field.min);
134
+ }
135
+ if ((field.type === "number" || field.type === "integer") &&
136
+ typeof field.max === "number") {
137
+ schema = schema.max(field.max);
138
+ }
139
+ if (field.notes?.length) {
140
+ schema = schema.describe(field.notes.join(" "));
141
+ }
142
+ return schema;
143
+ }
144
+ function buildArrayItemSchema(field) {
145
+ switch (field.itemsType) {
146
+ case "string":
147
+ return z.string();
148
+ case "number":
149
+ return z.number();
150
+ case "integer":
151
+ return z.number().int();
152
+ case "boolean":
153
+ return z.boolean();
154
+ case "object":
155
+ return z.object({}).catchall(z.unknown());
156
+ default:
157
+ return z.unknown();
158
+ }
159
+ }
160
+ async function safeGetCapabilityContract(client, domain, capabilityId) {
161
+ try {
162
+ return await client.getCapabilityContract(domain, capabilityId);
163
+ }
164
+ catch {
165
+ return null;
166
+ }
167
+ }
168
+ async function mapWithConcurrency(items, concurrency, mapper) {
169
+ const results = new Array(items.length);
170
+ let nextIndex = 0;
171
+ const workers = Array.from({
172
+ length: Math.max(1, Math.min(concurrency, items.length || 1)),
173
+ }, async () => {
174
+ while (nextIndex < items.length) {
175
+ const currentIndex = nextIndex;
176
+ const item = items[currentIndex];
177
+ if (item === undefined) {
178
+ return;
179
+ }
180
+ nextIndex += 1;
181
+ results[currentIndex] = await mapper(item, currentIndex);
182
+ }
183
+ });
184
+ await Promise.all(workers);
185
+ return results;
186
+ }
187
+ function capitalize(value) {
188
+ return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
189
+ }
190
+ function humanizeIdentifier(value) {
191
+ return value
192
+ .replace(/[._-]+/g, " ")
193
+ .replace(/\s+/g, " ")
194
+ .trim()
195
+ .replace(/\b\w/g, (match) => match.toUpperCase());
196
+ }
197
+ function normalizeToolName(capabilityKey) {
198
+ return capabilityKey
199
+ .replace(/[^a-zA-Z0-9]+/g, "_")
200
+ .replace(/^_+|_+$/g, "")
201
+ .replace(/_+/g, "_")
202
+ .toLowerCase();
203
+ }
204
+ //# sourceMappingURL=tool-catalog.js.map