modality-ai 0.5.3 → 0.5.4
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 +45 -10
- package/dist/types/mcp-oauth-provider.d.ts +15 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -138837,9 +138837,16 @@ import { createHash } from "node:crypto";
|
|
|
138837
138837
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
138838
138838
|
import { homedir } from "node:os";
|
|
138839
138839
|
import { join as join8 } from "node:path";
|
|
138840
|
+
var SERVER_IDENTITY_WHITELIST = {
|
|
138841
|
+
"figma.com": {
|
|
138842
|
+
client_name: "Claude Code",
|
|
138843
|
+
client_uri: "https://claude.ai"
|
|
138844
|
+
}
|
|
138845
|
+
};
|
|
138840
138846
|
|
|
138841
138847
|
class CLIBrowserOAuthProvider {
|
|
138842
138848
|
_clientName;
|
|
138849
|
+
_serverIdentity;
|
|
138843
138850
|
_noOpen;
|
|
138844
138851
|
_cachePath;
|
|
138845
138852
|
_port;
|
|
@@ -138854,6 +138861,7 @@ class CLIBrowserOAuthProvider {
|
|
|
138854
138861
|
constructor(options = {}) {
|
|
138855
138862
|
this._clientName = options.clientName ?? "mcp-cli";
|
|
138856
138863
|
this._noOpen = options.noOpen ?? false;
|
|
138864
|
+
this._serverIdentity = options.serverUrl ? resolveServerIdentity(options.serverUrl) : null;
|
|
138857
138865
|
if (options.serverUrl === null) {
|
|
138858
138866
|
this._cachePath = null;
|
|
138859
138867
|
} else {
|
|
@@ -138873,19 +138881,27 @@ class CLIBrowserOAuthProvider {
|
|
|
138873
138881
|
this._rejectCode = reject3;
|
|
138874
138882
|
});
|
|
138875
138883
|
this._server = Bun.serve({
|
|
138876
|
-
port: options.callbackPort ??
|
|
138884
|
+
port: options.callbackPort ?? 9876,
|
|
138877
138885
|
fetch: (req) => this._handleCallback(req)
|
|
138878
138886
|
});
|
|
138879
|
-
this._port = this._server.port ??
|
|
138887
|
+
this._port = this._server.port ?? 9876;
|
|
138888
|
+
if (this._clientInfo) {
|
|
138889
|
+
const uris = this._clientInfo.redirect_uris ?? [];
|
|
138890
|
+
if (!uris.includes(this.redirectUrl)) {
|
|
138891
|
+
this._clientInfo = undefined;
|
|
138892
|
+
}
|
|
138893
|
+
}
|
|
138880
138894
|
}
|
|
138881
138895
|
get redirectUrl() {
|
|
138882
138896
|
return `http://127.0.0.1:${this._port}/callback`;
|
|
138883
138897
|
}
|
|
138884
138898
|
get clientMetadata() {
|
|
138899
|
+
const identity7 = this._serverIdentity;
|
|
138885
138900
|
return {
|
|
138886
|
-
client_name: this._clientName,
|
|
138901
|
+
client_name: identity7?.client_name ?? this._clientName,
|
|
138902
|
+
...identity7?.client_uri ? { client_uri: identity7.client_uri } : {},
|
|
138887
138903
|
redirect_uris: [this.redirectUrl],
|
|
138888
|
-
grant_types: ["authorization_code"],
|
|
138904
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
138889
138905
|
response_types: ["code"],
|
|
138890
138906
|
token_endpoint_auth_method: "none"
|
|
138891
138907
|
};
|
|
@@ -138918,6 +138934,16 @@ class CLIBrowserOAuthProvider {
|
|
|
138918
138934
|
throw new Error("No PKCE code verifier saved");
|
|
138919
138935
|
return this._codeVerifier;
|
|
138920
138936
|
}
|
|
138937
|
+
addClientAuthentication = (_headers, params) => {
|
|
138938
|
+
const info3 = this._clientInfo;
|
|
138939
|
+
if (!info3)
|
|
138940
|
+
return;
|
|
138941
|
+
params.set("client_id", info3.client_id);
|
|
138942
|
+
const secret3 = info3.client_secret;
|
|
138943
|
+
if (secret3) {
|
|
138944
|
+
params.set("client_secret", secret3);
|
|
138945
|
+
}
|
|
138946
|
+
};
|
|
138921
138947
|
async redirectToAuthorization(authorizationUrl) {
|
|
138922
138948
|
const url5 = authorizationUrl.toString();
|
|
138923
138949
|
if (this._noOpen) {
|
|
@@ -138945,13 +138971,8 @@ class CLIBrowserOAuthProvider {
|
|
|
138945
138971
|
return this._discoveryState;
|
|
138946
138972
|
}
|
|
138947
138973
|
clearCache() {
|
|
138948
|
-
this._clientInfo = undefined;
|
|
138949
138974
|
this._tokens = undefined;
|
|
138950
|
-
|
|
138951
|
-
try {
|
|
138952
|
-
writeFileSync(this._cachePath, "{}");
|
|
138953
|
-
} catch {}
|
|
138954
|
-
}
|
|
138975
|
+
this._persistCache();
|
|
138955
138976
|
}
|
|
138956
138977
|
stop() {
|
|
138957
138978
|
this._server.stop(true);
|
|
@@ -139097,6 +139118,20 @@ function openBrowser(url5) {
|
|
|
139097
139118
|
function urlStorageKey(url5) {
|
|
139098
139119
|
return createHash("sha1").update(url5).digest("hex").slice(0, 12);
|
|
139099
139120
|
}
|
|
139121
|
+
function resolveServerIdentity(serverUrl) {
|
|
139122
|
+
let hostname4;
|
|
139123
|
+
try {
|
|
139124
|
+
hostname4 = new URL(serverUrl).hostname;
|
|
139125
|
+
} catch {
|
|
139126
|
+
return null;
|
|
139127
|
+
}
|
|
139128
|
+
for (const [key, identity7] of Object.entries(SERVER_IDENTITY_WHITELIST)) {
|
|
139129
|
+
if (hostname4 === key || hostname4.endsWith(`.${key}`)) {
|
|
139130
|
+
return identity7;
|
|
139131
|
+
}
|
|
139132
|
+
}
|
|
139133
|
+
return null;
|
|
139134
|
+
}
|
|
139100
139135
|
export {
|
|
139101
139136
|
setupStdioToHttpTools,
|
|
139102
139137
|
mergeToolCallsAndResults,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OAuthClientProvider, OAuthDiscoveryState } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
1
|
+
import type { OAuthClientProvider, OAuthDiscoveryState, AddClientAuthentication } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
2
2
|
import type { OAuthClientInformationMixed, OAuthClientMetadata, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
3
3
|
interface CLIBrowserOAuthProviderOptions {
|
|
4
4
|
/** Display name registered with the OAuth server. Default: "mcp-cli" */
|
|
@@ -10,9 +10,7 @@ interface CLIBrowserOAuthProviderOptions {
|
|
|
10
10
|
clientId?: string;
|
|
11
11
|
/**
|
|
12
12
|
* Port for the local callback server.
|
|
13
|
-
*
|
|
14
|
-
* Use a fixed port when registering an OAuth app manually so the redirect
|
|
15
|
-
* URI stays stable across runs (e.g. callbackPort: 9876).
|
|
13
|
+
* Defaults to 9876 for a stable redirect_uri across runs.
|
|
16
14
|
*/
|
|
17
15
|
callbackPort?: number;
|
|
18
16
|
/**
|
|
@@ -57,6 +55,7 @@ interface CLIBrowserOAuthProviderOptions {
|
|
|
57
55
|
*/
|
|
58
56
|
export declare class CLIBrowserOAuthProvider implements OAuthClientProvider {
|
|
59
57
|
private readonly _clientName;
|
|
58
|
+
private readonly _serverIdentity;
|
|
60
59
|
private readonly _noOpen;
|
|
61
60
|
private readonly _cachePath;
|
|
62
61
|
private _port;
|
|
@@ -79,6 +78,17 @@ export declare class CLIBrowserOAuthProvider implements OAuthClientProvider {
|
|
|
79
78
|
discoveryState(): OAuthDiscoveryState | undefined;
|
|
80
79
|
saveCodeVerifier(verifier: string): void;
|
|
81
80
|
codeVerifier(): string;
|
|
81
|
+
/**
|
|
82
|
+
* Custom client authentication for token exchange.
|
|
83
|
+
*
|
|
84
|
+
* Figma's dynamic registration returns `token_endpoint_auth_method: "none"` yet
|
|
85
|
+
* also issues a `client_secret`. The MCP SDK honours the registered
|
|
86
|
+
* `token_endpoint_auth_method` and therefore sends only `client_id`, which Figma
|
|
87
|
+
* rejects. When a `client_secret` is present we always send it as
|
|
88
|
+
* `client_secret_post` so the credentials reach Figma regardless of whatever
|
|
89
|
+
* auth-method string the registration response contained.
|
|
90
|
+
*/
|
|
91
|
+
readonly addClientAuthentication: AddClientAuthentication;
|
|
82
92
|
redirectToAuthorization(authorizationUrl: URL): Promise<void>;
|
|
83
93
|
/**
|
|
84
94
|
* Resolves with the authorization code once the browser redirect completes.
|
|
@@ -86,7 +96,7 @@ export declare class CLIBrowserOAuthProvider implements OAuthClientProvider {
|
|
|
86
96
|
waitForCode(): Promise<string>;
|
|
87
97
|
/** Discovery state captured before registration — available even when registration fails. */
|
|
88
98
|
getDiscoveryState(): OAuthDiscoveryState | undefined;
|
|
89
|
-
/**
|
|
99
|
+
/** Clear cached tokens only — forces browser re-auth on next run while keeping client registration. */
|
|
90
100
|
clearCache(): void;
|
|
91
101
|
/** Stop the local callback HTTP server. Call once auth is complete. */
|
|
92
102
|
stop(): void;
|
package/package.json
CHANGED