@paca-ai/paca-mcp 0.2.0-rc.2 → 0.2.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 (67) hide show
  1. package/README.md +12 -10
  2. package/build/api/client.d.ts.map +1 -1
  3. package/build/api/client.js.map +1 -1
  4. package/build/api/index.d.ts +0 -1
  5. package/build/api/index.d.ts.map +1 -1
  6. package/build/api/index.js +0 -1
  7. package/build/api/index.js.map +1 -1
  8. package/build/api/task-extended-client.d.ts +6 -12
  9. package/build/api/task-extended-client.d.ts.map +1 -1
  10. package/build/api/task-extended-client.js +31 -42
  11. package/build/api/task-extended-client.js.map +1 -1
  12. package/build/index.js +2 -2
  13. package/build/index.js.map +1 -1
  14. package/build/package.json +1 -1
  15. package/build/plugin-loader.d.ts +66 -0
  16. package/build/plugin-loader.d.ts.map +1 -0
  17. package/build/plugin-loader.js +362 -0
  18. package/build/plugin-loader.js.map +1 -0
  19. package/build/server.d.ts +3 -1
  20. package/build/server.d.ts.map +1 -1
  21. package/build/server.js +19 -6
  22. package/build/server.js.map +1 -1
  23. package/build/tools/attachment-tools.d.ts +3 -7
  24. package/build/tools/attachment-tools.d.ts.map +1 -1
  25. package/build/tools/attachment-tools.js +3 -265
  26. package/build/tools/attachment-tools.js.map +1 -1
  27. package/build/tools/doc-github-tools.d.ts +3 -7
  28. package/build/tools/doc-github-tools.d.ts.map +1 -1
  29. package/build/tools/doc-github-tools.js +3 -256
  30. package/build/tools/doc-github-tools.js.map +1 -1
  31. package/build/tools/document-tools.d.ts.map +1 -1
  32. package/build/tools/document-tools.js.map +1 -1
  33. package/build/tools/index.d.ts +1 -2
  34. package/build/tools/index.d.ts.map +1 -1
  35. package/build/tools/index.js +12 -32
  36. package/build/tools/index.js.map +1 -1
  37. package/build/tools/member-tools.d.ts.map +1 -1
  38. package/build/tools/member-tools.js.map +1 -1
  39. package/build/tools/project-tools.d.ts.map +1 -1
  40. package/build/tools/project-tools.js.map +1 -1
  41. package/build/tools/sprint-tools.d.ts.map +1 -1
  42. package/build/tools/sprint-tools.js.map +1 -1
  43. package/build/tools/task-activity-tools.d.ts +1 -5
  44. package/build/tools/task-activity-tools.d.ts.map +1 -1
  45. package/build/tools/task-activity-tools.js +12 -238
  46. package/build/tools/task-activity-tools.js.map +1 -1
  47. package/build/tools/task-tools.d.ts +2 -2
  48. package/build/tools/task-tools.d.ts.map +1 -1
  49. package/build/tools/task-tools.js +50 -21
  50. package/build/tools/task-tools.js.map +1 -1
  51. package/build/tools/task-type-tools.d.ts.map +1 -1
  52. package/build/tools/task-type-tools.js.map +1 -1
  53. package/build/types/index.d.ts +2 -27
  54. package/build/types/index.d.ts.map +1 -1
  55. package/build/utils/converters.d.ts +4 -1
  56. package/build/utils/converters.d.ts.map +1 -1
  57. package/build/utils/converters.js +127 -3
  58. package/build/utils/converters.js.map +1 -1
  59. package/build/utils/formatters.d.ts +18 -1
  60. package/build/utils/formatters.d.ts.map +1 -1
  61. package/build/utils/formatters.js +126 -0
  62. package/build/utils/formatters.js.map +1 -1
  63. package/package.json +1 -1
  64. package/build/api/github-client.d.ts +0 -21
  65. package/build/api/github-client.d.ts.map +0 -1
  66. package/build/api/github-client.js +0 -87
  67. package/build/api/github-client.js.map +0 -1
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Plugin MCP loader.
3
+ *
4
+ * At MCP server startup this module:
5
+ * 1. Fetches the list of enabled plugins from `GET /api/v1/plugins`.
6
+ * 2. For each plugin that declares `manifest.mcp.remoteEntryUrl`, dynamically
7
+ * imports the remote entry module.
8
+ * 3. Validates the module's default export against the PluginMCPEntry contract.
9
+ * 4. Collects all tool definitions and registers dispatch mappings.
10
+ *
11
+ * The resulting {@link PluginRegistry} is consumed by `server.ts` to merge
12
+ * plugin tools with core tools and route tool calls.
13
+ */
14
+ import { resolve4, resolve6 } from "node:dns/promises";
15
+ import { isIPv4, isIPv6 } from "node:net";
16
+ // ── Registry ──────────────────────────────────────────────────────────────────
17
+ /**
18
+ * Holds all successfully loaded plugin MCP entries and their merged tool list.
19
+ * Constructed by {@link loadPlugins}.
20
+ */
21
+ export class PluginRegistry {
22
+ loaded;
23
+ /** Map from tool name → plugin ID (for fast dispatch). */
24
+ toolOwner;
25
+ /** Deduplicated tool definitions contributed by loaded plugins. */
26
+ tools;
27
+ constructor(loaded) {
28
+ this.loaded = loaded;
29
+ this.toolOwner = new Map();
30
+ this.tools = [];
31
+ for (const p of loaded) {
32
+ for (const tool of p.entry.tools) {
33
+ if (this.toolOwner.has(tool.name)) {
34
+ const existingPluginId = this.toolOwner.get(tool.name);
35
+ console.warn(`Duplicate plugin MCP tool name "${tool.name}" declared by plugin "${p.pluginId}"; already registered by plugin "${existingPluginId}". Skipping duplicate.`);
36
+ continue;
37
+ }
38
+ this.toolOwner.set(tool.name, p.pluginId);
39
+ this.tools.push(tool);
40
+ }
41
+ }
42
+ }
43
+ /** All unique tool definitions contributed by loaded plugins. */
44
+ getAllTools() {
45
+ return this.tools;
46
+ }
47
+ /**
48
+ * Dispatch a tool call to the owning plugin.
49
+ * Returns `null` if no loaded plugin owns the given tool name.
50
+ */
51
+ async handleToolCall(toolName, args, config) {
52
+ const pluginId = this.toolOwner.get(toolName);
53
+ if (!pluginId)
54
+ return null;
55
+ const plugin = this.loaded.find((p) => p.pluginId === pluginId);
56
+ if (!plugin)
57
+ return null;
58
+ const context = {
59
+ pluginId,
60
+ baseURL: config.baseURL,
61
+ apiKey: config.apiKey,
62
+ };
63
+ try {
64
+ return await plugin.entry.handleToolCall(toolName, args, context);
65
+ }
66
+ catch (error) {
67
+ const message = error instanceof Error ? error.message : "Unknown plugin tool error";
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text: `Plugin tool "${toolName}" failed: ${message}`,
73
+ },
74
+ ],
75
+ isError: true,
76
+ };
77
+ }
78
+ }
79
+ }
80
+ // ── Loader ────────────────────────────────────────────────────────────────────
81
+ /**
82
+ * Fetch all enabled plugins from the Paca API and load any that declare an
83
+ * `mcp.remoteEntryUrl` in their manifest.
84
+ *
85
+ * Failures for individual plugins are logged and skipped so that a broken
86
+ * third-party plugin does not prevent the server from starting.
87
+ */
88
+ export async function loadPlugins(config) {
89
+ let plugins = [];
90
+ try {
91
+ plugins = await fetchInstalledPlugins(config);
92
+ }
93
+ catch (err) {
94
+ console.error("[plugin-loader] Failed to fetch plugin list — starting without plugins:", err);
95
+ return new PluginRegistry([]);
96
+ }
97
+ const mcpPlugins = plugins.filter((p) => p.enabled && p.manifest?.mcp?.remoteEntryUrl);
98
+ if (mcpPlugins.length === 0) {
99
+ return new PluginRegistry([]);
100
+ }
101
+ console.error(`[plugin-loader] Loading ${mcpPlugins.length} plugin(s) with MCP tools...`);
102
+ const loaded = [];
103
+ for (const plugin of mcpPlugins) {
104
+ // biome-ignore lint/style/noNonNullAssertion: filtered above
105
+ const url = plugin.manifest.mcp.remoteEntryUrl;
106
+ try {
107
+ const entry = await loadPluginEntry(plugin.name, url, config.baseURL);
108
+ loaded.push({ pluginId: plugin.name, entry });
109
+ console.error(`[plugin-loader] Loaded "${plugin.name}" (${entry.tools.length} tool(s))`);
110
+ }
111
+ catch (err) {
112
+ console.error(`[plugin-loader] Failed to load plugin "${plugin.name}" from ${url}:`, err);
113
+ }
114
+ }
115
+ return new PluginRegistry(loaded);
116
+ }
117
+ // ── Helpers ───────────────────────────────────────────────────────────────────
118
+ async function fetchInstalledPlugins(config) {
119
+ const url = `${config.baseURL}/api/v1/plugins`;
120
+ const response = await fetch(url, {
121
+ headers: {
122
+ "Content-Type": "application/json",
123
+ "X-API-Key": config.apiKey,
124
+ },
125
+ });
126
+ if (!response.ok) {
127
+ const text = await response.text();
128
+ throw new Error(`GET /api/v1/plugins failed: ${response.status} ${response.statusText} — ${text}`);
129
+ }
130
+ const body = await response.json();
131
+ // Handle SuccessEnvelope wrapper
132
+ if (body && typeof body === "object" && "success" in body && body.success) {
133
+ const data = body.data;
134
+ return data.plugins ?? [];
135
+ }
136
+ // Direct array fallback
137
+ if (Array.isArray(body))
138
+ return body;
139
+ return [];
140
+ }
141
+ async function loadPluginEntry(pluginId, url, baseURL) {
142
+ // Dynamic import works for both file:// and https:// URLs in Node 18+.
143
+ // For http:// URLs (common in local dev), we fetch the source first and
144
+ // evaluate it via a data: URL import.
145
+ const importUrl = await resolveImportUrl(url, baseURL);
146
+ const mod = await import(importUrl);
147
+ const entry = mod.default ?? mod;
148
+ assertPluginMCPEntry(pluginId, entry);
149
+ return entry;
150
+ }
151
+ /**
152
+ * Resolve a plugin entry URL to a form that Node.js `import()` can consume,
153
+ * while enforcing URL safety rules:
154
+ *
155
+ * - Relative / path-only URLs (e.g. `/plugins-mcp/<id>/mcp.js`) are resolved
156
+ * against `baseURL` so that Node's `import()` receives an absolute URL.
157
+ * - Only `https://`, `file://`, and `http://` (localhost-only) URLs are
158
+ * accepted. Any other scheme is rejected.
159
+ * - For `https://` URLs the hostname is resolved via DNS and the function
160
+ * throws if any resolved address falls inside a private / internal IP range
161
+ * (SSRF protection, similar to the API marketplace URL validator).
162
+ * - For `http://` URLs the hostname must be localhost or a loopback address.
163
+ * The source is fetched and re-exposed as a `data:` URL because Node.js
164
+ * cannot `import()` plain `http://` URLs.
165
+ */
166
+ async function resolveImportUrl(url, baseURL) {
167
+ // Always resolve against baseURL so the URL constructor handles absolute,
168
+ // relative, and protocol-relative URLs correctly without fragile heuristics:
169
+ // "/plugins-mcp/id/mcp.js" → "<baseURL>/plugins-mcp/id/mcp.js"
170
+ // "//cdn.example.com/mcp.js" → inherits baseURL's scheme
171
+ // "https://cdn.example.com/mcp.js" → unchanged (base ignored for absolute URLs)
172
+ let resolved;
173
+ try {
174
+ resolved = new URL(url, baseURL);
175
+ }
176
+ catch {
177
+ throw new Error(`Plugin entry URL is invalid: "${url}"`);
178
+ }
179
+ const scheme = resolved.protocol; // includes trailing ':', e.g. "https:"
180
+ if (scheme === "file:") {
181
+ return resolved.href;
182
+ }
183
+ if (scheme === "https:") {
184
+ // Guard against SSRF: reject hostnames that resolve to private IPs.
185
+ await assertNotPrivateHost(resolved.hostname);
186
+ return resolved.href;
187
+ }
188
+ if (scheme === "http:") {
189
+ // http:// is allowed only for local development (localhost / loopback).
190
+ if (!isLocalhostHostname(resolved.hostname)) {
191
+ throw new Error(`http:// plugin URLs are only allowed for localhost. ` +
192
+ `Got "${resolved.hostname}" — use https:// for remote plugins.`);
193
+ }
194
+ // Node.js cannot import() http:// URLs — fetch source and wrap in a
195
+ // data: URL so import() can evaluate it without network restrictions.
196
+ const response = await fetch(resolved.href);
197
+ if (!response.ok) {
198
+ throw new Error(`Failed to fetch plugin module from ${resolved.href}: ${response.status} ${response.statusText}`);
199
+ }
200
+ const source = await response.text();
201
+ // Use base64 to avoid issues with special characters in the source
202
+ const b64 = Buffer.from(source, "utf8").toString("base64");
203
+ return `data:text/javascript;base64,${b64}`;
204
+ }
205
+ throw new Error(`Plugin entry URL scheme "${scheme.replace(":", "")}" is not allowed. ` +
206
+ `Only https://, http:// (localhost only), and file:// are permitted.`);
207
+ }
208
+ /** Returns true if the hostname is a loopback / localhost address. */
209
+ function isLocalhostHostname(hostname) {
210
+ const lower = hostname.toLowerCase();
211
+ // Plain loopback names and addresses
212
+ if (lower === "localhost" || lower === "127.0.0.1" || lower === "::1") {
213
+ return true;
214
+ }
215
+ // IPv4-mapped IPv6 loopback (e.g. ::ffff:127.0.0.1)
216
+ if (lower.startsWith("::ffff:")) {
217
+ const ipv4Part = lower.slice(7);
218
+ return ipv4Part.startsWith("127.");
219
+ }
220
+ return false;
221
+ }
222
+ /**
223
+ * Throws if `hostname` is an IP in a private / internal range, or if it
224
+ * resolves via DNS to such an IP. Mirrors the Go `isPrivateOrInternalIP`
225
+ * helper used by the API marketplace URL validator.
226
+ *
227
+ * Note: like the Go implementation this is susceptible to DNS rebinding.
228
+ * For production deployments consider an egress proxy with allowlist filtering.
229
+ */
230
+ async function assertNotPrivateHost(hostname) {
231
+ // If the hostname is already a bare IP, check it directly.
232
+ if (isIPv4(hostname) || isIPv6(hostname)) {
233
+ if (isPrivateIP(hostname)) {
234
+ throw new Error(`Plugin entry URL hostname "${hostname}" is a private/internal IP address`);
235
+ }
236
+ return;
237
+ }
238
+ // Resolve the hostname and check every resulting IP.
239
+ const ips = [];
240
+ const [v4Result, v6Result] = await Promise.allSettled([
241
+ resolve4(hostname),
242
+ resolve6(hostname),
243
+ ]);
244
+ if (v4Result.status === "fulfilled")
245
+ ips.push(...v4Result.value);
246
+ if (v6Result.status === "fulfilled")
247
+ ips.push(...v6Result.value);
248
+ if (ips.length === 0) {
249
+ throw new Error(`Failed to resolve plugin entry URL hostname "${hostname}"`);
250
+ }
251
+ for (const ip of ips) {
252
+ if (isPrivateIP(ip)) {
253
+ throw new Error(`Plugin entry URL hostname "${hostname}" resolves to private/internal IP "${ip}"`);
254
+ }
255
+ }
256
+ }
257
+ /**
258
+ * Returns true if `ip` falls within a private / internal IPv4 or IPv6 range.
259
+ * Covers: loopback, link-local, RFC-1918, and IPv6 unique-local / link-local.
260
+ */
261
+ function isPrivateIP(ip) {
262
+ if (isIPv4(ip)) {
263
+ const parts = ip.split(".").map(Number);
264
+ const [a, b] = parts;
265
+ // 127.0.0.0/8 — loopback
266
+ if (a === 127)
267
+ return true;
268
+ // 10.0.0.0/8 — RFC 1918
269
+ if (a === 10)
270
+ return true;
271
+ // 172.16.0.0/12 — RFC 1918
272
+ if (a === 172 && b >= 16 && b <= 31)
273
+ return true;
274
+ // 192.168.0.0/16 — RFC 1918
275
+ if (a === 192 && b === 168)
276
+ return true;
277
+ // 169.254.0.0/16 — link-local
278
+ if (a === 169 && b === 254)
279
+ return true;
280
+ return false;
281
+ }
282
+ if (isIPv6(ip)) {
283
+ const bytes = parseIPv6Bytes(ip);
284
+ if (!bytes)
285
+ return false;
286
+ const b0 = bytes[0];
287
+ const b1 = bytes[1];
288
+ // ::1 — loopback (128-bit all-zeros except last bit)
289
+ if (bytes.slice(0, 15).every((b) => b === 0) && bytes[15] === 1)
290
+ return true;
291
+ // fc00::/7 — unique local: first 7 bits are 1111110x (b0 & 0xfe === 0xfc)
292
+ if ((b0 & 0xfe) === 0xfc)
293
+ return true;
294
+ // fe80::/10 — link-local: first 10 bits are 1111111010 (b0 === 0xfe, b1 high 2 bits === 10)
295
+ if (b0 === 0xfe && (b1 & 0xc0) === 0x80)
296
+ return true;
297
+ // ::ffff:0:0/96 — IPv4-mapped: delegate to IPv4 check
298
+ const isIPv4Mapped = bytes.slice(0, 10).every((b) => b === 0) &&
299
+ bytes[10] === 0xff &&
300
+ bytes[11] === 0xff;
301
+ if (isIPv4Mapped) {
302
+ const ipv4 = `${bytes[12]}.${bytes[13]}.${bytes[14]}.${bytes[15]}`;
303
+ return isPrivateIP(ipv4);
304
+ }
305
+ return false;
306
+ }
307
+ return false;
308
+ }
309
+ /**
310
+ * Parse an IPv6 address string into a 16-byte Uint8Array.
311
+ * Handles compressed (::) notation by expanding it first via the URL API,
312
+ * which gives us reliable normalization without manual parsing.
313
+ * Returns null if parsing fails.
314
+ */
315
+ function parseIPv6Bytes(ip) {
316
+ try {
317
+ // Wrap in a URL to let the browser/Node URL parser normalize the address.
318
+ const u = new URL(`http://[${ip}]/`);
319
+ // hostname strips the brackets; the URL spec normalises IPv6 to lowercase.
320
+ const normalized = u.hostname;
321
+ // Expand :: shorthand.
322
+ const halves = normalized.split("::");
323
+ let groups;
324
+ if (halves.length === 2) {
325
+ const left = halves[0] ? halves[0].split(":") : [];
326
+ const right = halves[1] ? halves[1].split(":") : [];
327
+ const missing = 8 - left.length - right.length;
328
+ const fill = Array(missing).fill("0");
329
+ groups = [...left, ...fill, ...right];
330
+ }
331
+ else {
332
+ groups = normalized.split(":");
333
+ }
334
+ if (groups.length !== 8)
335
+ return null;
336
+ const bytes = new Uint8Array(16);
337
+ for (let i = 0; i < 8; i++) {
338
+ const val = Number.parseInt(groups[i], 16);
339
+ if (Number.isNaN(val) || val < 0 || val > 0xffff)
340
+ return null;
341
+ bytes[i * 2] = (val >> 8) & 0xff;
342
+ bytes[i * 2 + 1] = val & 0xff;
343
+ }
344
+ return bytes;
345
+ }
346
+ catch {
347
+ return null;
348
+ }
349
+ }
350
+ function assertPluginMCPEntry(pluginId, value) {
351
+ if (!value || typeof value !== "object") {
352
+ throw new Error(`Plugin "${pluginId}": default export is not an object`);
353
+ }
354
+ const entry = value;
355
+ if (!Array.isArray(entry.tools)) {
356
+ throw new Error(`Plugin "${pluginId}": default export must have a "tools" array`);
357
+ }
358
+ if (typeof entry.handleToolCall !== "function") {
359
+ throw new Error(`Plugin "${pluginId}": default export must have a "handleToolCall" function`);
360
+ }
361
+ }
362
+ //# sourceMappingURL=plugin-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"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"}
package/build/server.d.ts CHANGED
@@ -2,8 +2,10 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import type { PacaConfig } from "./types/index.js";
3
3
  /**
4
4
  * Creates and configures the Paca MCP server.
5
+ * Loads plugin MCP modules from the Paca API before returning.
6
+ *
5
7
  * @param config - Paca configuration
6
8
  * @returns Configured MCP server
7
9
  */
8
- export declare function createServer(config: PacaConfig): Server;
10
+ export declare function createServer(config: PacaConfig): Promise<Server>;
9
11
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAcnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA2CvD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAcnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA4DtE"}
package/build/server.js CHANGED
@@ -1,28 +1,32 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
- import { PacaAPIClient, PacaAPIDocClient, PacaAPIExtendedClient, PacaAPIGitHubClient, PacaAPITaskExtendedClient, PacaAPIViewsClient, } from "./api/index.js";
3
+ import { PacaAPIClient, PacaAPIDocClient, PacaAPIExtendedClient, PacaAPITaskExtendedClient, PacaAPIViewsClient, } from "./api/index.js";
4
+ import { loadPlugins } from "./plugin-loader.js";
4
5
  import { getAllTools, handleToolCall } from "./tools/index.js";
5
6
  /**
6
7
  * Creates and configures the Paca MCP server.
8
+ * Loads plugin MCP modules from the Paca API before returning.
9
+ *
7
10
  * @param config - Paca configuration
8
11
  * @returns Configured MCP server
9
12
  */
10
- export function createServer(config) {
13
+ export async function createServer(config) {
11
14
  // Initialize all API clients
12
15
  const apiClient = new PacaAPIClient(config);
13
16
  const extendedClient = new PacaAPIExtendedClient(config);
14
17
  const viewsClient = new PacaAPIViewsClient(config);
15
18
  const taskExtendedClient = new PacaAPITaskExtendedClient(config);
16
19
  const docClient = new PacaAPIDocClient(config);
17
- const githubClient = new PacaAPIGitHubClient(config);
18
20
  const clients = {
19
21
  apiClient,
20
22
  extendedClient,
21
23
  viewsClient,
22
24
  taskExtendedClient,
23
25
  docClient,
24
- githubClient,
25
26
  };
27
+ // Load plugin MCP modules from the Paca API.
28
+ // Failures for individual plugins are logged and skipped.
29
+ const pluginRegistry = await loadPlugins(config);
26
30
  const server = new Server({
27
31
  name: "paca",
28
32
  version: "0.1.0",
@@ -31,14 +35,23 @@ export function createServer(config) {
31
35
  tools: {},
32
36
  },
33
37
  });
34
- // Handler for listing available tools
38
+ // Handler for listing available tools (core + plugins)
35
39
  server.setRequestHandler(ListToolsRequestSchema, async () => {
36
40
  return {
37
- tools: getAllTools(),
41
+ tools: [...getAllTools(), ...pluginRegistry.getAllTools()],
38
42
  };
39
43
  });
40
44
  // Handler for executing tool calls
41
45
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
46
+ const { name, arguments: args } = request.params;
47
+ // Try plugin registry first (plugin tool names are chosen by developers,
48
+ // so we check plugins before falling through to core tools to make
49
+ // routing explicit).
50
+ const pluginResult = await pluginRegistry.handleToolCall(name, (args ?? {}), config);
51
+ if (pluginResult !== null) {
52
+ return pluginResult;
53
+ }
54
+ // Fall through to core tool handlers
42
55
  return handleToolCall(request, clients);
43
56
  });
44
57
  return server;
@@ -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,EACN,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG/D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC9C,6BAA6B;IAC7B,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,kBAAkB,GAAG,IAAI,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAErD,MAAM,OAAO,GAAG;QACf,SAAS;QACT,cAAc;QACd,WAAW;QACX,kBAAkB;QAClB,SAAS;QACT,YAAY;KACZ,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,MAAM,CACxB;QACC,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO;KAChB,EACD;QACC,YAAY,EAAE;YACb,KAAK,EAAE,EAAE;SACT;KACD,CACD,CAAC;IAEF,sCAAsC;IACtC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAC3D,OAAO;YACN,KAAK,EAAE,WAAW,EAAE;SACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,OAAO,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACN,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG/D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAkB;IACpD,6BAA6B;IAC7B,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,kBAAkB,GAAG,IAAI,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG;QACf,SAAS;QACT,cAAc;QACd,WAAW;QACX,kBAAkB;QAClB,SAAS;KACT,CAAC;IAEF,6CAA6C;IAC7C,0DAA0D;IAC1D,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,MAAM,CACxB;QACC,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO;KAChB,EACD;QACC,YAAY,EAAE;YACb,KAAK,EAAE,EAAE;SACT;KACD,CACD,CAAC;IAEF,uDAAuD;IACvD,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAC3D,OAAO;YACN,KAAK,EAAE,CAAC,GAAG,WAAW,EAAE,EAAE,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;SAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEjD,yEAAyE;QACzE,mEAAmE;QACnE,qBAAqB;QACrB,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,cAAc,CACvD,IAAI,EACJ,CAAC,IAAI,IAAI,EAAE,CAA4B,EACvC,MAAM,CACN,CAAC;QACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,YAAY,CAAC;QACrB,CAAC;QAED,qCAAqC;QACrC,OAAO,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -1,15 +1,11 @@
1
1
  import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
- import type { PacaAPITaskExtendedClient, PacaAPIViewsClient } from "../api/index.js";
2
+ import type { PacaAPIViewsClient } from "../api/index.js";
3
3
  /**
4
4
  * Returns all attachment-related MCP tools.
5
5
  */
6
6
  export declare function getAttachmentTools(): Tool[];
7
7
  /**
8
- * Returns all BDD scenario-related MCP tools.
8
+ * Handles attachment tool calls.
9
9
  */
10
- export declare function getBDDScenarioTools(): Tool[];
11
- /**
12
- * Handles attachment and BDD scenario tool calls.
13
- */
14
- export declare function handleAttachmentTool(toolName: string, args: any, viewsClient: PacaAPIViewsClient, taskClient: PacaAPITaskExtendedClient): Promise<any>;
10
+ export declare function handleAttachmentTool(toolName: string, args: any, viewsClient: PacaAPIViewsClient): Promise<any>;
15
11
  //# sourceMappingURL=attachment-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-tools.d.ts","sourceRoot":"","sources":["../../src/tools/attachment-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EACX,yBAAyB,EACzB,kBAAkB,EAClB,MAAM,iBAAiB,CAAC;AA0DzB;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,EAAE,CAiE3C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,EAAE,CA2I5C;AA2BD;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,kBAAkB,EAC/B,UAAU,EAAE,yBAAyB,GACnC,OAAO,CAAC,GAAG,CAAC,CA+Id"}
1
+ {"version":3,"file":"attachment-tools.d.ts","sourceRoot":"","sources":["../../src/tools/attachment-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAoB1D;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,EAAE,CAyE3C;AAWD;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,kBAAkB,GAC7B,OAAO,CAAC,GAAG,CAAC,CAsDd"}