apcore-mcp 0.3.0 → 0.5.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 (38) hide show
  1. package/dist/adapters/annotations.d.ts +6 -2
  2. package/dist/adapters/annotations.d.ts.map +1 -1
  3. package/dist/adapters/annotations.js +27 -9
  4. package/dist/adapters/annotations.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +20 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/explorer/handler.d.ts +55 -0
  9. package/dist/explorer/handler.d.ts.map +1 -0
  10. package/dist/explorer/handler.js +175 -0
  11. package/dist/explorer/handler.js.map +1 -0
  12. package/dist/explorer/html.d.ts +9 -0
  13. package/dist/explorer/html.d.ts.map +1 -0
  14. package/dist/explorer/html.js +238 -0
  15. package/dist/explorer/html.js.map +1 -0
  16. package/dist/explorer/index.d.ts +6 -0
  17. package/dist/explorer/index.d.ts.map +1 -0
  18. package/dist/explorer/index.js +5 -0
  19. package/dist/explorer/index.js.map +1 -0
  20. package/dist/index.d.ts +41 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +102 -18
  23. package/dist/index.js.map +1 -1
  24. package/dist/server/factory.d.ts +12 -0
  25. package/dist/server/factory.d.ts.map +1 -1
  26. package/dist/server/factory.js +73 -9
  27. package/dist/server/factory.js.map +1 -1
  28. package/dist/server/router.d.ts +7 -1
  29. package/dist/server/router.d.ts.map +1 -1
  30. package/dist/server/router.js +65 -5
  31. package/dist/server/router.js.map +1 -1
  32. package/dist/server/transport.d.ts +55 -1
  33. package/dist/server/transport.d.ts.map +1 -1
  34. package/dist/server/transport.js +114 -1
  35. package/dist/server/transport.js.map +1 -1
  36. package/dist/types.d.ts +4 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +19 -2
@@ -21,10 +21,14 @@ export declare class AnnotationMapper {
21
21
  /**
22
22
  * Generate a description suffix string from annotations.
23
23
  *
24
+ * Only includes annotation fields that differ from their default values:
25
+ * readonly=false, destructive=false, idempotent=false,
26
+ * requires_approval=false, open_world=true
27
+ *
24
28
  * Returns a formatted string like:
25
- * `\n\n[Annotations: readonly=true, destructive=false, ...]`
29
+ * `\n\n[Annotations: readonly=true, idempotent=true]`
26
30
  *
27
- * Returns an empty string if annotations are null.
31
+ * Returns an empty string if annotations are null or all fields are defaults.
28
32
  */
29
33
  toDescriptionSuffix(annotations: ModuleAnnotations | null): string;
30
34
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/adapters/annotations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzE,qBAAa,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,kBAAkB;IAoB3E;;;;;;;OAOG;IACH,mBAAmB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,MAAM;IAgBlE;;;;OAIG;IACH,mBAAmB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO;CAOpE"}
1
+ {"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/adapters/annotations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzE,qBAAa,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,kBAAkB;IAoB3E;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,MAAM;IAgClE;;;;OAIG;IACH,mBAAmB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO;CAOpE"}
@@ -37,22 +37,40 @@ export class AnnotationMapper {
37
37
  /**
38
38
  * Generate a description suffix string from annotations.
39
39
  *
40
+ * Only includes annotation fields that differ from their default values:
41
+ * readonly=false, destructive=false, idempotent=false,
42
+ * requires_approval=false, open_world=true
43
+ *
40
44
  * Returns a formatted string like:
41
- * `\n\n[Annotations: readonly=true, destructive=false, ...]`
45
+ * `\n\n[Annotations: readonly=true, idempotent=true]`
42
46
  *
43
- * Returns an empty string if annotations are null.
47
+ * Returns an empty string if annotations are null or all fields are defaults.
44
48
  */
45
49
  toDescriptionSuffix(annotations) {
46
50
  if (annotations === null) {
47
51
  return "";
48
52
  }
49
- const parts = [
50
- `readonly=${annotations.readonly}`,
51
- `destructive=${annotations.destructive}`,
52
- `idempotent=${annotations.idempotent}`,
53
- `requires_approval=${annotations.requiresApproval}`,
54
- `open_world=${annotations.openWorld}`,
55
- ];
53
+ const DEFAULTS = {
54
+ readonly: false,
55
+ destructive: false,
56
+ idempotent: false,
57
+ requires_approval: false,
58
+ open_world: true,
59
+ };
60
+ const parts = [];
61
+ if (annotations.readonly !== DEFAULTS.readonly)
62
+ parts.push(`readonly=${annotations.readonly}`);
63
+ if (annotations.destructive !== DEFAULTS.destructive)
64
+ parts.push(`destructive=${annotations.destructive}`);
65
+ if (annotations.idempotent !== DEFAULTS.idempotent)
66
+ parts.push(`idempotent=${annotations.idempotent}`);
67
+ if (annotations.requiresApproval !== DEFAULTS.requires_approval)
68
+ parts.push(`requires_approval=${annotations.requiresApproval}`);
69
+ if (annotations.openWorld !== DEFAULTS.open_world)
70
+ parts.push(`open_world=${annotations.openWorld}`);
71
+ if (parts.length === 0) {
72
+ return "";
73
+ }
56
74
  return `\n\n[Annotations: ${parts.join(", ")}]`;
57
75
  }
58
76
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/adapters/annotations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,OAAO,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,WAAqC;QACpD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO;gBACL,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,KAAK;gBACtB,cAAc,EAAE,KAAK;gBACrB,aAAa,EAAE,IAAI;gBACnB,KAAK,EAAE,IAAI;aACZ,CAAC;QACJ,CAAC;QAED,OAAO;YACL,YAAY,EAAE,WAAW,CAAC,QAAQ;YAClC,eAAe,EAAE,WAAW,CAAC,WAAW;YACxC,cAAc,EAAE,WAAW,CAAC,UAAU;YACtC,aAAa,EAAE,WAAW,CAAC,SAAS;YACpC,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,mBAAmB,CAAC,WAAqC;QACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,KAAK,GAAa;YACtB,YAAY,WAAW,CAAC,QAAQ,EAAE;YAClC,eAAe,WAAW,CAAC,WAAW,EAAE;YACxC,cAAc,WAAW,CAAC,UAAU,EAAE;YACtC,qBAAqB,WAAW,CAAC,gBAAgB,EAAE;YACnD,cAAc,WAAW,CAAC,SAAS,EAAE;SACtC,CAAC;QAEF,OAAO,qBAAqB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,mBAAmB,CAAC,WAAqC;QACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,WAAW,CAAC,gBAAgB,CAAC;IACtC,CAAC;CACF"}
1
+ {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/adapters/annotations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,OAAO,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,WAAqC;QACpD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO;gBACL,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,KAAK;gBACtB,cAAc,EAAE,KAAK;gBACrB,aAAa,EAAE,IAAI;gBACnB,KAAK,EAAE,IAAI;aACZ,CAAC;QACJ,CAAC;QAED,OAAO;YACL,YAAY,EAAE,WAAW,CAAC,QAAQ;YAClC,eAAe,EAAE,WAAW,CAAC,WAAW;YACxC,cAAc,EAAE,WAAW,CAAC,UAAU;YACtC,aAAa,EAAE,WAAW,CAAC,SAAS;YACpC,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,WAAqC;QACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAA4B;YACxC,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,KAAK;YACjB,iBAAiB,EAAE,KAAK;YACxB,UAAU,EAAE,IAAI;SACjB,CAAC;QAEF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;YAC5C,KAAK,CAAC,IAAI,CAAC,YAAY,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjD,IAAI,WAAW,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;YAClD,KAAK,CAAC,IAAI,CAAC,eAAe,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;QACvD,IAAI,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;YAChD,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,IAAI,WAAW,CAAC,gBAAgB,KAAK,QAAQ,CAAC,iBAAiB;YAC7D,KAAK,CAAC,IAAI,CAAC,qBAAqB,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAClE,IAAI,WAAW,CAAC,SAAS,KAAK,QAAQ,CAAC,UAAU;YAC/C,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;QAEpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,qBAAqB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,mBAAmB,CAAC,WAAqC;QACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,WAAW,CAAC,gBAAgB,CAAC;IACtC,CAAC;CACF"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAiCH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmG1C"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAoCH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkH1C"}
package/dist/cli.js CHANGED
@@ -28,6 +28,9 @@ Options:
28
28
  --name <string> MCP server name (default: apcore-mcp, max 255 chars)
29
29
  --version <string> MCP server version (default: package version)
30
30
  --log-level <level> Logging level: DEBUG, INFO, WARNING, ERROR (default: INFO)
31
+ --explorer Enable the browser-based Tool Explorer UI (HTTP only)
32
+ --explorer-prefix <path> URL prefix for the explorer UI (default: /explorer)
33
+ --allow-execute Allow tool execution from the explorer UI
31
34
  --help Show this help message
32
35
  `);
33
36
  }
@@ -47,6 +50,9 @@ export async function main() {
47
50
  name: { type: "string", default: "apcore-mcp" },
48
51
  version: { type: "string" },
49
52
  "log-level": { type: "string", default: "INFO" },
53
+ explorer: { type: "boolean", default: false },
54
+ "explorer-prefix": { type: "string", default: "/explorer" },
55
+ "allow-execute": { type: "boolean", default: false },
50
56
  help: { type: "boolean", default: false },
51
57
  },
52
58
  strict: true,
@@ -93,22 +99,27 @@ export async function main() {
93
99
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
100
  let Registry;
95
101
  try {
96
- // @ts-expect-error - apcore is a peer dependency, not available at compile time
97
- const apcore = await import("apcore");
102
+ const apcore = await import("apcore-js");
98
103
  Registry = apcore.Registry;
99
104
  }
100
105
  catch {
101
- fail("Failed to import 'apcore' package. Install it with: npm install apcore");
106
+ fail("Failed to import 'apcore-js' package. Install it with: npm install apcore-js");
102
107
  }
103
108
  // Create Registry and discover modules
104
- const registry = new Registry({ extensions_dir: resolvedDir });
105
- const numModules = registry.discover();
109
+ const registry = new Registry({ extensionsDir: resolvedDir });
110
+ const numModules = await registry.discover();
106
111
  if (numModules === 0) {
107
112
  console.warn(`Warning: No modules discovered in '${extensionsDir}'.`);
108
113
  }
109
114
  else {
110
115
  console.info(`Discovered ${numModules} module(s) in '${extensionsDir}'.`);
111
116
  }
117
+ // Validate log-level
118
+ const logLevel = values["log-level"];
119
+ const validLogLevels = ["DEBUG", "INFO", "WARNING", "ERROR"];
120
+ if (logLevel && !validLogLevels.includes(logLevel)) {
121
+ fail(`--log-level must be one of: ${validLogLevels.join(", ")}. Got '${logLevel}'.`);
122
+ }
112
123
  // Launch the MCP server
113
124
  try {
114
125
  await serve(registry, {
@@ -117,6 +128,10 @@ export async function main() {
117
128
  port,
118
129
  name,
119
130
  version: values.version ?? undefined,
131
+ logLevel: logLevel,
132
+ explorer: values.explorer,
133
+ explorerPrefix: values["explorer-prefix"],
134
+ allowExecute: values["allow-execute"],
120
135
  });
121
136
  }
122
137
  catch (error) {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * ExplorerHandler - HTTP route handler for the MCP Tool Explorer.
3
+ *
4
+ * Provides a browser-based UI for inspecting and testing MCP tools.
5
+ * Handles explorer-prefixed HTTP routes within the existing HTTP server.
6
+ *
7
+ * Routes:
8
+ * - GET {prefix}/ → HTML explorer page
9
+ * - GET {prefix}/tools → JSON array of tool summaries
10
+ * - GET {prefix}/tools/{name} → JSON tool detail
11
+ * - POST {prefix}/tools/{name}/call → Execute tool (403 if disabled)
12
+ */
13
+ import type { IncomingMessage, ServerResponse } from "node:http";
14
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
15
+ import type { ExecutionRouter } from "../server/router.js";
16
+ /** Options for creating an ExplorerHandler. */
17
+ export interface ExplorerHandlerOptions {
18
+ /** Whether to allow tool execution from the explorer UI. Default: false */
19
+ allowExecute?: boolean;
20
+ /** URL prefix for the explorer. Default: "/explorer" */
21
+ prefix?: string;
22
+ }
23
+ export declare class ExplorerHandler {
24
+ private readonly _toolsByName;
25
+ private readonly _tools;
26
+ private readonly _router;
27
+ private readonly _allowExecute;
28
+ private readonly _prefix;
29
+ constructor(tools: Tool[], router: ExecutionRouter, options?: ExplorerHandlerOptions);
30
+ /** The URL prefix this handler is mounted at. */
31
+ get prefix(): string;
32
+ /**
33
+ * Attempt to handle an HTTP request.
34
+ *
35
+ * @returns true if the request was handled, false if it should be passed through
36
+ */
37
+ handleRequest(req: IncomingMessage, res: ServerResponse, url: URL): Promise<boolean>;
38
+ /**
39
+ * Build a summary dict for a tool (used in the list endpoint).
40
+ */
41
+ private _toolSummary;
42
+ /**
43
+ * Build a full detail dict for a tool (used in the detail endpoint).
44
+ */
45
+ private _toolDetail;
46
+ /**
47
+ * Handle GET {prefix}/tools/{name} - return tool detail or 404.
48
+ */
49
+ private _handleToolDetail;
50
+ /**
51
+ * Handle POST {prefix}/tools/{name}/call - execute tool or return 403/404.
52
+ */
53
+ private _handleCallTool;
54
+ }
55
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/explorer/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI3D,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,sBAAsB;IASlC,iDAAiD;IACjD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACG,aAAa,CACjB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,GAAG,GACP,OAAO,CAAC,OAAO,CAAC;IA6CnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;YACW,eAAe;CAqE9B"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * ExplorerHandler - HTTP route handler for the MCP Tool Explorer.
3
+ *
4
+ * Provides a browser-based UI for inspecting and testing MCP tools.
5
+ * Handles explorer-prefixed HTTP routes within the existing HTTP server.
6
+ *
7
+ * Routes:
8
+ * - GET {prefix}/ → HTML explorer page
9
+ * - GET {prefix}/tools → JSON array of tool summaries
10
+ * - GET {prefix}/tools/{name} → JSON tool detail
11
+ * - POST {prefix}/tools/{name}/call → Execute tool (403 if disabled)
12
+ */
13
+ import { readBody } from "../server/transport.js";
14
+ import { EXPLORER_HTML } from "./html.js";
15
+ /** Maximum request body size for explorer call endpoint (1MB). */
16
+ const EXPLORER_MAX_BODY_BYTES = 1024 * 1024;
17
+ export class ExplorerHandler {
18
+ _toolsByName;
19
+ _tools;
20
+ _router;
21
+ _allowExecute;
22
+ _prefix;
23
+ constructor(tools, router, options) {
24
+ this._tools = tools;
25
+ this._router = router;
26
+ this._allowExecute = options?.allowExecute ?? false;
27
+ this._prefix = options?.prefix ?? "/explorer";
28
+ this._toolsByName = new Map(tools.map((t) => [t.name, t]));
29
+ }
30
+ /** The URL prefix this handler is mounted at. */
31
+ get prefix() {
32
+ return this._prefix;
33
+ }
34
+ /**
35
+ * Attempt to handle an HTTP request.
36
+ *
37
+ * @returns true if the request was handled, false if it should be passed through
38
+ */
39
+ async handleRequest(req, res, url) {
40
+ const pathname = url.pathname;
41
+ // Normalize: strip trailing slash for matching (except root)
42
+ const prefixSlash = this._prefix + "/";
43
+ // GET {prefix}/ → HTML page
44
+ if (req.method === "GET" &&
45
+ (pathname === this._prefix || pathname === prefixSlash)) {
46
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
47
+ res.end(EXPLORER_HTML);
48
+ return true;
49
+ }
50
+ // GET {prefix}/tools → list all tools
51
+ if (req.method === "GET" && pathname === this._prefix + "/tools") {
52
+ const summaries = this._tools.map((t) => this._toolSummary(t));
53
+ res.writeHead(200, { "Content-Type": "application/json" });
54
+ res.end(JSON.stringify(summaries));
55
+ return true;
56
+ }
57
+ // POST {prefix}/tools/{name}/call → execute tool
58
+ if (req.method === "POST" && pathname.startsWith(this._prefix + "/tools/") && pathname.endsWith("/call")) {
59
+ const toolName = decodeURIComponent(pathname.slice((this._prefix + "/tools/").length, -"/call".length));
60
+ await this._handleCallTool(req, res, toolName);
61
+ return true;
62
+ }
63
+ // GET {prefix}/tools/{name} → tool detail
64
+ if (req.method === "GET" && pathname.startsWith(this._prefix + "/tools/")) {
65
+ const toolName = decodeURIComponent(pathname.slice((this._prefix + "/tools/").length));
66
+ this._handleToolDetail(res, toolName);
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+ /**
72
+ * Build a summary dict for a tool (used in the list endpoint).
73
+ */
74
+ _toolSummary(tool) {
75
+ const result = {
76
+ name: tool.name,
77
+ description: tool.description ?? "",
78
+ };
79
+ if (tool.annotations) {
80
+ result.annotations = tool.annotations;
81
+ }
82
+ return result;
83
+ }
84
+ /**
85
+ * Build a full detail dict for a tool (used in the detail endpoint).
86
+ */
87
+ _toolDetail(tool) {
88
+ const result = {
89
+ name: tool.name,
90
+ description: tool.description ?? "",
91
+ inputSchema: tool.inputSchema,
92
+ };
93
+ if (tool.annotations) {
94
+ result.annotations = tool.annotations;
95
+ }
96
+ return result;
97
+ }
98
+ /**
99
+ * Handle GET {prefix}/tools/{name} - return tool detail or 404.
100
+ */
101
+ _handleToolDetail(res, toolName) {
102
+ const tool = this._toolsByName.get(toolName);
103
+ if (!tool) {
104
+ res.writeHead(404, { "Content-Type": "application/json" });
105
+ res.end(JSON.stringify({ error: `Tool not found: ${toolName}` }));
106
+ return;
107
+ }
108
+ res.writeHead(200, { "Content-Type": "application/json" });
109
+ res.end(JSON.stringify(this._toolDetail(tool)));
110
+ }
111
+ /**
112
+ * Handle POST {prefix}/tools/{name}/call - execute tool or return 403/404.
113
+ */
114
+ async _handleCallTool(req, res, toolName) {
115
+ if (!this._allowExecute) {
116
+ res.writeHead(403, { "Content-Type": "application/json" });
117
+ res.end(JSON.stringify({
118
+ error: "Tool execution is disabled. Launch with --allow-execute to enable.",
119
+ }));
120
+ return;
121
+ }
122
+ const tool = this._toolsByName.get(toolName);
123
+ if (!tool) {
124
+ res.writeHead(404, { "Content-Type": "application/json" });
125
+ res.end(JSON.stringify({ error: `Tool not found: ${toolName}` }));
126
+ return;
127
+ }
128
+ let body = {};
129
+ try {
130
+ const raw = await readBody(req, EXPLORER_MAX_BODY_BYTES);
131
+ if (raw) {
132
+ body = JSON.parse(raw);
133
+ }
134
+ }
135
+ catch {
136
+ // Use empty body if parsing fails
137
+ }
138
+ try {
139
+ const [content, isError] = await this._router.handleCall(toolName, body);
140
+ // Extract text from content list
141
+ const texts = content
142
+ .filter((item) => item.type === "text")
143
+ .map((item) => item.text);
144
+ // Try to parse as JSON for a cleaner response
145
+ let result;
146
+ if (texts.length === 1) {
147
+ try {
148
+ result = JSON.parse(texts[0]);
149
+ }
150
+ catch {
151
+ result = texts[0];
152
+ }
153
+ }
154
+ else {
155
+ result = texts;
156
+ }
157
+ if (isError) {
158
+ res.writeHead(500, { "Content-Type": "application/json" });
159
+ res.end(JSON.stringify({ error: result }));
160
+ }
161
+ else {
162
+ res.writeHead(200, { "Content-Type": "application/json" });
163
+ res.end(JSON.stringify({ result }));
164
+ }
165
+ }
166
+ catch (err) {
167
+ console.error(`Explorer call_tool error for ${toolName}:`, err);
168
+ res.writeHead(500, { "Content-Type": "application/json" });
169
+ res.end(JSON.stringify({
170
+ error: err instanceof Error ? err.message : String(err),
171
+ }));
172
+ }
173
+ }
174
+ }
175
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/explorer/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Self-contained HTML page for the MCP Tool Explorer.
3
+ *
4
+ * Single-page application with no external dependencies.
5
+ * Displays registered MCP tools, their schemas, annotations,
6
+ * and optionally allows executing tools from the browser.
7
+ */
8
+ export declare const EXPLORER_HTML = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>MCP Tool Explorer</title>\n<style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, monospace;\n background: #f5f5f5; color: #333; padding: 24px; }\n h1 { font-size: 1.4rem; margin-bottom: 16px; }\n .tool-list { list-style: none; }\n .tool-item { background: #fff; border: 1px solid #ddd; border-radius: 6px;\n padding: 12px 16px; margin-bottom: 8px; cursor: pointer; }\n .tool-item:hover { border-color: #888; }\n .tool-name { font-weight: 600; }\n .tool-desc { color: #666; font-size: 0.9rem; margin-top: 4px; }\n .hint { display: inline-block; background: #e8e8e8; padding: 2px 8px;\n border-radius: 3px; font-size: 0.75rem; margin-right: 4px; }\n .hint-readonly { background: #d4edda; color: #155724; }\n .hint-destructive { background: #f8d7da; color: #721c24; }\n .hint-idempotent { background: #cce5ff; color: #004085; }\n .detail { background: #fff; border: 1px solid #ddd; border-radius: 6px;\n padding: 16px; margin-top: 16px; display: none; }\n .detail.active { display: block; }\n .detail h2 { font-size: 1.1rem; margin-bottom: 12px; }\n .schema-label { font-weight: 600; margin-top: 12px; display: block; }\n pre { background: #282c34; color: #abb2bf; padding: 12px; border-radius: 4px;\n overflow-x: auto; font-size: 0.85rem; margin-top: 4px; }\n #loading { color: #888; }\n .try-it { margin-top: 16px; border-top: 1px solid #eee; padding-top: 16px; }\n .try-it h3 { font-size: 0.95rem; margin-bottom: 8px; }\n .input-editor { width: 100%; min-height: 120px; font-family: monospace;\n font-size: 0.85rem; padding: 10px; border: 1px solid #ddd;\n border-radius: 4px; resize: vertical; background: #fafafa; }\n .execute-btn { margin-top: 8px; padding: 8px 20px; background: #4CAF50; color: #fff;\n border: none; border-radius: 4px; cursor: pointer; font-size: 0.9rem;\n font-weight: 600; }\n .execute-btn:hover { background: #45a049; }\n .execute-btn:disabled { background: #ccc; cursor: not-allowed; }\n .result-area { margin-top: 12px; }\n .result-area pre { background: #1a2332; }\n .result-error { color: #f93e3e; }\n .result-success { color: #49cc90; }\n .exec-disabled { color: #888; font-size: 0.85rem; font-style: italic; margin-top: 16px; }\n</style>\n</head>\n<body>\n<h1>MCP Tool Explorer</h1>\n<div id=\"loading\">Loading tools...</div>\n<ul class=\"tool-list\" id=\"tools\"></ul>\n<div class=\"detail\" id=\"detail\"></div>\n<script>\n(function() {\n var base = window.location.pathname.replace(/\\/$/, '');\n var toolsEl = document.getElementById('tools');\n var detailEl = document.getElementById('detail');\n var loadingEl = document.getElementById('loading');\n var executeEnabled = null;\n\n function esc(s) {\n var d = document.createElement('div');\n d.appendChild(document.createTextNode(s));\n return d.innerHTML;\n }\n\n function defaultFromSchema(schema) {\n if (!schema || !schema.properties) return {};\n var result = {};\n var props = schema.properties;\n for (var key in props) {\n if (!props.hasOwnProperty(key)) continue;\n var t = props[key].type;\n if (props[key]['default'] !== undefined) {\n result[key] = props[key]['default'];\n } else if (t === 'string') {\n result[key] = '';\n } else if (t === 'number' || t === 'integer') {\n result[key] = 0;\n } else if (t === 'boolean') {\n result[key] = false;\n } else if (t === 'array') {\n result[key] = [];\n } else if (t === 'object') {\n result[key] = {};\n } else {\n result[key] = null;\n }\n }\n return result;\n }\n\n function hintsHtml(annotations) {\n if (!annotations) return '';\n var parts = [];\n if (annotations.readOnlyHint) parts.push('<span class=\"hint hint-readonly\">readOnly</span>');\n if (annotations.destructiveHint) parts.push('<span class=\"hint hint-destructive\">destructive</span>');\n if (annotations.idempotentHint) parts.push('<span class=\"hint hint-idempotent\">idempotent</span>');\n if (annotations.openWorldHint === false) parts.push('<span class=\"hint\">closedWorld</span>');\n return parts.join('');\n }\n\n fetch(base + '/tools')\n .then(function(r) { return r.json(); })\n .then(function(tools) {\n loadingEl.style.display = 'none';\n tools.forEach(function(t) {\n var li = document.createElement('li');\n li.className = 'tool-item';\n li.innerHTML =\n '<span class=\"tool-name\">' + esc(t.name) + '</span> ' +\n hintsHtml(t.annotations) +\n '<div class=\"tool-desc\">' + esc(t.description || '') + '</div>';\n li.onclick = function() { loadDetail(t.name); };\n toolsEl.appendChild(li);\n });\n fetch(base + '/tools/__probe__/call', {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: '{}'\n }).then(function(r) {\n executeEnabled = r.status !== 403;\n }).catch(function() {});\n })\n .catch(function(e) { loadingEl.textContent = 'Error: ' + e; });\n\n function loadDetail(name) {\n fetch(base + '/tools/' + encodeURIComponent(name))\n .then(function(r) { return r.json(); })\n .then(function(d) {\n detailEl.className = 'detail active';\n var html =\n '<h2>' + esc(d.name) + '</h2>' +\n '<p>' + esc(d.description || '') + '</p>' +\n '<span class=\"schema-label\">Input Schema</span>' +\n '<pre>' + esc(JSON.stringify(d.inputSchema, null, 2)) + '</pre>';\n\n if (d.annotations) {\n html += '<span class=\"schema-label\">Annotations</span>' +\n '<pre>' + esc(JSON.stringify(d.annotations, null, 2)) + '</pre>';\n }\n\n html += '<div class=\"try-it\" id=\"try-it-section\">' +\n '<h3>Try it</h3>' +\n '<textarea class=\"input-editor\" id=\"input-editor\">' +\n esc(JSON.stringify(defaultFromSchema(d.inputSchema), null, 2)) +\n '</textarea>' +\n '<button class=\"execute-btn\" id=\"execute-btn\">Execute</button>' +\n '<div class=\"result-area\" id=\"result-area\"></div>' +\n '</div>';\n\n detailEl.innerHTML = html;\n\n document.getElementById('execute-btn').onclick = function() {\n execTool(d.name);\n };\n\n if (executeEnabled === false) {\n var section = document.getElementById('try-it-section');\n if (section) section.innerHTML =\n '<p class=\"exec-disabled\">' +\n 'Tool execution is disabled. ' +\n 'Launch with --allow-execute to enable.</p>';\n }\n })\n .catch(function(e) {\n detailEl.className = 'detail active';\n detailEl.innerHTML = '<p class=\"result-error\">Failed to load tool details: ' + esc(e.message) + '</p>';\n });\n }\n\n function execTool(name) {\n var btn = document.getElementById('execute-btn');\n var editor = document.getElementById('input-editor');\n var resultArea = document.getElementById('result-area');\n\n var inputText = editor.value.trim();\n var inputs;\n try {\n inputs = inputText ? JSON.parse(inputText) : {};\n } catch (e) {\n resultArea.innerHTML = '<p class=\"result-error\">Invalid JSON: ' + esc(e.message) + '</p>';\n return;\n }\n\n btn.disabled = true;\n btn.textContent = 'Executing...';\n resultArea.innerHTML = '';\n\n fetch(base + '/tools/' + encodeURIComponent(name) + '/call', {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify(inputs)\n })\n .then(function(r) {\n if (r.status === 403) {\n executeEnabled = false;\n var section = document.getElementById('try-it-section');\n if (section) section.innerHTML =\n '<p class=\"exec-disabled\">' +\n 'Tool execution is disabled. ' +\n 'Launch with --allow-execute to enable.</p>';\n return null;\n }\n return r.json().then(function(data) { return {status: r.status, data: data}; });\n })\n .then(function(result) {\n if (!result) return;\n btn.disabled = false;\n btn.textContent = 'Execute';\n if (result.status >= 400) {\n resultArea.innerHTML = '<span class=\"schema-label result-error\">Error (' + result.status + ')</span>' +\n '<pre>' + esc(JSON.stringify(result.data, null, 2)) + '</pre>';\n } else {\n resultArea.innerHTML = '<span class=\"schema-label result-success\">Result</span>' +\n '<pre>' + esc(JSON.stringify(result.data, null, 2)) + '</pre>';\n }\n })\n .catch(function(e) {\n btn.disabled = false;\n btn.textContent = 'Execute';\n resultArea.innerHTML = '<p class=\"result-error\">Request failed: ' + esc(e.message) + '</p>';\n });\n }\n})();\n</script>\n</body>\n</html>\n";
9
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/explorer/html.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,i/RAqOzB,CAAC"}