@lovable.dev/mcp-js 0.22.1 → 0.22.2-rc.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/dist/authorize-CumVyk7p.d.cts +27 -0
- package/dist/authorize-D6p4-9_D.d.ts +27 -0
- package/dist/base-DCe0kP79.d.cts +29 -0
- package/dist/base-DCe0kP79.d.ts +29 -0
- package/dist/cli/extract-manifest.cjs +116 -201
- package/dist/cli/extract-manifest.d.cts +1 -1
- package/dist/cli/extract-manifest.d.ts +1 -1
- package/dist/cli/extract-manifest.js +117 -156
- package/dist/content-D5LJAHyM.js +12 -0
- package/dist/content-NCYIGgOb.cjs +17 -0
- package/dist/context-BweeEcoA.cjs +56 -0
- package/dist/context-CIpPzN7P.js +51 -0
- package/dist/cors-C2n2LxrC.js +830 -0
- package/dist/cors-Cga2PWEg.cjs +913 -0
- package/dist/forwarded--h4efJy-.js +43 -0
- package/dist/forwarded-Pi8Hs5Ps.cjs +48 -0
- package/dist/fs-errors-CWNzOV75.cjs +11 -0
- package/dist/fs-errors-PA2t1TIp.js +6 -0
- package/dist/index.cjs +129 -329
- package/dist/index.d.cts +26 -26
- package/dist/index.d.ts +26 -26
- package/dist/index.js +118 -177
- package/dist/{io-D4srzRKc.d.ts → io-CfSPxeBN.d.ts} +6 -4
- package/dist/io-DPYvBqET.d.cts +15 -0
- package/dist/list-tools-07OV14rK.cjs +57 -0
- package/dist/list-tools-B4TTPEl1.d.cts +8 -0
- package/dist/list-tools-I8Hvub9P.js +46 -0
- package/dist/list-tools-bh6-eqZM.d.ts +8 -0
- package/dist/logger-2OXtfiIW.js +141 -0
- package/dist/logger-BqPOa_E1.cjs +194 -0
- package/dist/mcp-B6z5Givq.js +123 -0
- package/dist/mcp-DLv_c1O5.cjs +128 -0
- package/dist/metadata-path-CAkNcfyY.js +12 -0
- package/dist/metadata-path-zd7NSNoa.cjs +17 -0
- package/dist/package-CxQcGWdU.cjs +9 -0
- package/dist/package-xS6mk-b_.js +4 -0
- package/dist/paths-IS65L6TA.js +7 -0
- package/dist/paths-OP318a6c.cjs +18 -0
- package/dist/protocols/mcp/index.cjs +3 -750
- package/dist/protocols/mcp/index.d.cts +6 -7
- package/dist/protocols/mcp/index.d.ts +6 -7
- package/dist/protocols/mcp/index.js +2 -12
- package/dist/protocols/oauth-metadata.cjs +48 -539
- package/dist/protocols/oauth-metadata.d.cts +5 -6
- package/dist/protocols/oauth-metadata.d.ts +5 -6
- package/dist/protocols/oauth-metadata.js +52 -10
- package/dist/protocols/rest/index.cjs +5 -843
- package/dist/protocols/rest/index.d.cts +7 -10
- package/dist/protocols/rest/index.d.ts +7 -10
- package/dist/protocols/rest/index.js +3 -16
- package/dist/rest-CggWx00c.js +117 -0
- package/dist/rest-DxhK7-3b.cjs +122 -0
- package/dist/stacks/supabase/index.cjs +76 -1318
- package/dist/stacks/supabase/index.d.cts +29 -30
- package/dist/stacks/supabase/index.d.ts +29 -30
- package/dist/stacks/supabase/index.js +73 -89
- package/dist/stacks/supabase/vite.cjs +258 -287
- package/dist/stacks/supabase/vite.d.cts +24 -24
- package/dist/stacks/supabase/vite.d.ts +24 -24
- package/dist/stacks/supabase/vite.js +252 -252
- package/dist/stacks/tanstack/index.cjs +42 -1272
- package/dist/stacks/tanstack/index.d.cts +8 -9
- package/dist/stacks/tanstack/index.d.ts +8 -9
- package/dist/stacks/tanstack/index.js +36 -41
- package/dist/stacks/tanstack/vite.cjs +223 -312
- package/dist/stacks/tanstack/vite.d.cts +80 -81
- package/dist/stacks/tanstack/vite.d.ts +80 -81
- package/dist/stacks/tanstack/vite.js +216 -282
- package/dist/types-BYdYYTjk.d.cts +321 -0
- package/dist/types-BYdYYTjk.d.ts +321 -0
- package/package.json +4 -4
- package/dist/authorize-BMeXd_Sh.d.ts +0 -25
- package/dist/base-CM-KCpp6.d.ts +0 -28
- package/dist/chunk-5HVSJCKE.js +0 -114
- package/dist/chunk-6DXGZZA4.js +0 -6
- package/dist/chunk-6QFZYYUV.js +0 -11
- package/dist/chunk-6SZOFKGH.js +0 -58
- package/dist/chunk-H37EB22A.js +0 -125
- package/dist/chunk-IFDWUM7L.js +0 -741
- package/dist/chunk-IXZIFYO6.js +0 -79
- package/dist/chunk-MA5H6PSF.js +0 -46
- package/dist/chunk-TJN33K5U.js +0 -141
- package/dist/chunk-UQK5UO6C.js +0 -26
- package/dist/chunk-XQWJN6DC.js +0 -14
- package/dist/chunk-Y3ZFPEQH.js +0 -8
- package/dist/chunk-ZQXSWTPU.js +0 -6
- package/dist/types-qqrmJ736.d.ts +0 -321
|
@@ -1,174 +1,135 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from "../
|
|
5
|
-
import "
|
|
6
|
-
import "
|
|
7
|
-
import "
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
} from "../chunk-Y3ZFPEQH.js";
|
|
11
|
-
import {
|
|
12
|
-
version
|
|
13
|
-
} from "../chunk-ZQXSWTPU.js";
|
|
14
|
-
|
|
15
|
-
// src/manifest/io.ts
|
|
16
|
-
import { randomUUID } from "crypto";
|
|
17
|
-
import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
18
|
-
import { dirname, resolve } from "path";
|
|
19
|
-
import { resolveConfig } from "vite";
|
|
20
|
-
|
|
21
|
-
// src/manifest/extract.ts
|
|
22
|
-
var MANIFEST_VERSION = 1;
|
|
23
|
-
var MANIFEST_RELATIVE_PATH = ".lovable/mcp/manifest.json";
|
|
2
|
+
import { t as version } from "../package-xS6mk-b_.js";
|
|
3
|
+
import { t as buildMcpListing } from "../list-tools-I8Hvub9P.js";
|
|
4
|
+
import { t as isFileMissing } from "../fs-errors-PA2t1TIp.js";
|
|
5
|
+
import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, resolve } from "node:path";
|
|
7
|
+
import { createServer, resolveConfig } from "vite";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
const MANIFEST_RELATIVE_PATH = ".lovable/mcp/manifest.json";
|
|
24
10
|
function manifestAuth(auth) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (auth.requiredScopes !== void 0)
|
|
43
|
-
oauth.required_scopes = auth.requiredScopes;
|
|
44
|
-
if (auth.jwksUri !== void 0)
|
|
45
|
-
oauth.jwks_uri = auth.jwksUri;
|
|
46
|
-
if (auth.algorithms !== void 0)
|
|
47
|
-
oauth.algorithms = auth.algorithms;
|
|
48
|
-
if (auth.clockToleranceSeconds !== void 0)
|
|
49
|
-
oauth.clock_tolerance_seconds = auth.clockToleranceSeconds;
|
|
50
|
-
return oauth;
|
|
11
|
+
if (!auth) return { type: "none" };
|
|
12
|
+
const oauth = {
|
|
13
|
+
type: "oauth",
|
|
14
|
+
issuer: auth.issuer
|
|
15
|
+
};
|
|
16
|
+
if (auth.resource !== void 0) oauth.resource = auth.resource;
|
|
17
|
+
if (auth.resourceName !== void 0) oauth.resource_name = auth.resourceName;
|
|
18
|
+
if (auth.resourceDocumentation !== void 0) oauth.resource_documentation = auth.resourceDocumentation;
|
|
19
|
+
if (auth.protectedResourceMetadataUrl !== void 0) oauth.protected_resource_metadata_url = auth.protectedResourceMetadataUrl;
|
|
20
|
+
if (auth.requireOAuthClientClaim !== void 0) oauth.require_oauth_client_claim = auth.requireOAuthClientClaim;
|
|
21
|
+
if (auth.acceptResourceClaim !== void 0) oauth.accept_resource_claim = auth.acceptResourceClaim;
|
|
22
|
+
if (auth.acceptedAudiences !== void 0) oauth.accepted_audiences = auth.acceptedAudiences;
|
|
23
|
+
if (auth.requiredScopes !== void 0) oauth.required_scopes = auth.requiredScopes;
|
|
24
|
+
if (auth.jwksUri !== void 0) oauth.jwks_uri = auth.jwksUri;
|
|
25
|
+
if (auth.algorithms !== void 0) oauth.algorithms = auth.algorithms;
|
|
26
|
+
if (auth.clockToleranceSeconds !== void 0) oauth.clock_tolerance_seconds = auth.clockToleranceSeconds;
|
|
27
|
+
return oauth;
|
|
51
28
|
}
|
|
52
29
|
function isToolShape(tool) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return typeof t.name === "string" && typeof t.title === "string" && typeof t.description === "string";
|
|
30
|
+
if (typeof tool !== "object" || tool === null) return false;
|
|
31
|
+
const t = tool;
|
|
32
|
+
return typeof t.name === "string" && typeof t.title === "string" && typeof t.description === "string";
|
|
57
33
|
}
|
|
58
34
|
function isAuthShape(auth) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const a = auth;
|
|
64
|
-
return a.type === "oauth" && typeof a.issuer === "string" && a.issuer.length > 0;
|
|
35
|
+
if (auth === void 0) return true;
|
|
36
|
+
if (typeof auth !== "object" || auth === null) return false;
|
|
37
|
+
const a = auth;
|
|
38
|
+
return a.type === "oauth" && typeof a.issuer === "string" && a.issuer.length > 0;
|
|
65
39
|
}
|
|
66
40
|
function manifestFromDefinition(definition, urlPath, source = "the MCP entry") {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
path: urlPath,
|
|
77
|
-
auth: manifestAuth(def.auth),
|
|
78
|
-
mcp: buildMcpListing(def)
|
|
79
|
-
};
|
|
41
|
+
const def = definition;
|
|
42
|
+
if (!(!!def && typeof def === "object" && typeof def.name === "string" && typeof def.title === "string" && typeof def.version === "string" && Array.isArray(def.tools) && def.tools.every(isToolShape) && isAuthShape(def.auth))) throw new Error(`@lovable.dev/mcp-js: ${source} must \`export default defineMcp(...)\` (got ${definition == null ? "no default export" : typeof definition}).`);
|
|
43
|
+
return {
|
|
44
|
+
version: 1,
|
|
45
|
+
sdk_version: version,
|
|
46
|
+
path: urlPath,
|
|
47
|
+
auth: manifestAuth(def.auth),
|
|
48
|
+
mcp: buildMcpListing(def)
|
|
49
|
+
};
|
|
80
50
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/manifest/ssr-loader.ts
|
|
53
|
+
async function produceViaSsr(projectRoot, alias, entryAbs, urlPath) {
|
|
54
|
+
const server = await createServer({
|
|
55
|
+
configFile: false,
|
|
56
|
+
root: projectRoot,
|
|
57
|
+
logLevel: "silent",
|
|
58
|
+
server: {
|
|
59
|
+
middlewareMode: true,
|
|
60
|
+
hmr: false,
|
|
61
|
+
watch: null
|
|
62
|
+
},
|
|
63
|
+
optimizeDeps: { noDiscovery: true },
|
|
64
|
+
resolve: { alias }
|
|
65
|
+
});
|
|
66
|
+
try {
|
|
67
|
+
return manifestFromDefinition((await server.ssrLoadModule(entryAbs)).default, urlPath, entryAbs);
|
|
68
|
+
} finally {
|
|
69
|
+
await server.close();
|
|
70
|
+
}
|
|
99
71
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
var DEFAULT_MCP_ENTRY = "src/lib/mcp/index.ts";
|
|
104
|
-
var DEFAULT_MCP_PATH = "/mcp";
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/manifest/io.ts
|
|
74
|
+
const MCP_PLUGIN_NAME_PREFIX = "@lovable.dev/mcp-js";
|
|
105
75
|
function writeManifestIfChanged(file, manifest) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
76
|
+
const content = JSON.stringify(manifest, null, 2) + "\n";
|
|
77
|
+
let existing;
|
|
78
|
+
try {
|
|
79
|
+
existing = readFileSync(file, "utf8");
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (!isFileMissing(err)) throw err;
|
|
82
|
+
}
|
|
83
|
+
if (existing === content) return;
|
|
84
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
85
|
+
const tmp = `${file}.${randomUUID()}.tmp`;
|
|
86
|
+
try {
|
|
87
|
+
writeFileSync(tmp, content, "utf8");
|
|
88
|
+
renameSync(tmp, file);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
try {
|
|
91
|
+
unlinkSync(tmp);
|
|
92
|
+
} catch {}
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
128
95
|
}
|
|
129
96
|
function removeManifest(file) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
97
|
+
try {
|
|
98
|
+
unlinkSync(file);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (!isFileMissing(err)) throw err;
|
|
101
|
+
}
|
|
136
102
|
}
|
|
137
103
|
async function syncManifest(manifestFile, entryAbs, urlPath, produce) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const manifest = await produce(entryAbs, urlPath);
|
|
151
|
-
writeManifestIfChanged(manifestFile, manifest);
|
|
104
|
+
let entryExists = true;
|
|
105
|
+
try {
|
|
106
|
+
lstatSync(entryAbs);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (!isFileMissing(err)) throw err;
|
|
109
|
+
entryExists = false;
|
|
110
|
+
}
|
|
111
|
+
if (!entryExists) {
|
|
112
|
+
removeManifest(manifestFile);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
writeManifestIfChanged(manifestFile, await produce(entryAbs, urlPath));
|
|
152
116
|
}
|
|
153
|
-
async function runExtract(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
entryAbs,
|
|
164
|
-
urlPath,
|
|
165
|
-
(entry, path) => produceViaSsr(projectRoot2, alias, entry, path)
|
|
166
|
-
);
|
|
117
|
+
async function runExtract(projectRoot) {
|
|
118
|
+
const resolved = await resolveConfig({
|
|
119
|
+
root: projectRoot,
|
|
120
|
+
logLevel: "silent"
|
|
121
|
+
}, "serve");
|
|
122
|
+
const alias = resolved.resolve?.alias ?? [];
|
|
123
|
+
const pluginApi = resolved.plugins.find((p) => typeof p.name === "string" && p.name.startsWith(MCP_PLUGIN_NAME_PREFIX))?.api;
|
|
124
|
+
const entryAbs = pluginApi?.mcpEntry ?? resolve(projectRoot, "src/lib/mcp/index.ts");
|
|
125
|
+
const urlPath = pluginApi?.urlPath ?? "/mcp";
|
|
126
|
+
await syncManifest(resolve(projectRoot, MANIFEST_RELATIVE_PATH), entryAbs, urlPath, (entry, path) => produceViaSsr(projectRoot, alias, entry, path));
|
|
167
127
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
process.exit(1);
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/cli/extract-manifest.ts
|
|
130
|
+
runExtract(process.argv[2] ?? process.cwd()).catch((err) => {
|
|
131
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
132
|
+
process.exit(1);
|
|
174
133
|
});
|
|
134
|
+
//#endregion
|
|
135
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/core/content.ts
|
|
2
|
+
/** Join the text of a result's `type: "text"` blocks into one string, dropping
|
|
3
|
+
* binary/resource blocks. Used to surface a `tool_error` message in the local
|
|
4
|
+
* log; never sent over the telemetry wire. Returns undefined when there is no
|
|
5
|
+
* text to show. */
|
|
6
|
+
function extractTextContent(content) {
|
|
7
|
+
if (!content) return void 0;
|
|
8
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
9
|
+
return text.length > 0 ? text : void 0;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { extractTextContent as t };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/core/content.ts
|
|
2
|
+
/** Join the text of a result's `type: "text"` blocks into one string, dropping
|
|
3
|
+
* binary/resource blocks. Used to surface a `tool_error` message in the local
|
|
4
|
+
* log; never sent over the telemetry wire. Returns undefined when there is no
|
|
5
|
+
* text to show. */
|
|
6
|
+
function extractTextContent(content) {
|
|
7
|
+
if (!content) return void 0;
|
|
8
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
9
|
+
return text.length > 0 ? text : void 0;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
Object.defineProperty(exports, "extractTextContent", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function() {
|
|
15
|
+
return extractTextContent;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/auth/context.ts
|
|
2
|
+
/**
|
|
3
|
+
* The auth surface passed to every tool handler as its second argument. It wraps
|
|
4
|
+
* the verified per-request auth context in a private field, so the context — and
|
|
5
|
+
* the bearer token inside it — can't be read, enumerated, spread, or
|
|
6
|
+
* `JSON.stringify`'d off the instance; the accessors below are the only way out.
|
|
7
|
+
* `getToken()` is the single intentional escape hatch for the raw bearer.
|
|
8
|
+
*/
|
|
9
|
+
var ToolContext = class {
|
|
10
|
+
#auth;
|
|
11
|
+
constructor(auth) {
|
|
12
|
+
this.#auth = auth;
|
|
13
|
+
}
|
|
14
|
+
/** Whether the in-flight tool call carries a verified auth context. */
|
|
15
|
+
isAuthenticated() {
|
|
16
|
+
return this.#auth !== void 0;
|
|
17
|
+
}
|
|
18
|
+
/** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
|
|
19
|
+
getToken() {
|
|
20
|
+
return this.#auth?.bearer.token;
|
|
21
|
+
}
|
|
22
|
+
/** The verified user id (the token `sub`), or `undefined`. */
|
|
23
|
+
getUserId() {
|
|
24
|
+
return this.#auth?.principal.sub;
|
|
25
|
+
}
|
|
26
|
+
/** The verified user email, or `undefined` when absent. */
|
|
27
|
+
getUserEmail() {
|
|
28
|
+
return this.#auth?.principal.email;
|
|
29
|
+
}
|
|
30
|
+
/** The verified OAuth `client_id`, or `undefined`. */
|
|
31
|
+
getClientId() {
|
|
32
|
+
return this.#auth?.principal.clientId;
|
|
33
|
+
}
|
|
34
|
+
/** The verified OAuth scopes, or `undefined` when unauthenticated. */
|
|
35
|
+
getScopes() {
|
|
36
|
+
return this.#auth?.principal.scopes;
|
|
37
|
+
}
|
|
38
|
+
/** The verified token issuer, or `undefined`. */
|
|
39
|
+
getIssuer() {
|
|
40
|
+
return this.#auth?.principal.issuer;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The full verified JWT claims, or `undefined`. Use this for app/business
|
|
44
|
+
* authorization on issuer-specific claims that have no dedicated accessor.
|
|
45
|
+
*/
|
|
46
|
+
getClaims() {
|
|
47
|
+
return this.#auth?.principal.claims;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
Object.defineProperty(exports, "ToolContext", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function() {
|
|
54
|
+
return ToolContext;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/auth/context.ts
|
|
2
|
+
/**
|
|
3
|
+
* The auth surface passed to every tool handler as its second argument. It wraps
|
|
4
|
+
* the verified per-request auth context in a private field, so the context — and
|
|
5
|
+
* the bearer token inside it — can't be read, enumerated, spread, or
|
|
6
|
+
* `JSON.stringify`'d off the instance; the accessors below are the only way out.
|
|
7
|
+
* `getToken()` is the single intentional escape hatch for the raw bearer.
|
|
8
|
+
*/
|
|
9
|
+
var ToolContext = class {
|
|
10
|
+
#auth;
|
|
11
|
+
constructor(auth) {
|
|
12
|
+
this.#auth = auth;
|
|
13
|
+
}
|
|
14
|
+
/** Whether the in-flight tool call carries a verified auth context. */
|
|
15
|
+
isAuthenticated() {
|
|
16
|
+
return this.#auth !== void 0;
|
|
17
|
+
}
|
|
18
|
+
/** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
|
|
19
|
+
getToken() {
|
|
20
|
+
return this.#auth?.bearer.token;
|
|
21
|
+
}
|
|
22
|
+
/** The verified user id (the token `sub`), or `undefined`. */
|
|
23
|
+
getUserId() {
|
|
24
|
+
return this.#auth?.principal.sub;
|
|
25
|
+
}
|
|
26
|
+
/** The verified user email, or `undefined` when absent. */
|
|
27
|
+
getUserEmail() {
|
|
28
|
+
return this.#auth?.principal.email;
|
|
29
|
+
}
|
|
30
|
+
/** The verified OAuth `client_id`, or `undefined`. */
|
|
31
|
+
getClientId() {
|
|
32
|
+
return this.#auth?.principal.clientId;
|
|
33
|
+
}
|
|
34
|
+
/** The verified OAuth scopes, or `undefined` when unauthenticated. */
|
|
35
|
+
getScopes() {
|
|
36
|
+
return this.#auth?.principal.scopes;
|
|
37
|
+
}
|
|
38
|
+
/** The verified token issuer, or `undefined`. */
|
|
39
|
+
getIssuer() {
|
|
40
|
+
return this.#auth?.principal.issuer;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The full verified JWT claims, or `undefined`. Use this for app/business
|
|
44
|
+
* authorization on issuer-specific claims that have no dedicated accessor.
|
|
45
|
+
*/
|
|
46
|
+
getClaims() {
|
|
47
|
+
return this.#auth?.principal.claims;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { ToolContext as t };
|