modality-ai 0.7.4 → 0.8.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/dist/index.js
CHANGED
|
@@ -126465,16 +126465,31 @@ class ModalityClientImpl {
|
|
|
126465
126465
|
}
|
|
126466
126466
|
}
|
|
126467
126467
|
parseContent(toolResult) {
|
|
126468
|
-
|
|
126469
|
-
|
|
126470
|
-
|
|
126471
|
-
return JSON.parse(
|
|
126468
|
+
const blocks = Array.isArray(toolResult?.content) ? toolResult.content : [];
|
|
126469
|
+
const parsed = blocks.filter((b) => b?.type === "text" && b.text).map((b) => {
|
|
126470
|
+
try {
|
|
126471
|
+
return JSON.parse(b.text);
|
|
126472
|
+
} catch {
|
|
126473
|
+
return b.text;
|
|
126472
126474
|
}
|
|
126473
|
-
|
|
126474
|
-
|
|
126475
|
-
|
|
126476
|
-
return content?.text ?? content ?? toolResult;
|
|
126475
|
+
});
|
|
126476
|
+
if (parsed.length === 0) {
|
|
126477
|
+
return toolResult?.content?.[0] ?? toolResult;
|
|
126477
126478
|
}
|
|
126479
|
+
const objects = parsed.filter((p) => typeof p === "object" && p !== null && !Array.isArray(p));
|
|
126480
|
+
const extras = parsed.filter((p) => typeof p !== "object" || p === null || Array.isArray(p));
|
|
126481
|
+
if (objects.length === 0) {
|
|
126482
|
+
return parsed.length === 1 ? parsed[0] : parsed;
|
|
126483
|
+
}
|
|
126484
|
+
const merged = Object.assign({}, ...objects);
|
|
126485
|
+
if (extras.length > 0) {
|
|
126486
|
+
const key = objects.some((o) => ("_extra" in o)) ? "__extra" : "_extra";
|
|
126487
|
+
merged[key] = extras.length === 1 ? extras[0] : extras;
|
|
126488
|
+
}
|
|
126489
|
+
if (merged.success === undefined) {
|
|
126490
|
+
merged.success = toolResult?.isError !== true;
|
|
126491
|
+
}
|
|
126492
|
+
return merged;
|
|
126478
126493
|
}
|
|
126479
126494
|
}
|
|
126480
126495
|
function http(url3, timeout, options) {
|
|
@@ -129443,7 +129458,7 @@ var setupStdioToHttpTools = async (client, mcpServer) => {
|
|
|
129443
129458
|
return setupAITools(aiTools, mcpServer);
|
|
129444
129459
|
};
|
|
129445
129460
|
// src/mcp-oauth-provider.ts
|
|
129446
|
-
import { createHash } from "node:crypto";
|
|
129461
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
129447
129462
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
129448
129463
|
import { homedir } from "node:os";
|
|
129449
129464
|
import { join as join9 } from "node:path";
|
|
@@ -129459,6 +129474,10 @@ class CLIBrowserOAuthProvider {
|
|
|
129459
129474
|
_serverIdentity;
|
|
129460
129475
|
_noOpen;
|
|
129461
129476
|
_cachePath;
|
|
129477
|
+
_callbackPath;
|
|
129478
|
+
_callbackHost;
|
|
129479
|
+
_state;
|
|
129480
|
+
_onAuthorizationUrl;
|
|
129462
129481
|
_port;
|
|
129463
129482
|
_server;
|
|
129464
129483
|
_resolveCode;
|
|
@@ -129471,6 +129490,10 @@ class CLIBrowserOAuthProvider {
|
|
|
129471
129490
|
constructor(options = {}) {
|
|
129472
129491
|
this._clientName = options.clientName ?? "mcp-cli";
|
|
129473
129492
|
this._noOpen = options.noOpen ?? false;
|
|
129493
|
+
this._onAuthorizationUrl = options.onAuthorizationUrl;
|
|
129494
|
+
this._state = randomBytes(16).toString("hex");
|
|
129495
|
+
this._callbackPath = options.externalCallback?.path ?? "/callback";
|
|
129496
|
+
this._callbackHost = options.externalCallback?.host ?? "127.0.0.1";
|
|
129474
129497
|
this._serverIdentity = options.serverUrl ? resolveServerIdentity(options.serverUrl) : null;
|
|
129475
129498
|
if (options.serverUrl === null) {
|
|
129476
129499
|
this._cachePath = null;
|
|
@@ -129490,11 +129513,15 @@ class CLIBrowserOAuthProvider {
|
|
|
129490
129513
|
this._resolveCode = resolve2;
|
|
129491
129514
|
this._rejectCode = reject3;
|
|
129492
129515
|
});
|
|
129493
|
-
|
|
129494
|
-
|
|
129495
|
-
|
|
129496
|
-
|
|
129497
|
-
|
|
129516
|
+
if (options.externalCallback) {
|
|
129517
|
+
this._port = options.externalCallback.port;
|
|
129518
|
+
} else {
|
|
129519
|
+
this._server = Bun.serve({
|
|
129520
|
+
port: options.callbackPort ?? 9876,
|
|
129521
|
+
fetch: (req) => this._handleCallback(req)
|
|
129522
|
+
});
|
|
129523
|
+
this._port = this._server.port ?? 9876;
|
|
129524
|
+
}
|
|
129498
129525
|
if (this._clientInfo) {
|
|
129499
129526
|
const uris = this._clientInfo.redirect_uris ?? [];
|
|
129500
129527
|
if (!uris.includes(this.redirectUrl)) {
|
|
@@ -129503,7 +129530,7 @@ class CLIBrowserOAuthProvider {
|
|
|
129503
129530
|
}
|
|
129504
129531
|
}
|
|
129505
129532
|
get redirectUrl() {
|
|
129506
|
-
return `http
|
|
129533
|
+
return `http://${this._callbackHost}:${this._port}${this._callbackPath}`;
|
|
129507
129534
|
}
|
|
129508
129535
|
get clientMetadata() {
|
|
129509
129536
|
const identity7 = this._serverIdentity;
|
|
@@ -129554,7 +129581,11 @@ class CLIBrowserOAuthProvider {
|
|
|
129554
129581
|
params.set("client_secret", secret3);
|
|
129555
129582
|
}
|
|
129556
129583
|
};
|
|
129584
|
+
state() {
|
|
129585
|
+
return this._state;
|
|
129586
|
+
}
|
|
129557
129587
|
async redirectToAuthorization(authorizationUrl) {
|
|
129588
|
+
this._onAuthorizationUrl?.(authorizationUrl);
|
|
129558
129589
|
const url5 = authorizationUrl.toString();
|
|
129559
129590
|
if (this._noOpen) {
|
|
129560
129591
|
console.error(`
|
|
@@ -129577,6 +129608,15 @@ class CLIBrowserOAuthProvider {
|
|
|
129577
129608
|
waitForCode() {
|
|
129578
129609
|
return this._pendingCode;
|
|
129579
129610
|
}
|
|
129611
|
+
get oauthState() {
|
|
129612
|
+
return this._state;
|
|
129613
|
+
}
|
|
129614
|
+
get callbackPath() {
|
|
129615
|
+
return this._callbackPath;
|
|
129616
|
+
}
|
|
129617
|
+
handleCallback(req) {
|
|
129618
|
+
return this._handleCallback(req);
|
|
129619
|
+
}
|
|
129580
129620
|
getDiscoveryState() {
|
|
129581
129621
|
return this._discoveryState;
|
|
129582
129622
|
}
|
|
@@ -129585,7 +129625,7 @@ class CLIBrowserOAuthProvider {
|
|
|
129585
129625
|
this._persistCache();
|
|
129586
129626
|
}
|
|
129587
129627
|
stop() {
|
|
129588
|
-
this._server
|
|
129628
|
+
this._server?.stop(true);
|
|
129589
129629
|
}
|
|
129590
129630
|
_loadCache() {
|
|
129591
129631
|
if (!this._cachePath)
|
|
@@ -129611,9 +129651,14 @@ class CLIBrowserOAuthProvider {
|
|
|
129611
129651
|
}
|
|
129612
129652
|
_handleCallback(req) {
|
|
129613
129653
|
const url5 = new URL(req.url);
|
|
129614
|
-
if (url5.pathname !==
|
|
129654
|
+
if (url5.pathname !== this._callbackPath) {
|
|
129615
129655
|
return new Response("Not found", { status: 404 });
|
|
129616
129656
|
}
|
|
129657
|
+
const returnedState = url5.searchParams.get("state");
|
|
129658
|
+
if (returnedState !== null && returnedState !== this._state) {
|
|
129659
|
+
this._rejectCode?.(new Error("OAuth state mismatch"));
|
|
129660
|
+
return errorPage("state_mismatch", "State parameter did not match.");
|
|
129661
|
+
}
|
|
129617
129662
|
const error54 = url5.searchParams.get("error");
|
|
129618
129663
|
if (error54) {
|
|
129619
129664
|
const description = url5.searchParams.get("error_description") ?? "";
|
|
@@ -47,6 +47,19 @@ declare class ModalityClientImpl {
|
|
|
47
47
|
callStream(method: string, params?: any, callback?: (p: any) => void): ReadableStream;
|
|
48
48
|
close(): Promise<void>;
|
|
49
49
|
listTools(): Promise<ListToolsResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Parse a CallToolResult into a plain value.
|
|
52
|
+
*
|
|
53
|
+
* modality-kit's `formatSuccessResponse(data, meta)` splits results across
|
|
54
|
+
* text blocks — block 0 is the envelope (`{message}`), blocks 1+ carry the
|
|
55
|
+
* payload — so ALL text blocks are parsed and object blocks shallow-merged
|
|
56
|
+
* (later blocks win on key collisions). Non-object blocks (e.g. the
|
|
57
|
+
* `DEBUG=1` "Response size" note) are collected under `_extra` (or
|
|
58
|
+
* `__extra` when the tool's payload already carries `_extra`).
|
|
59
|
+
*
|
|
60
|
+
* The merged object always carries `success`: derived from the MCP-level
|
|
61
|
+
* `isError` flag unless the tool set it explicitly.
|
|
62
|
+
*/
|
|
50
63
|
parseContent(toolResult: any): unknown;
|
|
51
64
|
}
|
|
52
65
|
export type ModalityClientInstance = ModalityClientImpl;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,8 +11,28 @@ interface CLIBrowserOAuthProviderOptions {
|
|
|
11
11
|
/**
|
|
12
12
|
* Port for the local callback server.
|
|
13
13
|
* Defaults to 9876 for a stable redirect_uri across runs.
|
|
14
|
+
* Ignored when `externalCallback` is set.
|
|
14
15
|
*/
|
|
15
16
|
callbackPort?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Route the OAuth redirect through an existing HTTP server instead of
|
|
19
|
+
* starting a local Bun.serve. When set, the provider binds no port of its
|
|
20
|
+
* own — the host app must forward the redirect request to `handleCallback()`.
|
|
21
|
+
* `port`/`path`/`host` define the advertised redirect_uri and must match the
|
|
22
|
+
* host server (defaults: host "127.0.0.1", path "/callback").
|
|
23
|
+
* Correlate the inbound callback to this provider via `oauthState`.
|
|
24
|
+
*/
|
|
25
|
+
externalCallback?: {
|
|
26
|
+
port: number;
|
|
27
|
+
path?: string;
|
|
28
|
+
host?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Invoked with the full authorization URL just before the browser opens.
|
|
32
|
+
* Lets the host correlate the later callback to this provider (e.g. by
|
|
33
|
+
* reading the `state` query param, which equals `oauthState`).
|
|
34
|
+
*/
|
|
35
|
+
onAuthorizationUrl?: (url: URL) => void;
|
|
16
36
|
/**
|
|
17
37
|
* Skip opening the system browser automatically.
|
|
18
38
|
* When true the authorization URL is printed but not launched.
|
|
@@ -58,8 +78,12 @@ export declare class CLIBrowserOAuthProvider implements OAuthClientProvider {
|
|
|
58
78
|
private readonly _serverIdentity;
|
|
59
79
|
private readonly _noOpen;
|
|
60
80
|
private readonly _cachePath;
|
|
81
|
+
private readonly _callbackPath;
|
|
82
|
+
private readonly _callbackHost;
|
|
83
|
+
private readonly _state;
|
|
84
|
+
private readonly _onAuthorizationUrl?;
|
|
61
85
|
private _port;
|
|
62
|
-
private _server
|
|
86
|
+
private _server?;
|
|
63
87
|
private _resolveCode?;
|
|
64
88
|
private _rejectCode?;
|
|
65
89
|
private _pendingCode;
|
|
@@ -89,16 +113,36 @@ export declare class CLIBrowserOAuthProvider implements OAuthClientProvider {
|
|
|
89
113
|
* auth-method string the registration response contained.
|
|
90
114
|
*/
|
|
91
115
|
readonly addClientAuthentication: AddClientAuthentication;
|
|
116
|
+
/**
|
|
117
|
+
* CSRF `state` echoed back on the redirect. The SDK reads this via the
|
|
118
|
+
* optional `state()` hook and appends it to the authorization request; the
|
|
119
|
+
* callback validates it. Also used by host apps to correlate an external
|
|
120
|
+
* callback to this provider instance.
|
|
121
|
+
*/
|
|
122
|
+
state(): string;
|
|
92
123
|
redirectToAuthorization(authorizationUrl: URL): Promise<void>;
|
|
93
124
|
/**
|
|
94
125
|
* Resolves with the authorization code once the browser redirect completes.
|
|
95
126
|
*/
|
|
96
127
|
waitForCode(): Promise<string>;
|
|
128
|
+
/** CSRF state for this flow — key an external callback route by this value. */
|
|
129
|
+
get oauthState(): string;
|
|
130
|
+
/** Advertised redirect path — the route an external host server must expose. */
|
|
131
|
+
get callbackPath(): string;
|
|
132
|
+
/**
|
|
133
|
+
* Handle an OAuth redirect request forwarded from an external host server
|
|
134
|
+
* (externalCallback mode). Resolves waitForCode() and returns the page to
|
|
135
|
+
* render in the browser tab.
|
|
136
|
+
*/
|
|
137
|
+
handleCallback(req: Request): Response;
|
|
97
138
|
/** Discovery state captured before registration — available even when registration fails. */
|
|
98
139
|
getDiscoveryState(): OAuthDiscoveryState | undefined;
|
|
99
140
|
/** Clear cached tokens only — forces browser re-auth on next run while keeping client registration. */
|
|
100
141
|
clearCache(): void;
|
|
101
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* Stop the local callback HTTP server. Call once auth is complete.
|
|
144
|
+
* No-op in externalCallback mode, where the host owns the server.
|
|
145
|
+
*/
|
|
102
146
|
stop(): void;
|
|
103
147
|
private _loadCache;
|
|
104
148
|
private _persistCache;
|
package/package.json
CHANGED