@fitchmultz/pi-mcp-adapter 8.0.6 → 8.0.8
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/CHANGELOG.md +142 -8
- package/OAUTH.md +13 -16
- package/README.md +8 -8
- package/cli.js +67 -28
- package/dist/abort.js +18 -9
- package/dist/client-operations.js +4 -2
- package/dist/commands.js +77 -43
- package/dist/config.js +194 -105
- package/dist/connection-runtime.d.ts +2 -2
- package/dist/connection-runtime.js +29 -18
- package/dist/consent-manager.d.ts +2 -2
- package/dist/consent-manager.js +5 -2
- package/dist/direct-tools.d.ts +1 -1
- package/dist/direct-tools.js +13 -7
- package/dist/elicitation-handler.d.ts +2 -3
- package/dist/elicitation-handler.js +113 -58
- package/dist/gateway-arguments.d.ts +1 -1
- package/dist/gateway-arguments.js +90 -23
- package/dist/glimpse-ui.js +10 -5
- package/dist/host-html-template.d.ts +3 -1
- package/dist/host-html-template.js +9 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +264 -119
- package/dist/init.d.ts +1 -3
- package/dist/init.js +91 -51
- package/dist/legacy-migration.d.ts +1 -1
- package/dist/legacy-migration.js +17 -12
- package/dist/lifecycle.d.ts +3 -3
- package/dist/lifecycle.js +33 -17
- package/dist/logger.d.ts +2 -2
- package/dist/logger.js +4 -2
- package/dist/mcp-auth-flow.js +150 -58
- package/dist/mcp-auth.d.ts +7 -7
- package/dist/mcp-auth.js +189 -138
- package/dist/mcp-callback-server.js +19 -8
- package/dist/mcp-code.js +168 -54
- package/dist/mcp-keyring-helper.cjs +57 -23
- package/dist/mcp-oauth-provider.d.ts +6 -7
- package/dist/mcp-oauth-provider.js +146 -72
- package/dist/mcp-oauth-runtime.js +29 -16
- package/dist/mcp-output-guard.js +193 -65
- package/dist/mcp-output-preview.js +41 -20
- package/dist/mcp-panel.d.ts +9 -9
- package/dist/mcp-panel.js +141 -70
- package/dist/mcp-script-worker.mjs +135 -43
- package/dist/mcp-setup-panel.d.ts +8 -8
- package/dist/mcp-setup-panel.js +130 -44
- package/dist/mcp-status.js +14 -7
- package/dist/mcp-trace.d.ts +10 -5
- package/dist/mcp-trace.js +127 -61
- package/dist/metadata-cache.d.ts +3 -4
- package/dist/metadata-cache.js +83 -43
- package/dist/npx-resolver.js +101 -60
- package/dist/onboarding-state.js +4 -2
- package/dist/plain-result-reader.js +78 -31
- package/dist/prompts.js +36 -20
- package/dist/proxy-modes.js +670 -193
- package/dist/resource-tools.js +30 -9
- package/dist/runtime-owner.js +36 -18
- package/dist/sampling-handler.d.ts +1 -2
- package/dist/sampling-handler.js +41 -21
- package/dist/search-ranking.d.ts +1 -1
- package/dist/search-ranking.js +67 -34
- package/dist/server-manager.d.ts +11 -11
- package/dist/server-manager.js +283 -166
- package/dist/session-recovery.js +113 -61
- package/dist/tool-approval.js +9 -3
- package/dist/tool-loader.js +154 -55
- package/dist/tool-metadata.d.ts +1 -1
- package/dist/tool-metadata.js +51 -23
- package/dist/tool-registrar.js +32 -10
- package/dist/tool-result-renderer.js +58 -33
- package/dist/types.d.ts +2 -2
- package/dist/types.js +39 -18
- package/dist/ui-message-history.js +33 -13
- package/dist/ui-resource-handler.d.ts +3 -3
- package/dist/ui-resource-handler.js +37 -21
- package/dist/ui-server.js +101 -43
- package/dist/ui-session.js +66 -29
- package/dist/ui-stream-types.js +14 -4
- package/dist/ui-tool-visibility.js +12 -6
- package/dist/unix-socket-transport.d.ts +1 -2
- package/dist/unix-socket-transport.js +19 -12
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +60 -35
- package/package.json +28 -2
- package/skills/mcp-scripting/SKILL.md +6 -6
|
@@ -1,63 +1,130 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { MAX_PAGE_SIZE, MAX_TOOL_NAME_LENGTH } from "./search-ranking.js";
|
|
3
|
-
const actions = [
|
|
3
|
+
const actions = [
|
|
4
|
+
"status",
|
|
5
|
+
"search",
|
|
6
|
+
"list",
|
|
7
|
+
"describe",
|
|
8
|
+
"call",
|
|
9
|
+
"connect",
|
|
10
|
+
"instructions",
|
|
11
|
+
"resources",
|
|
12
|
+
"read-resource",
|
|
13
|
+
"read-result",
|
|
14
|
+
"auth-start",
|
|
15
|
+
"auth-complete",
|
|
16
|
+
"ui-messages",
|
|
17
|
+
];
|
|
4
18
|
const requirements = {
|
|
5
|
-
search: ["query"],
|
|
6
|
-
|
|
7
|
-
|
|
19
|
+
search: ["query"],
|
|
20
|
+
list: ["server"],
|
|
21
|
+
describe: ["tool"],
|
|
22
|
+
call: ["tool"],
|
|
23
|
+
connect: ["server"],
|
|
24
|
+
instructions: ["server"],
|
|
25
|
+
resources: ["server"],
|
|
26
|
+
"read-resource": ["server", "uri"],
|
|
27
|
+
"read-result": ["ref"],
|
|
28
|
+
"auth-start": ["server"],
|
|
29
|
+
"auth-complete": ["server"],
|
|
8
30
|
};
|
|
9
31
|
export const gatewayParameters = Type.Object({
|
|
10
32
|
action: Type.Unsafe({ type: "string", enum: [...actions] }),
|
|
11
33
|
server: Type.Optional(Type.String({ description: "MCP server; required for server and resource actions." })),
|
|
12
|
-
tool: Type.Optional(Type.String({
|
|
13
|
-
|
|
34
|
+
tool: Type.Optional(Type.String({
|
|
35
|
+
maxLength: MAX_TOOL_NAME_LENGTH,
|
|
36
|
+
description: "Exact tool name for call or describe. Use server to disambiguate.",
|
|
37
|
+
})),
|
|
38
|
+
args: Type.Optional(Type.Object({}, {
|
|
39
|
+
additionalProperties: true,
|
|
40
|
+
description: "Tool arguments, or {redirectUrl} for auth-complete.",
|
|
41
|
+
})),
|
|
14
42
|
query: Type.Optional(Type.String({ description: "Search terms. Prefer mcp_search to discover and load tools." })),
|
|
15
43
|
includeSchemas: Type.Optional(Type.Boolean({ description: "Include complete schemas in search results (default true)." })),
|
|
16
|
-
limit: Type.Optional(Type.Integer({
|
|
17
|
-
|
|
44
|
+
limit: Type.Optional(Type.Integer({
|
|
45
|
+
minimum: 1,
|
|
46
|
+
description: "Page size (default 12, max 100); for read-result, characters of selected JSON.",
|
|
47
|
+
})),
|
|
48
|
+
offset: Type.Optional(Type.Integer({
|
|
49
|
+
minimum: 0,
|
|
50
|
+
description: "Zero-based item offset; for read-result, character offset in selected JSON.",
|
|
51
|
+
})),
|
|
18
52
|
uri: Type.Optional(Type.String({ description: "Exact MCP resource URI for read-resource." })),
|
|
19
|
-
ref: Type.Optional(Type.String({
|
|
20
|
-
|
|
21
|
-
|
|
53
|
+
ref: Type.Optional(Type.String({
|
|
54
|
+
description: "Saved result reference returned by an earlier MCP call; read-result never calls the server again.",
|
|
55
|
+
})),
|
|
56
|
+
path: Type.Optional(Type.String({
|
|
57
|
+
description: "JSON Pointer into a saved result, e.g. /structuredContent/rows.",
|
|
58
|
+
})),
|
|
59
|
+
fields: Type.Optional(Type.Array(Type.String(), {
|
|
60
|
+
description: "Immediate object fields to retain when reading a saved result.",
|
|
61
|
+
})),
|
|
22
62
|
}, {
|
|
23
63
|
additionalProperties: false,
|
|
24
64
|
allOf: [
|
|
25
|
-
...Object.entries(requirements).map(([action, required]) => ({
|
|
26
|
-
|
|
65
|
+
...Object.entries(requirements).map(([action, required]) => ({
|
|
66
|
+
if: { properties: { action: { const: action } } },
|
|
67
|
+
then: { required },
|
|
68
|
+
})),
|
|
69
|
+
{
|
|
70
|
+
if: { properties: { action: { enum: ["search", "list", "connect", "resources"] } } },
|
|
71
|
+
then: { properties: { limit: { maximum: MAX_PAGE_SIZE } } },
|
|
72
|
+
},
|
|
27
73
|
],
|
|
28
74
|
});
|
|
29
75
|
/** Migrate stored v5 calls before host validation; the advertised schema stays explicit. */
|
|
30
76
|
export function prepareGatewayArguments(input) {
|
|
31
|
-
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
77
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
32
78
|
throw new Error("MCP arguments must be an object");
|
|
79
|
+
}
|
|
33
80
|
const value = input;
|
|
34
81
|
let action = value.action;
|
|
35
82
|
const result = { ...value };
|
|
36
83
|
if (action === undefined) {
|
|
37
|
-
action = value.tool
|
|
38
|
-
|
|
84
|
+
action = value.tool
|
|
85
|
+
? "call"
|
|
86
|
+
: value.connect
|
|
87
|
+
? "connect"
|
|
88
|
+
: value.describe
|
|
89
|
+
? "describe"
|
|
90
|
+
: value.instructions
|
|
91
|
+
? "instructions"
|
|
92
|
+
: value.search !== undefined
|
|
93
|
+
? "search"
|
|
94
|
+
: value.server
|
|
95
|
+
? "list"
|
|
96
|
+
: "status";
|
|
97
|
+
if (action === "connect") {
|
|
39
98
|
result.server = value.connect;
|
|
40
|
-
|
|
99
|
+
}
|
|
100
|
+
if (action === "describe") {
|
|
41
101
|
result.tool = value.describe;
|
|
42
|
-
|
|
102
|
+
}
|
|
103
|
+
if (action === "instructions") {
|
|
43
104
|
result.server = value.instructions;
|
|
44
|
-
|
|
105
|
+
}
|
|
106
|
+
if (action === "search") {
|
|
45
107
|
result.query = value.search;
|
|
108
|
+
}
|
|
46
109
|
}
|
|
47
|
-
for (const key of ["connect", "describe", "instructions", "search"])
|
|
110
|
+
for (const key of ["connect", "describe", "instructions", "search"]) {
|
|
48
111
|
delete result[key];
|
|
49
|
-
|
|
112
|
+
}
|
|
113
|
+
if (!actions.includes(action)) {
|
|
50
114
|
throw new Error(`Unknown MCP action: ${String(action)}`);
|
|
115
|
+
}
|
|
51
116
|
result.action = action;
|
|
52
117
|
if (typeof result.args === "string") {
|
|
53
118
|
result.args = result.args === "" ? undefined : JSON.parse(result.args);
|
|
54
119
|
}
|
|
55
|
-
if (result.args !== undefined &&
|
|
120
|
+
if (result.args !== undefined &&
|
|
121
|
+
(!result.args || typeof result.args !== "object" || Array.isArray(result.args))) {
|
|
56
122
|
throw new Error("Invalid args: expected a JSON object");
|
|
57
123
|
}
|
|
58
124
|
for (const field of requirements[action] ?? []) {
|
|
59
|
-
if (typeof result[field] !== "string" || (field !== "query" && result[field] === ""))
|
|
125
|
+
if (typeof result[field] !== "string" || (field !== "query" && result[field] === "")) {
|
|
60
126
|
throw new Error(`${action} requires ${field}`);
|
|
127
|
+
}
|
|
61
128
|
}
|
|
62
129
|
return result;
|
|
63
130
|
}
|
package/dist/glimpse-ui.js
CHANGED
|
@@ -14,8 +14,9 @@ import { createRequire } from "node:module";
|
|
|
14
14
|
let glimpseAvailable = null;
|
|
15
15
|
let resolvedBinaryPath = null;
|
|
16
16
|
export function isGlimpseAvailable() {
|
|
17
|
-
if (glimpseAvailable !== null)
|
|
17
|
+
if (glimpseAvailable !== null) {
|
|
18
18
|
return glimpseAvailable;
|
|
19
|
+
}
|
|
19
20
|
if (platform() !== "darwin") {
|
|
20
21
|
glimpseAvailable = false;
|
|
21
22
|
return false;
|
|
@@ -33,16 +34,18 @@ function getGlimpseBinaryPath() {
|
|
|
33
34
|
const require = createRequire(import.meta.url);
|
|
34
35
|
const glimpseuiPath = require.resolve("glimpseui");
|
|
35
36
|
const binaryPath = join(dirname(glimpseuiPath), "glimpse");
|
|
36
|
-
if (existsSync(binaryPath))
|
|
37
|
+
if (existsSync(binaryPath)) {
|
|
37
38
|
return binaryPath;
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
catch { }
|
|
40
42
|
// Global npm install
|
|
41
43
|
try {
|
|
42
44
|
const globalRoot = execFileSync("npm", ["root", "-g"], { encoding: "utf-8" }).trim();
|
|
43
45
|
const binaryPath = join(globalRoot, "glimpseui", "src", "glimpse");
|
|
44
|
-
if (existsSync(binaryPath))
|
|
46
|
+
if (existsSync(binaryPath)) {
|
|
45
47
|
return binaryPath;
|
|
48
|
+
}
|
|
46
49
|
}
|
|
47
50
|
catch { }
|
|
48
51
|
return null;
|
|
@@ -59,15 +62,17 @@ export async function openGlimpseWindow(html, options) {
|
|
|
59
62
|
title: options.title,
|
|
60
63
|
});
|
|
61
64
|
win.on("closed", () => {
|
|
62
|
-
if (!active)
|
|
65
|
+
if (!active) {
|
|
63
66
|
return;
|
|
67
|
+
}
|
|
64
68
|
active = false;
|
|
65
69
|
options.onClosed();
|
|
66
70
|
});
|
|
67
71
|
return {
|
|
68
72
|
close: () => {
|
|
69
|
-
if (!active)
|
|
73
|
+
if (!active) {
|
|
70
74
|
return;
|
|
75
|
+
}
|
|
71
76
|
active = false;
|
|
72
77
|
win.close();
|
|
73
78
|
},
|
|
@@ -12,4 +12,6 @@ export interface HostHtmlTemplateInput {
|
|
|
12
12
|
appBridgeModuleUrl?: string;
|
|
13
13
|
}
|
|
14
14
|
export declare function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string;
|
|
15
|
-
export declare function buildCspMetaContent(csp
|
|
15
|
+
export declare function buildCspMetaContent(csp?: {
|
|
16
|
+
[K in keyof UiResourceCsp]?: unknown;
|
|
17
|
+
}): string;
|
|
@@ -397,31 +397,28 @@ export function buildCspMetaContent(csp) {
|
|
|
397
397
|
toDirective("font-src", ["'self'"], resourceDomains),
|
|
398
398
|
toDirective("img-src", ["'self'", "data:"], resourceDomains),
|
|
399
399
|
toDirective("media-src", ["'self'", "data:"], resourceDomains),
|
|
400
|
-
connectDomains.length > 0
|
|
401
|
-
|
|
402
|
-
: "connect-src 'none'",
|
|
403
|
-
frameDomains.length > 0
|
|
404
|
-
? `frame-src ${frameDomains.join(" ")}`
|
|
405
|
-
: "frame-src 'none'",
|
|
400
|
+
connectDomains.length > 0 ? `connect-src ${connectDomains.join(" ")}` : "connect-src 'none'",
|
|
401
|
+
frameDomains.length > 0 ? `frame-src ${frameDomains.join(" ")}` : "frame-src 'none'",
|
|
406
402
|
"worker-src 'none'",
|
|
407
403
|
"object-src 'none'",
|
|
408
|
-
baseUriDomains.length > 0
|
|
409
|
-
? `base-uri ${baseUriDomains.join(" ")}`
|
|
410
|
-
: "base-uri 'self'",
|
|
404
|
+
baseUriDomains.length > 0 ? `base-uri ${baseUriDomains.join(" ")}` : "base-uri 'self'",
|
|
411
405
|
].join("; ");
|
|
412
406
|
}
|
|
413
407
|
function toDirective(name, trustedSources, domains) {
|
|
414
408
|
return `${name} ${[...new Set([...trustedSources, ...domains])].join(" ")}`;
|
|
415
409
|
}
|
|
416
410
|
function sanitizeCspDomains(domains) {
|
|
417
|
-
if (!Array.isArray(domains))
|
|
411
|
+
if (!Array.isArray(domains)) {
|
|
418
412
|
return [];
|
|
419
|
-
|
|
413
|
+
}
|
|
414
|
+
return [
|
|
415
|
+
...new Set(domains.filter((domain) => typeof domain === "string" &&
|
|
420
416
|
domain.length > 0 &&
|
|
421
417
|
// HTTP headers must be printable ASCII; rejecting all other code points also
|
|
422
418
|
// excludes every C0/C1 control character before Node serializes the policy.
|
|
423
419
|
/^[\x21-\x7E]+$/.test(domain) &&
|
|
424
|
-
!/[;'"]/.test(domain)))
|
|
420
|
+
!/[;'"]/.test(domain))),
|
|
421
|
+
];
|
|
425
422
|
}
|
|
426
423
|
function safeInlineJSON(value) {
|
|
427
424
|
return JSON.stringify(value)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { McpAdapterOptions } from "./types.ts";
|
|
3
|
-
export type { McpAdapterOptions, McpOperationContext, McpToolCallEvent, McpToolCallIdentity } from "./types.ts";
|
|
3
|
+
export type { McpAdapterOptions, McpOperationContext, McpToolCallEvent, McpToolCallIdentity, } from "./types.ts";
|
|
4
4
|
export { MCP_STATUS_EVENT, MCP_STATUS_SNAPSHOT_VERSION, type McpServerRuntimeStatus, type McpServerStatusSnapshot, type McpStatusSnapshot, } from "./types.ts";
|
|
5
5
|
export declare function createMcpAdapter(options?: McpAdapterOptions): (pi: ExtensionAPI) => void;
|
|
6
6
|
declare const _default: (pi: ExtensionAPI) => void;
|