@paca-ai/paca-mcp 0.2.0-rc.1 → 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.
- package/README.md +12 -10
- package/build/api/client.d.ts.map +1 -1
- package/build/api/client.js.map +1 -1
- package/build/api/index.d.ts +0 -1
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +0 -1
- package/build/api/index.js.map +1 -1
- package/build/api/task-extended-client.d.ts +6 -12
- package/build/api/task-extended-client.d.ts.map +1 -1
- package/build/api/task-extended-client.js +31 -42
- package/build/api/task-extended-client.js.map +1 -1
- package/build/index.js +2 -2
- package/build/index.js.map +1 -1
- package/build/package.json +1 -1
- package/build/plugin-loader.d.ts +66 -0
- package/build/plugin-loader.d.ts.map +1 -0
- package/build/plugin-loader.js +362 -0
- package/build/plugin-loader.js.map +1 -0
- package/build/server.d.ts +3 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +19 -6
- package/build/server.js.map +1 -1
- package/build/tools/attachment-tools.d.ts +3 -7
- package/build/tools/attachment-tools.d.ts.map +1 -1
- package/build/tools/attachment-tools.js +3 -265
- package/build/tools/attachment-tools.js.map +1 -1
- package/build/tools/doc-github-tools.d.ts +3 -7
- package/build/tools/doc-github-tools.d.ts.map +1 -1
- package/build/tools/doc-github-tools.js +3 -256
- package/build/tools/doc-github-tools.js.map +1 -1
- package/build/tools/document-tools.d.ts.map +1 -1
- package/build/tools/document-tools.js.map +1 -1
- package/build/tools/index.d.ts +1 -2
- package/build/tools/index.d.ts.map +1 -1
- package/build/tools/index.js +12 -32
- package/build/tools/index.js.map +1 -1
- package/build/tools/member-tools.d.ts.map +1 -1
- package/build/tools/member-tools.js.map +1 -1
- package/build/tools/project-tools.d.ts.map +1 -1
- package/build/tools/project-tools.js.map +1 -1
- package/build/tools/sprint-tools.d.ts.map +1 -1
- package/build/tools/sprint-tools.js.map +1 -1
- package/build/tools/task-activity-tools.d.ts +1 -5
- package/build/tools/task-activity-tools.d.ts.map +1 -1
- package/build/tools/task-activity-tools.js +12 -238
- package/build/tools/task-activity-tools.js.map +1 -1
- package/build/tools/task-tools.d.ts +2 -2
- package/build/tools/task-tools.d.ts.map +1 -1
- package/build/tools/task-tools.js +50 -21
- package/build/tools/task-tools.js.map +1 -1
- package/build/tools/task-type-tools.d.ts.map +1 -1
- package/build/tools/task-type-tools.js.map +1 -1
- package/build/types/index.d.ts +2 -27
- package/build/types/index.d.ts.map +1 -1
- package/build/utils/converters.d.ts +4 -1
- package/build/utils/converters.d.ts.map +1 -1
- package/build/utils/converters.js +127 -3
- package/build/utils/converters.js.map +1 -1
- package/build/utils/formatters.d.ts +18 -1
- package/build/utils/formatters.d.ts.map +1 -1
- package/build/utils/formatters.js +126 -0
- package/build/utils/formatters.js.map +1 -1
- package/package.json +1 -1
- package/build/api/github-client.d.ts +0 -21
- package/build/api/github-client.d.ts.map +0 -1
- package/build/api/github-client.js +0 -87
- 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
|
package/build/server.d.ts.map
CHANGED
|
@@ -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
|
|
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,
|
|
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;
|
package/build/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACN,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,
|
|
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 {
|
|
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
|
-
*
|
|
8
|
+
* Handles attachment tool calls.
|
|
9
9
|
*/
|
|
10
|
-
export declare function
|
|
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,
|
|
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"}
|