@truealter/sdk 0.4.1 → 0.5.1
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 +103 -74
- package/dist/bin/alter-identity.js +177 -19
- package/dist/bin/mcp-bridge.js +47 -11
- package/dist/index.cjs +203 -20
- package/dist/index.d.cts +431 -30
- package/dist/index.d.ts +431 -30
- package/dist/index.js +199 -23
- package/dist/mcp-bridge.js +166 -0
- package/package.json +7 -4
package/dist/index.cjs
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
var p256 = require('@noble/curves/p256');
|
|
4
4
|
var sha256 = require('@noble/hashes/sha256');
|
|
5
5
|
var utils = require('@noble/hashes/utils');
|
|
6
|
+
var crypto$1 = require('crypto');
|
|
6
7
|
var ed25519 = require('@noble/ed25519');
|
|
7
8
|
var sha512 = require('@noble/hashes/sha512');
|
|
8
|
-
var
|
|
9
|
-
var os = require('os');
|
|
9
|
+
var fs = require('fs');
|
|
10
10
|
var path = require('path');
|
|
11
|
+
var os = require('os');
|
|
12
|
+
var child_process = require('child_process');
|
|
11
13
|
var process$1 = require('process');
|
|
12
|
-
var fs = require('fs');
|
|
13
|
-
var crypto$1 = require('crypto');
|
|
14
14
|
|
|
15
15
|
function _interopNamespace(e) {
|
|
16
16
|
if (e && e.__esModule) return e;
|
|
@@ -132,8 +132,7 @@ function loadPrivateKey(key) {
|
|
|
132
132
|
return key;
|
|
133
133
|
}
|
|
134
134
|
if (typeof key === "string" && key.includes("-----BEGIN")) {
|
|
135
|
-
const
|
|
136
|
-
const keyObj = nodeCrypto.createPrivateKey({ key, format: "pem" });
|
|
135
|
+
const keyObj = crypto$1.createPrivateKey({ key, format: "pem" });
|
|
137
136
|
const jwk = keyObj.export({ format: "jwk" });
|
|
138
137
|
if (jwk.crv !== "P-256" || !jwk.d) {
|
|
139
138
|
throw new TypeError("PEM is not a P-256 private key.");
|
|
@@ -457,11 +456,19 @@ var X402Client = class {
|
|
|
457
456
|
maxPerQuery;
|
|
458
457
|
networks;
|
|
459
458
|
assets;
|
|
459
|
+
// undefined = allowlist check disabled (backward-compatible default).
|
|
460
|
+
// Non-null = active allowlist; reject any recipient not in the set.
|
|
461
|
+
recipientAllowlist;
|
|
460
462
|
constructor(opts = {}) {
|
|
461
463
|
this.signer = opts.signer;
|
|
462
464
|
this.maxPerQuery = opts.maxPerQuery !== void 0 ? Number(opts.maxPerQuery) : void 0;
|
|
463
465
|
this.networks = new Set(opts.networks ?? ["base", "base-sepolia"]);
|
|
464
466
|
this.assets = new Set(opts.assets ?? ["USDC"]);
|
|
467
|
+
if (opts.recipientAllowlist !== void 0) {
|
|
468
|
+
this.recipientAllowlist = opts.recipientAllowlist.length === 0 ? void 0 : new Set(opts.recipientAllowlist.map((a) => a.toLowerCase()));
|
|
469
|
+
} else {
|
|
470
|
+
this.recipientAllowlist = void 0;
|
|
471
|
+
}
|
|
465
472
|
}
|
|
466
473
|
/**
|
|
467
474
|
* Validate the envelope against this client's policy and, if a signer
|
|
@@ -487,6 +494,15 @@ var X402Client = class {
|
|
|
487
494
|
);
|
|
488
495
|
}
|
|
489
496
|
}
|
|
497
|
+
if (this.recipientAllowlist !== void 0) {
|
|
498
|
+
const recipientNorm = (envelope.recipient ?? "").toLowerCase();
|
|
499
|
+
if (!recipientNorm || !this.recipientAllowlist.has(recipientNorm)) {
|
|
500
|
+
throw new AlterError(
|
|
501
|
+
"PAYMENT_REQUIRED",
|
|
502
|
+
`recipient "${envelope.recipient}" is not on the known-recipient allowlist`
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
490
506
|
if (!this.signer) {
|
|
491
507
|
throw new AlterPaymentRequired(envelope.resource ?? "unknown", envelope);
|
|
492
508
|
}
|
|
@@ -544,6 +560,7 @@ var MCPClient = class {
|
|
|
544
560
|
clientInfo;
|
|
545
561
|
x402;
|
|
546
562
|
signing;
|
|
563
|
+
extraHeaders;
|
|
547
564
|
requestCounter = 0;
|
|
548
565
|
initialised = false;
|
|
549
566
|
constructor(opts = {}) {
|
|
@@ -555,6 +572,7 @@ var MCPClient = class {
|
|
|
555
572
|
this.clientInfo = opts.clientInfo ?? { name: "@truealter/sdk", version: "0.2.0" };
|
|
556
573
|
this.x402 = opts.x402;
|
|
557
574
|
this.signing = opts.signing;
|
|
575
|
+
this.extraHeaders = opts.extraHeaders;
|
|
558
576
|
}
|
|
559
577
|
/**
|
|
560
578
|
* Send the MCP `initialize` handshake and capture the resulting session
|
|
@@ -718,6 +736,7 @@ var MCPClient = class {
|
|
|
718
736
|
}
|
|
719
737
|
buildHeaders(extra) {
|
|
720
738
|
const headers = {
|
|
739
|
+
...this.extraHeaders ?? {},
|
|
721
740
|
"Content-Type": "application/json",
|
|
722
741
|
Accept: "application/json",
|
|
723
742
|
"User-Agent": `${this.clientInfo.name}/${this.clientInfo.version}`
|
|
@@ -864,6 +883,7 @@ var DEFAULT_VERIFY_AT_ALLOWLIST = Object.freeze([
|
|
|
864
883
|
"api.truealter.com",
|
|
865
884
|
"mcp.truealter.com"
|
|
866
885
|
]);
|
|
886
|
+
var ALTER_PLATFORM_ISS = "did:alter:platform";
|
|
867
887
|
async function verifyProvenance(envelope, opts = {}) {
|
|
868
888
|
const token = typeof envelope === "string" ? envelope : envelope.token;
|
|
869
889
|
if (!token) return { valid: false, reason: "empty token" };
|
|
@@ -946,9 +966,55 @@ async function verifyProvenance(envelope, opts = {}) {
|
|
|
946
966
|
if (typeof payload.iat === "number" && payload.iat > now + 300) {
|
|
947
967
|
return { valid: false, reason: "issued in the future", payload, kid: header.kid };
|
|
948
968
|
}
|
|
969
|
+
const expectedIss = opts.expectedIss !== void 0 ? opts.expectedIss : ALTER_PLATFORM_ISS;
|
|
970
|
+
if (expectedIss !== "" && payload.iss !== expectedIss) {
|
|
971
|
+
return {
|
|
972
|
+
valid: false,
|
|
973
|
+
reason: `iss mismatch: expected "${expectedIss}", got "${payload.iss}"`,
|
|
974
|
+
payload,
|
|
975
|
+
kid: header.kid
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
if (opts.expectedAud !== void 0 && opts.expectedAud !== "") {
|
|
979
|
+
const tokenAud = payload.aud;
|
|
980
|
+
const audList = tokenAud === void 0 ? [] : Array.isArray(tokenAud) ? tokenAud : [tokenAud];
|
|
981
|
+
if (!audList.includes(opts.expectedAud)) {
|
|
982
|
+
return {
|
|
983
|
+
valid: false,
|
|
984
|
+
reason: `aud mismatch: expected "${opts.expectedAud}", got ${JSON.stringify(tokenAud ?? null)}`,
|
|
985
|
+
payload,
|
|
986
|
+
kid: header.kid
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
}
|
|
949
990
|
return { valid: true, payload, kid: header.kid };
|
|
950
991
|
}
|
|
951
|
-
async function verifyToolSignatures(tools, signatures) {
|
|
992
|
+
async function verifyToolSignatures(tools, signatures, opts = {}) {
|
|
993
|
+
const jwksUrl = opts.jwksUrl ?? "https://api.truealter.com/.well-known/alter-keys.json";
|
|
994
|
+
const fetchImpl = opts.fetch ?? fetch;
|
|
995
|
+
if (!jwksUrl.startsWith("https://")) {
|
|
996
|
+
return tools.map((t) => ({
|
|
997
|
+
tool: t.name,
|
|
998
|
+
valid: false,
|
|
999
|
+
reason: `jwksUrl must be https: got ${jwksUrl}`
|
|
1000
|
+
}));
|
|
1001
|
+
}
|
|
1002
|
+
const needsJwks = tools.some((t) => {
|
|
1003
|
+
const sig = signatures[t.name];
|
|
1004
|
+
return sig && sig.signature;
|
|
1005
|
+
});
|
|
1006
|
+
let jwks = null;
|
|
1007
|
+
if (needsJwks) {
|
|
1008
|
+
try {
|
|
1009
|
+
jwks = await fetchJwks(jwksUrl, fetchImpl);
|
|
1010
|
+
} catch (err) {
|
|
1011
|
+
return tools.map((t) => ({
|
|
1012
|
+
tool: t.name,
|
|
1013
|
+
valid: false,
|
|
1014
|
+
reason: `jwks fetch failed: ${err.message}`
|
|
1015
|
+
}));
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
952
1018
|
const out = [];
|
|
953
1019
|
for (const tool of tools) {
|
|
954
1020
|
const sig = signatures[tool.name];
|
|
@@ -961,6 +1027,63 @@ async function verifyToolSignatures(tools, signatures) {
|
|
|
961
1027
|
out.push({ tool: tool.name, valid: false, reason: "schema hash mismatch" });
|
|
962
1028
|
continue;
|
|
963
1029
|
}
|
|
1030
|
+
const jwsToken = sig.signature;
|
|
1031
|
+
if (!jwsToken) {
|
|
1032
|
+
out.push({ tool: tool.name, valid: true, warn_no_signature: true });
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
const jwksDoc = jwks;
|
|
1036
|
+
let jHeader;
|
|
1037
|
+
let jPayloadRaw;
|
|
1038
|
+
let jSigBytes;
|
|
1039
|
+
try {
|
|
1040
|
+
const parts2 = jwsToken.split(".");
|
|
1041
|
+
if (parts2.length !== 3) throw new Error("JWS must have three segments");
|
|
1042
|
+
jHeader = JSON.parse(new TextDecoder().decode(base64urlDecode(parts2[0])));
|
|
1043
|
+
jPayloadRaw = new TextDecoder().decode(base64urlDecode(parts2[1]));
|
|
1044
|
+
jSigBytes = base64urlDecode(parts2[2]);
|
|
1045
|
+
} catch (err) {
|
|
1046
|
+
out.push({ tool: tool.name, valid: false, reason: `malformed tool JWS: ${err.message}` });
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
if (jHeader.alg !== "ES256") {
|
|
1050
|
+
out.push({ tool: tool.name, valid: false, reason: `unsupported tool sig alg: ${jHeader.alg}` });
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
if (jPayloadRaw !== sig.schema_hash) {
|
|
1054
|
+
out.push({ tool: tool.name, valid: false, reason: "tool JWS payload does not match schema_hash" });
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
const jwk = jwksDoc.keys.find((k) => jHeader.kid ? k.kid === jHeader.kid : true);
|
|
1058
|
+
if (!jwk) {
|
|
1059
|
+
out.push({ tool: tool.name, valid: false, reason: `no JWK for kid=${jHeader.kid}` });
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
1062
|
+
let publicKey;
|
|
1063
|
+
try {
|
|
1064
|
+
publicKey = await importEs256JwkAsPublicKey(jwk);
|
|
1065
|
+
} catch (err) {
|
|
1066
|
+
out.push({ tool: tool.name, valid: false, reason: `jwk import: ${err.message}` });
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
const parts = jwsToken.split(".");
|
|
1070
|
+
const signedInput = new TextEncoder().encode(`${parts[0]}.${parts[1]}`);
|
|
1071
|
+
let sigValid = false;
|
|
1072
|
+
try {
|
|
1073
|
+
sigValid = await crypto.subtle.verify(
|
|
1074
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
1075
|
+
publicKey,
|
|
1076
|
+
toArrayBuffer(jSigBytes),
|
|
1077
|
+
toArrayBuffer(signedInput)
|
|
1078
|
+
);
|
|
1079
|
+
} catch (err) {
|
|
1080
|
+
out.push({ tool: tool.name, valid: false, reason: `sig verify error: ${err.message}` });
|
|
1081
|
+
continue;
|
|
1082
|
+
}
|
|
1083
|
+
if (!sigValid) {
|
|
1084
|
+
out.push({ tool: tool.name, valid: false, reason: "tool signature mismatch" });
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
964
1087
|
out.push({ tool: tool.name, valid: true });
|
|
965
1088
|
}
|
|
966
1089
|
return out;
|
|
@@ -1142,10 +1265,10 @@ var AlterClient = class {
|
|
|
1142
1265
|
}
|
|
1143
1266
|
/** Verify a person is registered with ALTER (handle or id). */
|
|
1144
1267
|
async verify(handleOrId, claims) {
|
|
1145
|
-
const args = handleOrId.includes("@") ? {
|
|
1146
|
-
// ~handle — server resolves these via the
|
|
1147
|
-
{
|
|
1148
|
-
) : {
|
|
1268
|
+
const args = handleOrId.includes("@") ? { member_id: "", email: handleOrId } : handleOrId.startsWith("~") ? (
|
|
1269
|
+
// ~handle — server resolves these via the member_id field
|
|
1270
|
+
{ member_id: handleOrId }
|
|
1271
|
+
) : { member_id: handleOrId };
|
|
1149
1272
|
if (claims) args.claims = claims;
|
|
1150
1273
|
return this.mcp.callTool("verify_identity", args);
|
|
1151
1274
|
}
|
|
@@ -1620,6 +1743,26 @@ function restoreFromBackup(path, backupPath) {
|
|
|
1620
1743
|
// src/wire/index.ts
|
|
1621
1744
|
var TIMESTAMP = () => String(Math.floor(Date.now() / 1e3));
|
|
1622
1745
|
var ISO_NOW = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
1746
|
+
function readCfAccessEnv() {
|
|
1747
|
+
const envPath = path.join(os.homedir(), ".config", "alter", "cf-access.env");
|
|
1748
|
+
try {
|
|
1749
|
+
const content = fs.readFileSync(envPath, "utf8");
|
|
1750
|
+
let clientId = "";
|
|
1751
|
+
let clientSecret = "";
|
|
1752
|
+
for (const line of content.split("\n")) {
|
|
1753
|
+
const trimmed = line.trim();
|
|
1754
|
+
if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
1755
|
+
const eqIdx = trimmed.indexOf("=");
|
|
1756
|
+
const key = trimmed.slice(0, eqIdx).replace(/^export\s+/, "").trim();
|
|
1757
|
+
const val = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
|
|
1758
|
+
if (key === "CF_ACCESS_CLIENT_ID") clientId = val;
|
|
1759
|
+
if (key === "CF_ACCESS_CLIENT_SECRET") clientSecret = val;
|
|
1760
|
+
}
|
|
1761
|
+
if (clientId && clientSecret) return { clientId, clientSecret };
|
|
1762
|
+
} catch {
|
|
1763
|
+
}
|
|
1764
|
+
return void 0;
|
|
1765
|
+
}
|
|
1623
1766
|
function clientById(id) {
|
|
1624
1767
|
const hit = ALL_CLIENTS.find((c) => c.id === id);
|
|
1625
1768
|
if (!hit) throw new Error(`unknown client id: ${id}`);
|
|
@@ -1628,6 +1771,7 @@ function clientById(id) {
|
|
|
1628
1771
|
function wire(opts = {}) {
|
|
1629
1772
|
const endpoint = opts.endpoint ?? DEFAULT_ENDPOINT;
|
|
1630
1773
|
const apiKey = opts.apiKey;
|
|
1774
|
+
const cfAccess = opts.cfAccess ?? readCfAccessEnv();
|
|
1631
1775
|
const probes = probeAll();
|
|
1632
1776
|
const selection = opts.only ?? probes.filter((p) => p.installed).map((p) => p.client.id);
|
|
1633
1777
|
const ts = TIMESTAMP();
|
|
@@ -1646,9 +1790,9 @@ function wire(opts = {}) {
|
|
|
1646
1790
|
}
|
|
1647
1791
|
try {
|
|
1648
1792
|
if (id === "claude-code") {
|
|
1649
|
-
targets.push(wireClaudeCode({ endpoint, apiKey }));
|
|
1793
|
+
targets.push(wireClaudeCode({ endpoint, apiKey, cfAccess }));
|
|
1650
1794
|
} else {
|
|
1651
|
-
targets.push(wireFileTarget({ id, endpoint, apiKey, timestamp: ts }));
|
|
1795
|
+
targets.push(wireFileTarget({ id, endpoint, apiKey, cfAccess, timestamp: ts }));
|
|
1652
1796
|
}
|
|
1653
1797
|
} catch (err) {
|
|
1654
1798
|
const message = err.message;
|
|
@@ -1682,7 +1826,12 @@ function wireFileTarget(args) {
|
|
|
1682
1826
|
`refusing to wire ${client.label}: config path ${sync.resolvedPath} lives under ${sync.matchedPrefix}. Synced volumes propagate credentials across devices \u2014 move the config off the sync root, or run wire on the device you want to target.`
|
|
1683
1827
|
);
|
|
1684
1828
|
}
|
|
1685
|
-
const
|
|
1829
|
+
const cfHeaders = {};
|
|
1830
|
+
if (args.cfAccess) {
|
|
1831
|
+
cfHeaders["CF-Access-Client-Id"] = args.cfAccess.clientId;
|
|
1832
|
+
cfHeaders["CF-Access-Client-Secret"] = args.cfAccess.clientSecret;
|
|
1833
|
+
}
|
|
1834
|
+
const entry = args.id === "claude-desktop" ? generateClaudeDesktopConfig({ endpoint: args.endpoint, apiKey: args.apiKey }) : generateGenericMcpConfig({ endpoint: args.endpoint, apiKey: args.apiKey, headers: cfHeaders });
|
|
1686
1835
|
const rootKey = client.rootKey;
|
|
1687
1836
|
const serverName = "alter";
|
|
1688
1837
|
const result = atomicJsonMerge({
|
|
@@ -1714,7 +1863,8 @@ function wireFileTarget(args) {
|
|
|
1714
1863
|
}
|
|
1715
1864
|
function wireClaudeCode(args) {
|
|
1716
1865
|
const cmd = "claude";
|
|
1717
|
-
const
|
|
1866
|
+
const bridgePath = resolveBridgeScript();
|
|
1867
|
+
const argList = bridgePath ? ["mcp", "add", "--scope", "user", "alter", "--", "node", bridgePath] : [
|
|
1718
1868
|
"mcp",
|
|
1719
1869
|
"add",
|
|
1720
1870
|
"--scope",
|
|
@@ -1722,16 +1872,15 @@ function wireClaudeCode(args) {
|
|
|
1722
1872
|
"--transport",
|
|
1723
1873
|
"http",
|
|
1724
1874
|
"alter",
|
|
1725
|
-
args.endpoint
|
|
1875
|
+
args.endpoint,
|
|
1876
|
+
...args.apiKey ? ["--header", `X-ALTER-API-Key:${args.apiKey}`] : []
|
|
1726
1877
|
];
|
|
1727
|
-
if (args.apiKey) {
|
|
1728
|
-
argList.push("--header", `X-ALTER-API-Key:${args.apiKey}`);
|
|
1729
|
-
}
|
|
1730
1878
|
const full = `${cmd} ${argList.join(" ")}`;
|
|
1731
1879
|
const run = child_process.spawnSync(cmd, argList, {
|
|
1732
1880
|
encoding: "utf8",
|
|
1733
1881
|
shell: process.platform === "win32",
|
|
1734
|
-
timeout: 1e4
|
|
1882
|
+
timeout: 1e4,
|
|
1883
|
+
env: bridgePath ? { ...process.env, ALTER_PUBLIC_MCP_ENDPOINT: args.endpoint, ...args.apiKey ? { ALTER_API_KEY: args.apiKey } : {} } : void 0
|
|
1735
1884
|
});
|
|
1736
1885
|
if (run.error) {
|
|
1737
1886
|
return {
|
|
@@ -1762,6 +1911,17 @@ function wireClaudeCode(args) {
|
|
|
1762
1911
|
reason: `claude mcp add exited ${String(run.status)}`
|
|
1763
1912
|
};
|
|
1764
1913
|
}
|
|
1914
|
+
function resolveBridgeScript() {
|
|
1915
|
+
const { existsSync: existsSync4 } = __require("fs");
|
|
1916
|
+
const { join: join3, dirname: dirname3 } = __require("path");
|
|
1917
|
+
const siblingBridge = join3(dirname3(__filename), "..", "dist", "mcp-bridge.js");
|
|
1918
|
+
if (existsSync4(siblingBridge)) return siblingBridge;
|
|
1919
|
+
const srcBridge = join3(dirname3(__filename), "..", "mcp-bridge.js");
|
|
1920
|
+
if (existsSync4(srcBridge)) return srcBridge;
|
|
1921
|
+
const npmGlobalBridge = join3(dirname3(__filename), "mcp-bridge.js");
|
|
1922
|
+
if (existsSync4(npmGlobalBridge)) return npmGlobalBridge;
|
|
1923
|
+
return null;
|
|
1924
|
+
}
|
|
1765
1925
|
function unwire() {
|
|
1766
1926
|
const state = readWireState();
|
|
1767
1927
|
const undone = [];
|
|
@@ -1965,6 +2125,26 @@ var TOOL_BLAST_RADIUS = {
|
|
|
1965
2125
|
query_graph_similarity: "high"
|
|
1966
2126
|
};
|
|
1967
2127
|
|
|
2128
|
+
// src/homepage.ts
|
|
2129
|
+
init_cjs_shims();
|
|
2130
|
+
var HOMEPAGE_LIMITS = {
|
|
2131
|
+
whoami_max_chars: 240,
|
|
2132
|
+
opener_max_chars: 280,
|
|
2133
|
+
pronouns_max_chars: 32,
|
|
2134
|
+
attunement_glyph_max_chars: 16
|
|
2135
|
+
};
|
|
2136
|
+
|
|
2137
|
+
// src/themes.ts
|
|
2138
|
+
init_cjs_shims();
|
|
2139
|
+
var THEME_LIMITS = {
|
|
2140
|
+
meta_name_pattern: /^[a-z][a-z0-9-]{0,63}$/,
|
|
2141
|
+
meta_description_max_chars: 240,
|
|
2142
|
+
opener_library_max_entries: 32,
|
|
2143
|
+
opener_entry_max_chars: 240,
|
|
2144
|
+
share_note_max_chars: 280
|
|
2145
|
+
};
|
|
2146
|
+
var OSC8_ALLOWED_SCHEMES = ["https:", "mailto:"];
|
|
2147
|
+
|
|
1968
2148
|
exports.ALL_CLIENTS = ALL_CLIENTS;
|
|
1969
2149
|
exports.AlterAuthError = AlterAuthError;
|
|
1970
2150
|
exports.AlterClient = AlterClient;
|
|
@@ -1984,11 +2164,14 @@ exports.DEFAULT_DOMAIN = DEFAULT_DOMAIN;
|
|
|
1984
2164
|
exports.DEFAULT_ENDPOINT = DEFAULT_ENDPOINT;
|
|
1985
2165
|
exports.DEFAULT_VERIFY_AT_ALLOWLIST = DEFAULT_VERIFY_AT_ALLOWLIST;
|
|
1986
2166
|
exports.FREE_TOOL_NAMES = FREE_TOOL_NAMES;
|
|
2167
|
+
exports.HOMEPAGE_LIMITS = HOMEPAGE_LIMITS;
|
|
1987
2168
|
exports.MCPClient = MCPClient;
|
|
1988
2169
|
exports.MCP_PROTOCOL_VERSION = MCP_PROTOCOL_VERSION;
|
|
2170
|
+
exports.OSC8_ALLOWED_SCHEMES = OSC8_ALLOWED_SCHEMES;
|
|
1989
2171
|
exports.PREMIUM_TOOL_NAMES = PREMIUM_TOOL_NAMES;
|
|
1990
2172
|
exports.SDK_NAME = SDK_NAME;
|
|
1991
2173
|
exports.SDK_VERSION = SDK_VERSION;
|
|
2174
|
+
exports.THEME_LIMITS = THEME_LIMITS;
|
|
1992
2175
|
exports.TOOL_BLAST_RADIUS = TOOL_BLAST_RADIUS;
|
|
1993
2176
|
exports.TOOL_COSTS = TOOL_COSTS;
|
|
1994
2177
|
exports.TOOL_TIERS = TOOL_TIERS;
|