@ainecto/mcp 0.1.3 → 0.1.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/README.md +6 -4
- package/dist/bin/ainecto.js +158 -36
- package/dist/bin/ainecto.js.map +1 -1
- package/dist/bin/mcp.js +130 -8
- package/dist/bin/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/mcp.js
CHANGED
|
@@ -18,9 +18,34 @@ function resolveEndpoint(input = {}) {
|
|
|
18
18
|
}
|
|
19
19
|
function normalizeEndpoint(endpoint) {
|
|
20
20
|
const url = new URL(endpoint);
|
|
21
|
+
assertTrustedEndpointUrl(url, "MCP endpoint");
|
|
21
22
|
url.hash = "";
|
|
22
23
|
return url.toString().replace(/\/$/, "");
|
|
23
24
|
}
|
|
25
|
+
function isDefaultEndpoint(endpoint) {
|
|
26
|
+
const normalized = normalizeEndpoint(endpoint);
|
|
27
|
+
return Object.values(DEFAULT_ENDPOINTS).includes(normalized);
|
|
28
|
+
}
|
|
29
|
+
function assertTrustedEndpointUrl(value, label = "URL") {
|
|
30
|
+
const url = typeof value === "string" ? new URL(value) : value;
|
|
31
|
+
if (url.protocol === "https:") {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (url.protocol === "http:" && isLoopbackHostname(url.hostname)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`${label} must use https, except http is allowed for localhost loopback endpoints.`);
|
|
38
|
+
}
|
|
39
|
+
function assertLoopbackRedirectUrl(value) {
|
|
40
|
+
const url = new URL(value);
|
|
41
|
+
if (url.protocol === "http:" && isLoopbackHostname(url.hostname)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
throw new Error("OAuth redirect URI must be an http localhost loopback URL.");
|
|
45
|
+
}
|
|
46
|
+
function isLoopbackHostname(hostname) {
|
|
47
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]";
|
|
48
|
+
}
|
|
24
49
|
function assertEnv(value) {
|
|
25
50
|
if (value === void 0) {
|
|
26
51
|
return void 0;
|
|
@@ -57,6 +82,7 @@ var FileTokenStore = class {
|
|
|
57
82
|
}
|
|
58
83
|
async readFile() {
|
|
59
84
|
try {
|
|
85
|
+
await this.hardenExistingPermissions();
|
|
60
86
|
const raw = await readFile(this.filePath, "utf8");
|
|
61
87
|
const parsed = JSON.parse(raw);
|
|
62
88
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -80,6 +106,11 @@ var FileTokenStore = class {
|
|
|
80
106
|
await rename(tmpPath, this.filePath);
|
|
81
107
|
await chmod(this.filePath, 384);
|
|
82
108
|
}
|
|
109
|
+
async hardenExistingPermissions() {
|
|
110
|
+
const dirPath = dirname(this.filePath);
|
|
111
|
+
await chmodIfPermissive(dirPath, 448);
|
|
112
|
+
await chmodIfPermissive(this.filePath, 384);
|
|
113
|
+
}
|
|
83
114
|
};
|
|
84
115
|
function tokenKey(endpoint) {
|
|
85
116
|
return createHash("sha256").update(endpoint).digest("hex");
|
|
@@ -87,6 +118,19 @@ function tokenKey(endpoint) {
|
|
|
87
118
|
function isNodeError(error, code) {
|
|
88
119
|
return error instanceof Error && "code" in error && error.code === code;
|
|
89
120
|
}
|
|
121
|
+
async function chmodIfPermissive(path, mode) {
|
|
122
|
+
try {
|
|
123
|
+
const result = await stat(path);
|
|
124
|
+
if ((result.mode & 63) !== 0) {
|
|
125
|
+
await chmod(path, mode);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
if (isNodeError(error, "ENOENT")) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
90
134
|
|
|
91
135
|
// src/core/auth/oauth.ts
|
|
92
136
|
import { createHash as createHash2, randomBytes } from "crypto";
|
|
@@ -96,6 +140,8 @@ import { URLSearchParams } from "url";
|
|
|
96
140
|
|
|
97
141
|
// src/core/auth/clientRegistration.ts
|
|
98
142
|
async function registerPublicClient(registrationEndpoint, redirectUri, fetchImpl = fetch) {
|
|
143
|
+
assertTrustedEndpointUrl(registrationEndpoint, "OAuth client registration endpoint");
|
|
144
|
+
assertLoopbackRedirectUrl(redirectUri);
|
|
99
145
|
const response = await fetchImpl(registrationEndpoint, {
|
|
100
146
|
method: "POST",
|
|
101
147
|
headers: { "content-type": "application/json", accept: "application/json" },
|
|
@@ -138,6 +184,7 @@ var OAuthClient = class {
|
|
|
138
184
|
async getAccessToken() {
|
|
139
185
|
const envToken = this.envVars.AINECTO_TOKEN;
|
|
140
186
|
if (envToken) {
|
|
187
|
+
assertEnvTokenEndpointAllowed(this.options.endpoint, this.envVars);
|
|
141
188
|
return envToken;
|
|
142
189
|
}
|
|
143
190
|
const stored = await this.options.tokenStore.load(this.options.endpoint);
|
|
@@ -171,6 +218,7 @@ var OAuthClient = class {
|
|
|
171
218
|
authorizeUrl.searchParams.set("code_challenge_method", "S256");
|
|
172
219
|
authorizeUrl.searchParams.set("resource", this.options.endpoint);
|
|
173
220
|
authorizeUrl.searchParams.set("state", state);
|
|
221
|
+
assertTrustedEndpointUrl(authorizeUrl, "OAuth authorization URL");
|
|
174
222
|
await this.openBrowserImpl(authorizeUrl.toString());
|
|
175
223
|
const code = await loopback.waitForCode();
|
|
176
224
|
const token = await exchangeToken(metadata.tokenEndpoint, {
|
|
@@ -224,18 +272,30 @@ function shouldRefresh(token, now = Date.now()) {
|
|
|
224
272
|
return token.expiresAt - now < 6e4;
|
|
225
273
|
}
|
|
226
274
|
async function discoverOAuthMetadata(endpoint, fetchImpl = fetch) {
|
|
275
|
+
assertTrustedEndpointUrl(endpoint, "MCP endpoint");
|
|
227
276
|
const resourceMetadataUrl = await discoverResourceMetadataUrl(endpoint, fetchImpl);
|
|
277
|
+
assertTrustedEndpointUrl(resourceMetadataUrl, "OAuth protected resource metadata URL");
|
|
228
278
|
const resourceMetadata = await fetchJson(resourceMetadataUrl, fetchImpl);
|
|
229
279
|
const authorizationServers = resourceMetadata.authorization_servers;
|
|
230
280
|
if (!Array.isArray(authorizationServers) || typeof authorizationServers[0] !== "string") {
|
|
231
281
|
throw new Error("OAuth protected resource metadata did not include authorization_servers.");
|
|
232
282
|
}
|
|
233
283
|
const authServer = authorizationServers[0];
|
|
284
|
+
assertTrustedEndpointUrl(authServer, "OAuth authorization server");
|
|
234
285
|
const metadataUrl = authServer.includes("/.well-known/") ? authServer : `${authServer.replace(/\/$/, "")}/.well-known/oauth-authorization-server`;
|
|
286
|
+
assertTrustedEndpointUrl(metadataUrl, "OAuth authorization server metadata URL");
|
|
235
287
|
const metadata = await fetchJson(metadataUrl, fetchImpl);
|
|
236
288
|
if (typeof metadata.authorization_endpoint !== "string" || typeof metadata.token_endpoint !== "string") {
|
|
237
289
|
throw new Error("OAuth authorization server metadata is missing authorization_endpoint or token_endpoint.");
|
|
238
290
|
}
|
|
291
|
+
assertTrustedEndpointUrl(metadata.authorization_endpoint, "OAuth authorization endpoint");
|
|
292
|
+
assertTrustedEndpointUrl(metadata.token_endpoint, "OAuth token endpoint");
|
|
293
|
+
if (typeof metadata.registration_endpoint === "string") {
|
|
294
|
+
assertTrustedEndpointUrl(metadata.registration_endpoint, "OAuth client registration endpoint");
|
|
295
|
+
}
|
|
296
|
+
if (typeof metadata.issuer === "string") {
|
|
297
|
+
assertTrustedEndpointUrl(metadata.issuer, "OAuth issuer");
|
|
298
|
+
}
|
|
239
299
|
const codeChallengeMethodsSupported = parseStringArray(metadata.code_challenge_methods_supported);
|
|
240
300
|
if (!codeChallengeMethodsSupported.includes("S256")) {
|
|
241
301
|
throw new Error("OAuth authorization server metadata must support PKCE S256.");
|
|
@@ -250,20 +310,25 @@ async function discoverOAuthMetadata(endpoint, fetchImpl = fetch) {
|
|
|
250
310
|
}
|
|
251
311
|
async function discoverResourceMetadataUrl(endpoint, fetchImpl) {
|
|
252
312
|
const challengeUrl = new URL(endpoint);
|
|
313
|
+
assertTrustedEndpointUrl(challengeUrl, "MCP endpoint");
|
|
253
314
|
const response = await fetchImpl(challengeUrl, { method: "GET" });
|
|
254
315
|
const challenge = response.headers.get("www-authenticate");
|
|
255
316
|
const fromChallenge = challenge ? parseBearerChallengeParam(challenge, "resource_metadata") : void 0;
|
|
256
317
|
if (fromChallenge) {
|
|
318
|
+
assertTrustedEndpointUrl(fromChallenge, "OAuth protected resource metadata URL");
|
|
257
319
|
return fromChallenge;
|
|
258
320
|
}
|
|
259
321
|
const origin = new URL(endpoint).origin;
|
|
260
|
-
|
|
322
|
+
const fallback = `${origin}/.well-known/oauth-protected-resource`;
|
|
323
|
+
assertTrustedEndpointUrl(fallback, "OAuth protected resource metadata URL");
|
|
324
|
+
return fallback;
|
|
261
325
|
}
|
|
262
326
|
function parseBearerChallengeParam(header, name) {
|
|
263
327
|
const pattern = new RegExp(`${name}="([^"]+)"`);
|
|
264
328
|
return pattern.exec(header)?.[1];
|
|
265
329
|
}
|
|
266
330
|
async function exchangeToken(tokenEndpoint, params, fetchImpl) {
|
|
331
|
+
assertTrustedEndpointUrl(tokenEndpoint, "OAuth token endpoint");
|
|
267
332
|
const response = await fetchImpl(tokenEndpoint, {
|
|
268
333
|
method: "POST",
|
|
269
334
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
@@ -342,18 +407,37 @@ function parseStringArray(value) {
|
|
|
342
407
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
343
408
|
}
|
|
344
409
|
async function fetchJson(url, fetchImpl) {
|
|
410
|
+
assertTrustedEndpointUrl(url, "OAuth metadata URL");
|
|
345
411
|
const response = await fetchImpl(url);
|
|
346
412
|
if (!response.ok) {
|
|
347
413
|
throw new Error(`Failed to fetch OAuth metadata from ${url}: HTTP ${response.status}.`);
|
|
348
414
|
}
|
|
349
415
|
return response.json();
|
|
350
416
|
}
|
|
417
|
+
function getBrowserOpenCommand(url, platform = process.platform) {
|
|
418
|
+
assertTrustedEndpointUrl(url, "OAuth authorization URL");
|
|
419
|
+
if (platform === "darwin") {
|
|
420
|
+
return { command: "open", args: [url] };
|
|
421
|
+
}
|
|
422
|
+
if (platform === "win32") {
|
|
423
|
+
return { command: "explorer.exe", args: [url] };
|
|
424
|
+
}
|
|
425
|
+
return { command: "xdg-open", args: [url] };
|
|
426
|
+
}
|
|
351
427
|
async function openBrowser(url) {
|
|
352
|
-
const command
|
|
353
|
-
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
428
|
+
const { command, args } = getBrowserOpenCommand(url);
|
|
354
429
|
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
355
430
|
child.unref();
|
|
356
431
|
}
|
|
432
|
+
function assertEnvTokenEndpointAllowed(endpoint, envVars) {
|
|
433
|
+
if (envVars.AINECTO_ALLOW_CUSTOM_ENDPOINT_TOKEN === "1") {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (isDefaultEndpoint(endpoint)) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
throw new Error("AINECTO_TOKEN can only be used with the default prod/dev endpoints. Set AINECTO_ALLOW_CUSTOM_ENDPOINT_TOKEN=1 only when you intentionally trust the custom endpoint.");
|
|
440
|
+
}
|
|
357
441
|
|
|
358
442
|
// src/core/mcp/rpcClient.ts
|
|
359
443
|
var McpRpcError = class extends Error {
|
|
@@ -419,10 +503,11 @@ var McpRpcClient = class {
|
|
|
419
503
|
}
|
|
420
504
|
const text = await response.text();
|
|
421
505
|
if (!response.ok) {
|
|
422
|
-
throw new McpRpcError(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
506
|
+
throw new McpRpcError(
|
|
507
|
+
`MCP HTTP request failed with HTTP ${response.status}.`,
|
|
508
|
+
"MCP_HTTP_ERROR",
|
|
509
|
+
httpErrorDetails(response.status, text, this.options.envVars ?? process.env)
|
|
510
|
+
);
|
|
426
511
|
}
|
|
427
512
|
if (!text.trim()) {
|
|
428
513
|
return void 0;
|
|
@@ -454,6 +539,13 @@ function isJsonRpcResponse(value) {
|
|
|
454
539
|
function isRecord2(value) {
|
|
455
540
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
456
541
|
}
|
|
542
|
+
function httpErrorDetails(status, body, envVars) {
|
|
543
|
+
const details = { status };
|
|
544
|
+
if (envVars.AINECTO_CLI_DEBUG === "1" || envVars.AINECTO_DEBUG === "1") {
|
|
545
|
+
details.body = safeBodyPreview(body);
|
|
546
|
+
}
|
|
547
|
+
return details;
|
|
548
|
+
}
|
|
457
549
|
function safeBodyPreview(body) {
|
|
458
550
|
return body.length > 500 ? `${body.slice(0, 500)}...` : body;
|
|
459
551
|
}
|
|
@@ -531,12 +623,42 @@ function toErrorShape(error) {
|
|
|
531
623
|
error: {
|
|
532
624
|
code: maybe.code ?? "CLI_ERROR",
|
|
533
625
|
message: error.message,
|
|
534
|
-
details: maybe.details
|
|
626
|
+
details: redactSecrets(maybe.details)
|
|
535
627
|
}
|
|
536
628
|
};
|
|
537
629
|
}
|
|
538
630
|
return { ok: false, error: { code: "CLI_ERROR", message: String(error) } };
|
|
539
631
|
}
|
|
632
|
+
function redactSecrets(value) {
|
|
633
|
+
return redactSecretsInner(value, /* @__PURE__ */ new WeakSet());
|
|
634
|
+
}
|
|
635
|
+
function redactSecretsInner(value, seen) {
|
|
636
|
+
if (typeof value === "string") {
|
|
637
|
+
return redactSecretString(value);
|
|
638
|
+
}
|
|
639
|
+
if (Array.isArray(value)) {
|
|
640
|
+
return value.map((item) => redactSecretsInner(item, seen));
|
|
641
|
+
}
|
|
642
|
+
if (value && typeof value === "object") {
|
|
643
|
+
if (seen.has(value)) {
|
|
644
|
+
return "[circular]";
|
|
645
|
+
}
|
|
646
|
+
seen.add(value);
|
|
647
|
+
const output = {};
|
|
648
|
+
for (const [key, child] of Object.entries(value)) {
|
|
649
|
+
output[key] = isSecretKey(key) ? "[redacted]" : redactSecretsInner(child, seen);
|
|
650
|
+
}
|
|
651
|
+
return output;
|
|
652
|
+
}
|
|
653
|
+
return value;
|
|
654
|
+
}
|
|
655
|
+
function isSecretKey(key) {
|
|
656
|
+
const normalized = key.toLowerCase().replace(/-/g, "_");
|
|
657
|
+
return normalized === "authorization" || normalized.includes("access_token") || normalized.includes("refresh_token") || normalized.includes("client_secret") || normalized.includes("token");
|
|
658
|
+
}
|
|
659
|
+
function redactSecretString(value) {
|
|
660
|
+
return value.replace(/("(?:authorization|access_token|refresh_token|client_secret|token)"\s*:\s*")([^"]*)(")/gi, "$1[redacted]$3").replace(/((?:authorization|access_token|refresh_token|client_secret|token)=)([^&\s"']+)/gi, "$1[redacted]").replace(/(authorization:\s*bearer\s+)([^\s,}]+)/gi, "$1[redacted]").replace(/(bearer\s+)(eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/gi, "$1[redacted]");
|
|
661
|
+
}
|
|
540
662
|
|
|
541
663
|
// src/adapters/mcp/args.ts
|
|
542
664
|
function parseMcpArgs(argv) {
|
package/dist/bin/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/config/endpoints.ts","../../src/core/auth/tokenStore.ts","../../src/core/auth/oauth.ts","../../src/core/auth/clientRegistration.ts","../../src/core/mcp/rpcClient.ts","../../src/core/mcp/stdioBridge.ts","../../src/adapters/mcp/connector.ts","../../src/core/output/render.ts","../../src/adapters/mcp/args.ts","../../src/bin/mcp.ts"],"sourcesContent":["export type AinectoEnv = \"prod\" | \"dev\";\n\nexport interface EndpointResolutionInput {\n env?: AinectoEnv;\n endpoint?: string;\n envVars?: NodeJS.ProcessEnv;\n}\n\nexport interface ResolvedEndpoint {\n env: AinectoEnv;\n endpoint: string;\n source: \"flag\" | \"env\" | \"default\";\n}\n\nconst DEFAULT_ENDPOINTS: Record<AinectoEnv, string> = {\n prod: \"https://ainecto.com/mcp\",\n dev: \"https://dev.ainecto.com/mcp\",\n};\n\nexport function resolveEndpoint(input: EndpointResolutionInput = {}): ResolvedEndpoint {\n const envVars = input.envVars ?? process.env;\n const env = input.env ?? \"prod\";\n\n if (input.endpoint) {\n return { env, endpoint: normalizeEndpoint(input.endpoint), source: \"flag\" };\n }\n\n if (envVars.AINECTO_MCP_ENDPOINT) {\n return { env, endpoint: normalizeEndpoint(envVars.AINECTO_MCP_ENDPOINT), source: \"env\" };\n }\n\n return { env, endpoint: DEFAULT_ENDPOINTS[env], source: \"default\" };\n}\n\nexport function normalizeEndpoint(endpoint: string): string {\n const url = new URL(endpoint);\n url.hash = \"\";\n return url.toString().replace(/\\/$/, \"\");\n}\n\nexport function assertEnv(value: string | undefined): AinectoEnv | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"prod\" || value === \"dev\") {\n return value;\n }\n throw new Error(`Invalid --env value \"${value}\". Expected \"prod\" or \"dev\".`);\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, stat, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredTokenSet {\n endpoint: string;\n accessToken: string;\n refreshToken?: string;\n tokenType?: string;\n expiresAt?: number;\n scope?: string;\n clientId?: string;\n clientSecret?: string;\n authorizationServer?: string;\n updatedAt: string;\n}\n\nexport interface TokenStore {\n load(endpoint: string): Promise<StoredTokenSet | undefined>;\n save(endpoint: string, token: StoredTokenSet): Promise<void>;\n delete(endpoint: string): Promise<void>;\n}\n\ntype TokenFile = Record<string, StoredTokenSet>;\n\nexport class FileTokenStore implements TokenStore {\n readonly filePath: string;\n\n constructor(rootDir = join(homedir(), \".ainecto\")) {\n this.filePath = join(rootDir, \"tokens.json\");\n }\n\n async load(endpoint: string): Promise<StoredTokenSet | undefined> {\n const file = await this.readFile();\n return file[tokenKey(endpoint)];\n }\n\n async save(endpoint: string, token: StoredTokenSet): Promise<void> {\n const file = await this.readFile();\n file[tokenKey(endpoint)] = { ...token, endpoint, updatedAt: new Date().toISOString() };\n await this.writeFile(file);\n }\n\n async delete(endpoint: string): Promise<void> {\n const file = await this.readFile();\n delete file[tokenKey(endpoint)];\n await this.writeFile(file);\n }\n\n private async readFile(): Promise<TokenFile> {\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"Token file must contain an object.\");\n }\n return parsed as TokenFile;\n } catch (error) {\n if (isNodeError(error, \"ENOENT\")) {\n return {};\n }\n throw error;\n }\n }\n\n private async writeFile(file: TokenFile): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 });\n await chmod(dirname(this.filePath), 0o700);\n const tmpPath = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;\n await writeFile(tmpPath, `${JSON.stringify(file, null, 2)}\\n`, { mode: 0o600 });\n await chmod(tmpPath, 0o600);\n await rename(tmpPath, this.filePath);\n await chmod(this.filePath, 0o600);\n }\n}\n\nexport function tokenKey(endpoint: string): string {\n return createHash(\"sha256\").update(endpoint).digest(\"hex\");\n}\n\nexport async function tokenStorePermissions(path: string): Promise<{ mode: number } | undefined> {\n try {\n const result = await stat(path);\n return { mode: result.mode & 0o777 };\n } catch (error) {\n if (isNodeError(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function removeTokenStoreForTests(path: string): Promise<void> {\n await rm(dirname(path), { recursive: true, force: true });\n}\n\nfunction isNodeError(error: unknown, code: string): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error && error.code === code;\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { spawn } from \"node:child_process\";\nimport { URLSearchParams } from \"node:url\";\nimport type { StoredTokenSet, TokenStore } from \"./tokenStore\";\nimport { registerPublicClient, type ClientRegistrationResult } from \"./clientRegistration\";\n\nexport interface OAuthClientOptions {\n endpoint: string;\n tokenStore: TokenStore;\n fetchImpl?: typeof fetch;\n envVars?: NodeJS.ProcessEnv;\n openBrowser?: (url: string) => Promise<void>;\n}\n\nexport interface OAuthMetadata {\n authorizationEndpoint: string;\n tokenEndpoint: string;\n registrationEndpoint?: string;\n issuer?: string;\n codeChallengeMethodsSupported: string[];\n}\n\nexport interface TokenProvider {\n getAccessToken(): Promise<string | undefined>;\n refreshAfterUnauthorized(): Promise<string | undefined>;\n}\n\nexport class OAuthClient implements TokenProvider {\n private readonly fetchImpl: typeof fetch;\n private readonly envVars: NodeJS.ProcessEnv;\n private readonly openBrowserImpl: (url: string) => Promise<void>;\n\n constructor(private readonly options: OAuthClientOptions) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.envVars = options.envVars ?? process.env;\n this.openBrowserImpl = options.openBrowser ?? openBrowser;\n }\n\n async getAccessToken(): Promise<string | undefined> {\n const envToken = this.envVars.AINECTO_TOKEN;\n if (envToken) {\n return envToken;\n }\n\n const stored = await this.options.tokenStore.load(this.options.endpoint);\n if (!stored) {\n return undefined;\n }\n\n if (!shouldRefresh(stored)) {\n return stored.accessToken;\n }\n\n return this.refreshStoredToken(stored);\n }\n\n async refreshAfterUnauthorized(): Promise<string | undefined> {\n const stored = await this.options.tokenStore.load(this.options.endpoint);\n if (!stored?.refreshToken) {\n return undefined;\n }\n return this.refreshStoredToken(stored);\n }\n\n async login(): Promise<StoredTokenSet> {\n const pkce = generatePkcePair();\n const state = generateOAuthState();\n const loopback = await createLoopbackReceiver(state);\n\n try {\n const metadata = await discoverOAuthMetadata(this.options.endpoint, this.fetchImpl);\n const registration = metadata.registrationEndpoint\n ? await registerPublicClient(metadata.registrationEndpoint, loopback.redirectUri, this.fetchImpl)\n : { clientId: \"ainecto-cli\" };\n const authorizeUrl = new URL(metadata.authorizationEndpoint);\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"client_id\", registration.clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", loopback.redirectUri);\n authorizeUrl.searchParams.set(\"code_challenge\", pkce.codeChallenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"resource\", this.options.endpoint);\n authorizeUrl.searchParams.set(\"state\", state);\n\n await this.openBrowserImpl(authorizeUrl.toString());\n const code = await loopback.waitForCode();\n const token = await exchangeToken(metadata.tokenEndpoint, {\n grant_type: \"authorization_code\",\n code,\n redirect_uri: loopback.redirectUri,\n client_id: registration.clientId,\n code_verifier: pkce.codeVerifier,\n resource: this.options.endpoint,\n ...(registration.clientSecret ? { client_secret: registration.clientSecret } : {}),\n }, this.fetchImpl);\n\n const stored = toStoredToken(this.options.endpoint, token, metadata, registration);\n await this.options.tokenStore.save(this.options.endpoint, stored);\n return stored;\n } finally {\n await loopback.close();\n }\n }\n\n async logout(): Promise<void> {\n await this.options.tokenStore.delete(this.options.endpoint);\n }\n\n private async refreshStoredToken(stored: StoredTokenSet): Promise<string | undefined> {\n if (!stored.refreshToken) {\n return stored.accessToken;\n }\n const metadata = await discoverOAuthMetadata(this.options.endpoint, this.fetchImpl);\n const token = await exchangeToken(metadata.tokenEndpoint, {\n grant_type: \"refresh_token\",\n refresh_token: stored.refreshToken,\n client_id: stored.clientId ?? \"ainecto-cli\",\n ...(stored.clientSecret ? { client_secret: stored.clientSecret } : {}),\n resource: this.options.endpoint,\n }, this.fetchImpl);\n const next = toStoredToken(this.options.endpoint, token, metadata, stored);\n await this.options.tokenStore.save(this.options.endpoint, next);\n return next.accessToken;\n }\n}\n\nexport function generatePkcePair(): { codeVerifier: string; codeChallenge: string } {\n const codeVerifier = randomBytes(32).toString(\"base64url\");\n const codeChallenge = createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\n return { codeVerifier, codeChallenge };\n}\n\nexport function generateOAuthState(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function shouldRefresh(token: Pick<StoredTokenSet, \"expiresAt\">, now = Date.now()): boolean {\n if (!token.expiresAt) {\n return false;\n }\n return token.expiresAt - now < 60_000;\n}\n\nexport async function discoverOAuthMetadata(endpoint: string, fetchImpl: typeof fetch = fetch): Promise<OAuthMetadata> {\n const resourceMetadataUrl = await discoverResourceMetadataUrl(endpoint, fetchImpl);\n const resourceMetadata = await fetchJson<Record<string, unknown>>(resourceMetadataUrl, fetchImpl);\n const authorizationServers = resourceMetadata.authorization_servers;\n if (!Array.isArray(authorizationServers) || typeof authorizationServers[0] !== \"string\") {\n throw new Error(\"OAuth protected resource metadata did not include authorization_servers.\");\n }\n const authServer = authorizationServers[0];\n const metadataUrl = authServer.includes(\"/.well-known/\")\n ? authServer\n : `${authServer.replace(/\\/$/, \"\")}/.well-known/oauth-authorization-server`;\n const metadata = await fetchJson<Record<string, unknown>>(metadataUrl, fetchImpl);\n if (typeof metadata.authorization_endpoint !== \"string\" || typeof metadata.token_endpoint !== \"string\") {\n throw new Error(\"OAuth authorization server metadata is missing authorization_endpoint or token_endpoint.\");\n }\n const codeChallengeMethodsSupported = parseStringArray(metadata.code_challenge_methods_supported);\n if (!codeChallengeMethodsSupported.includes(\"S256\")) {\n throw new Error(\"OAuth authorization server metadata must support PKCE S256.\");\n }\n return {\n authorizationEndpoint: metadata.authorization_endpoint,\n tokenEndpoint: metadata.token_endpoint,\n registrationEndpoint: typeof metadata.registration_endpoint === \"string\" ? metadata.registration_endpoint : undefined,\n issuer: typeof metadata.issuer === \"string\" ? metadata.issuer : undefined,\n codeChallengeMethodsSupported,\n };\n}\n\nasync function discoverResourceMetadataUrl(endpoint: string, fetchImpl: typeof fetch): Promise<string> {\n const challengeUrl = new URL(endpoint);\n const response = await fetchImpl(challengeUrl, { method: \"GET\" });\n const challenge = response.headers.get(\"www-authenticate\");\n const fromChallenge = challenge ? parseBearerChallengeParam(challenge, \"resource_metadata\") : undefined;\n if (fromChallenge) {\n return fromChallenge;\n }\n const origin = new URL(endpoint).origin;\n return `${origin}/.well-known/oauth-protected-resource`;\n}\n\nexport function parseBearerChallengeParam(header: string, name: string): string | undefined {\n const pattern = new RegExp(`${name}=\"([^\"]+)\"`);\n return pattern.exec(header)?.[1];\n}\n\nasync function exchangeToken(\n tokenEndpoint: string,\n params: Record<string, string>,\n fetchImpl: typeof fetch,\n): Promise<Record<string, unknown>> {\n const response = await fetchImpl(tokenEndpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params),\n });\n if (!response.ok) {\n throw new Error(`OAuth token exchange failed with HTTP ${response.status}.`);\n }\n return response.json() as Promise<Record<string, unknown>>;\n}\n\ntype TokenContext = Partial<Pick<StoredTokenSet, \"refreshToken\" | \"tokenType\" | \"expiresAt\" | \"scope\" | \"clientId\" | \"clientSecret\">>\n & Partial<ClientRegistrationResult>;\n\nfunction toStoredToken(\n endpoint: string,\n token: Record<string, unknown>,\n metadata: OAuthMetadata,\n previous?: TokenContext,\n): StoredTokenSet {\n if (typeof token.access_token !== \"string\") {\n throw new Error(\"OAuth token response did not include access_token.\");\n }\n const expiresIn = typeof token.expires_in === \"number\" ? token.expires_in : undefined;\n return {\n endpoint,\n accessToken: token.access_token,\n refreshToken: typeof token.refresh_token === \"string\" ? token.refresh_token : previous?.refreshToken,\n tokenType: typeof token.token_type === \"string\" ? token.token_type : previous?.tokenType,\n expiresAt: expiresIn ? Date.now() + expiresIn * 1000 : previous?.expiresAt,\n scope: typeof token.scope === \"string\" ? token.scope : previous?.scope,\n clientId: previous?.clientId ?? \"ainecto-cli\",\n clientSecret: previous?.clientSecret,\n authorizationServer: metadata.issuer,\n updatedAt: new Date().toISOString(),\n };\n}\n\nasync function createLoopbackReceiver(expectedState: string): Promise<{\n redirectUri: string;\n waitForCode(): Promise<string>;\n close(): Promise<void>;\n}> {\n let resolveCode!: (code: string) => void;\n let rejectCode!: (error: Error) => void;\n const codePromise = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n codePromise.catch(() => undefined);\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const error = url.searchParams.get(\"error\");\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (error) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization failed. You can close this tab.\");\n rejectCode(new Error(`OAuth authorization failed: ${error}`));\n return;\n }\n if (!state || state !== expectedState) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization state mismatch. You can close this tab.\");\n rejectCode(new Error(\"OAuth state mismatch.\"));\n return;\n }\n if (!code) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Missing OAuth code.\");\n rejectCode(new Error(\"OAuth redirect did not include a code.\"));\n return;\n }\n res.writeHead(200, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization complete. You can close this tab.\");\n resolveCode(code);\n });\n\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"Loopback OAuth server did not bind to a TCP port.\");\n }\n return {\n redirectUri: `http://127.0.0.1:${address.port}/callback`,\n waitForCode: () => codePromise,\n close: () => new Promise<void>((resolve, reject) => server.close((error) => error ? reject(error) : resolve())),\n };\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nasync function fetchJson<T>(url: string, fetchImpl: typeof fetch): Promise<T> {\n const response = await fetchImpl(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth metadata from ${url}: HTTP ${response.status}.`);\n }\n return response.json() as Promise<T>;\n}\n\nasync function openBrowser(url: string): Promise<void> {\n const command = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"cmd\" : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.unref();\n}\n","export interface ClientRegistrationResult {\n clientId: string;\n clientSecret?: string;\n}\n\nexport async function registerPublicClient(\n registrationEndpoint: string,\n redirectUri: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClientRegistrationResult> {\n const response = await fetchImpl(registrationEndpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", accept: \"application/json\" },\n body: JSON.stringify({\n client_name: \"Ainecto CLI\",\n redirect_uris: [redirectUri],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n }),\n });\n if (!response.ok) {\n throw new Error(`OAuth client registration failed with HTTP ${response.status}.`);\n }\n const body = await response.json() as unknown;\n if (!isRecord(body) || typeof body.client_id !== \"string\") {\n throw new Error(\"OAuth client registration response did not include client_id.\");\n }\n return {\n clientId: body.client_id,\n clientSecret: typeof body.client_secret === \"string\" ? body.client_secret : undefined,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import type { TokenProvider } from \"../auth/oauth\";\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n method: string;\n params?: unknown;\n}\n\nexport interface JsonRpcSuccess {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n result: unknown;\n}\n\nexport interface JsonRpcFailure {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n error: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport type JsonRpcResponse = JsonRpcSuccess | JsonRpcFailure;\n\nexport interface McpRpcClientOptions {\n endpoint: string;\n tokenProvider?: TokenProvider;\n fetchImpl?: typeof fetch;\n}\n\nexport class McpRpcError extends Error {\n constructor(\n message: string,\n readonly code: string,\n readonly details?: unknown,\n ) {\n super(message);\n }\n}\n\nexport class McpRpcClient {\n private readonly fetchImpl: typeof fetch;\n private nextId = 1;\n\n constructor(private readonly options: McpRpcClientOptions) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n initialize(): Promise<unknown> {\n return this.request(\"initialize\", {\n protocolVersion: \"2024-11-05\",\n capabilities: {},\n clientInfo: { name: \"@ainecto/mcp\", version: \"0.1.0\" },\n });\n }\n\n async toolsList(): Promise<unknown[]> {\n const result = await this.request(\"tools/list\", {});\n if (!isRecord(result) || !Array.isArray(result.tools)) {\n throw new McpRpcError(\"tools/list response did not include a tools array.\", \"MCP_PROTOCOL_ERROR\", result);\n }\n return result.tools;\n }\n\n async toolsCall(name: string, args: unknown): Promise<unknown> {\n return this.request(\"tools/call\", { name, arguments: args ?? {} });\n }\n\n async request(method: string, params?: unknown): Promise<unknown> {\n const response = await this.sendRaw({\n jsonrpc: \"2.0\",\n id: this.nextId++,\n method,\n params,\n });\n if (!response) {\n return undefined;\n }\n if (\"error\" in response) {\n throw new McpRpcError(response.error.message, \"MCP_ERROR\", response.error);\n }\n return response.result;\n }\n\n async sendRaw(request: JsonRpcRequest): Promise<JsonRpcResponse | undefined> {\n const token = await this.options.tokenProvider?.getAccessToken();\n let response = await this.postJson(request, token);\n if (response.status === 401 && this.options.tokenProvider) {\n const refreshed = await this.options.tokenProvider.refreshAfterUnauthorized();\n if (refreshed) {\n response = await this.postJson(request, refreshed);\n }\n }\n\n if (response.status === 204 || response.status === 202) {\n return undefined;\n }\n const text = await response.text();\n if (!response.ok) {\n throw new McpRpcError(`MCP HTTP request failed with HTTP ${response.status}.`, \"MCP_HTTP_ERROR\", {\n status: response.status,\n body: safeBodyPreview(text),\n });\n }\n if (!text.trim()) {\n return undefined;\n }\n const parsed = JSON.parse(text) as unknown;\n if (!isJsonRpcResponse(parsed)) {\n throw new McpRpcError(\"MCP response was not a JSON-RPC response.\", \"MCP_PROTOCOL_ERROR\", parsed);\n }\n return parsed;\n }\n\n private postJson(request: JsonRpcRequest, token: string | undefined): Promise<Response> {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n };\n if (token) {\n headers.authorization = `Bearer ${token}`;\n }\n return this.fetchImpl(this.options.endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n });\n }\n}\n\nfunction isJsonRpcResponse(value: unknown): value is JsonRpcResponse {\n return isRecord(value)\n && value.jsonrpc === \"2.0\"\n && (\"result\" in value || \"error\" in value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction safeBodyPreview(body: string): string {\n return body.length > 500 ? `${body.slice(0, 500)}...` : body;\n}\n","import { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport { McpRpcClient, type JsonRpcRequest } from \"./rpcClient\";\n\nexport interface StdioBridgeOptions {\n input: Readable;\n output: Writable;\n errorOutput: Writable;\n client: McpRpcClient;\n}\n\nexport async function runStdioBridge(options: StdioBridgeOptions): Promise<void> {\n const lines = createInterface({ input: options.input, crlfDelay: Infinity });\n\n for await (const line of lines) {\n if (!line.trim()) {\n continue;\n }\n try {\n const request = parseJsonRpcRequest(line);\n const response = await options.client.sendRaw(request);\n if (response && request.id !== undefined) {\n options.output.write(`${JSON.stringify(response)}\\n`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n options.output.write(`${JSON.stringify({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32603, message },\n })}\\n`);\n }\n }\n}\n\nfunction parseJsonRpcRequest(line: string): JsonRpcRequest {\n const parsed = JSON.parse(line) as unknown;\n if (!isRecord(parsed) || parsed.jsonrpc !== \"2.0\" || typeof parsed.method !== \"string\") {\n throw new Error(\"Invalid JSON-RPC request.\");\n }\n return {\n jsonrpc: \"2.0\",\n id: typeof parsed.id === \"string\" || typeof parsed.id === \"number\" || parsed.id === null ? parsed.id : undefined,\n method: parsed.method,\n params: parsed.params,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { FileTokenStore } from \"../../core/auth/tokenStore\";\nimport { OAuthClient } from \"../../core/auth/oauth\";\nimport { McpRpcClient } from \"../../core/mcp/rpcClient\";\nimport { runStdioBridge } from \"../../core/mcp/stdioBridge\";\nimport type { Readable, Writable } from \"node:stream\";\n\nexport interface ConnectorOptions {\n endpoint: string;\n input: Readable;\n output: Writable;\n errorOutput: Writable;\n}\n\nexport async function runConnector(options: ConnectorOptions): Promise<void> {\n const tokenStore = new FileTokenStore();\n const auth = new OAuthClient({ endpoint: options.endpoint, tokenStore });\n const client = new McpRpcClient({ endpoint: options.endpoint, tokenProvider: auth });\n await runStdioBridge({\n input: options.input,\n output: options.output,\n errorOutput: options.errorOutput,\n client,\n });\n}\n","export interface CliErrorShape {\n ok: false;\n error: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nexport interface CliSuccessShape {\n ok: true;\n data: unknown;\n warnings?: string[];\n}\n\nexport function renderSuccess(data: unknown, options: { json?: boolean; warnings?: string[] } = {}): string {\n if (options.json) {\n const shape: CliSuccessShape = { ok: true, data };\n if (options.warnings?.length) {\n shape.warnings = options.warnings;\n }\n return `${JSON.stringify(shape, null, 2)}\\n`;\n }\n const warnings = options.warnings?.length ? `${options.warnings.map((warning) => `Warning: ${warning}`).join(\"\\n\")}\\n` : \"\";\n return `${warnings}${renderHuman(data)}\\n`;\n}\n\nexport function renderError(error: unknown, options: { json?: boolean } = {}): string {\n const shape = toErrorShape(error);\n if (options.json) {\n return `${JSON.stringify(shape, null, 2)}\\n`;\n }\n return `Error: ${shape.error.message}\\n`;\n}\n\nexport function toErrorShape(error: unknown): CliErrorShape {\n if (error instanceof Error) {\n const maybe = error as Error & { code?: string; details?: unknown };\n return {\n ok: false,\n error: {\n code: maybe.code ?? \"CLI_ERROR\",\n message: error.message,\n details: maybe.details,\n },\n };\n }\n return { ok: false, error: { code: \"CLI_ERROR\", message: String(error) } };\n}\n\nfunction renderHuman(data: unknown): string {\n if (Array.isArray(data)) {\n return data.map((item) => renderHuman(item)).join(\"\\n\");\n }\n if (typeof data === \"string\") {\n return data;\n }\n return JSON.stringify(data, null, 2);\n}\n","import { assertEnv, type AinectoEnv } from \"../../core/config/endpoints\";\n\nexport interface McpBinArgs {\n env?: AinectoEnv;\n endpoint?: string;\n help: boolean;\n}\n\nexport function parseMcpArgs(argv: string[]): McpBinArgs {\n const result: McpBinArgs = { help: false };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (!arg) {\n continue;\n }\n if (arg === \"--env\") {\n result.env = assertEnv(requireFlagValue(arg, argv[++index]));\n } else if (arg === \"--endpoint\") {\n result.endpoint = requireFlagValue(arg, argv[++index]);\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.help = true;\n } else {\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n return result;\n}\n\nfunction requireFlagValue(flag: string, value: string | undefined): string {\n if (!value || value.startsWith(\"--\")) {\n throw new Error(`${flag} requires a value.`);\n }\n return value;\n}\n","#!/usr/bin/env node\nimport { resolveEndpoint } from \"../core/config/endpoints\";\nimport { runConnector } from \"../adapters/mcp/connector\";\nimport { renderError } from \"../core/output/render\";\nimport { parseMcpArgs } from \"../adapters/mcp/args\";\n\ntry {\n const args = parseMcpArgs(process.argv.slice(2));\n if (args.help) {\n process.stdout.write(\"Usage: mcp [--env prod|dev] [--endpoint URL]\\n\");\n process.exit(0);\n }\n const resolved = resolveEndpoint({ env: args.env, endpoint: args.endpoint });\n await runConnector({\n endpoint: resolved.endpoint,\n input: process.stdin,\n output: process.stdout,\n errorOutput: process.stderr,\n });\n} catch (error) {\n process.stderr.write(renderError(error));\n process.exitCode = 1;\n}\n"],"mappings":"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","names":["createHash","createHash","isRecord","isRecord"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/config/endpoints.ts","../../src/core/auth/tokenStore.ts","../../src/core/auth/oauth.ts","../../src/core/auth/clientRegistration.ts","../../src/core/mcp/rpcClient.ts","../../src/core/mcp/stdioBridge.ts","../../src/adapters/mcp/connector.ts","../../src/core/output/render.ts","../../src/adapters/mcp/args.ts","../../src/bin/mcp.ts"],"sourcesContent":["export type AinectoEnv = \"prod\" | \"dev\";\n\nexport interface EndpointResolutionInput {\n env?: AinectoEnv;\n endpoint?: string;\n envVars?: NodeJS.ProcessEnv;\n}\n\nexport interface ResolvedEndpoint {\n env: AinectoEnv;\n endpoint: string;\n source: \"flag\" | \"env\" | \"default\";\n}\n\nconst DEFAULT_ENDPOINTS: Record<AinectoEnv, string> = {\n prod: \"https://ainecto.com/mcp\",\n dev: \"https://dev.ainecto.com/mcp\",\n};\n\nexport function resolveEndpoint(input: EndpointResolutionInput = {}): ResolvedEndpoint {\n const envVars = input.envVars ?? process.env;\n const env = input.env ?? \"prod\";\n\n if (input.endpoint) {\n return { env, endpoint: normalizeEndpoint(input.endpoint), source: \"flag\" };\n }\n\n if (envVars.AINECTO_MCP_ENDPOINT) {\n return { env, endpoint: normalizeEndpoint(envVars.AINECTO_MCP_ENDPOINT), source: \"env\" };\n }\n\n return { env, endpoint: DEFAULT_ENDPOINTS[env], source: \"default\" };\n}\n\nexport function normalizeEndpoint(endpoint: string): string {\n const url = new URL(endpoint);\n assertTrustedEndpointUrl(url, \"MCP endpoint\");\n url.hash = \"\";\n return url.toString().replace(/\\/$/, \"\");\n}\n\nexport function isDefaultEndpoint(endpoint: string): boolean {\n const normalized = normalizeEndpoint(endpoint);\n return Object.values(DEFAULT_ENDPOINTS).includes(normalized);\n}\n\nexport function assertTrustedEndpointUrl(value: string | URL, label = \"URL\"): void {\n const url = typeof value === \"string\" ? new URL(value) : value;\n if (url.protocol === \"https:\") {\n return;\n }\n if (url.protocol === \"http:\" && isLoopbackHostname(url.hostname)) {\n return;\n }\n throw new Error(`${label} must use https, except http is allowed for localhost loopback endpoints.`);\n}\n\nexport function assertLoopbackRedirectUrl(value: string): void {\n const url = new URL(value);\n if (url.protocol === \"http:\" && isLoopbackHostname(url.hostname)) {\n return;\n }\n throw new Error(\"OAuth redirect URI must be an http localhost loopback URL.\");\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return hostname === \"localhost\"\n || hostname === \"127.0.0.1\"\n || hostname === \"::1\"\n || hostname === \"[::1]\";\n}\n\nexport function assertEnv(value: string | undefined): AinectoEnv | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"prod\" || value === \"dev\") {\n return value;\n }\n throw new Error(`Invalid --env value \"${value}\". Expected \"prod\" or \"dev\".`);\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, stat, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredTokenSet {\n endpoint: string;\n accessToken: string;\n refreshToken?: string;\n tokenType?: string;\n expiresAt?: number;\n scope?: string;\n clientId?: string;\n clientSecret?: string;\n authorizationServer?: string;\n updatedAt: string;\n}\n\nexport interface TokenStore {\n load(endpoint: string): Promise<StoredTokenSet | undefined>;\n save(endpoint: string, token: StoredTokenSet): Promise<void>;\n delete(endpoint: string): Promise<void>;\n}\n\ntype TokenFile = Record<string, StoredTokenSet>;\n\nexport class FileTokenStore implements TokenStore {\n readonly filePath: string;\n\n constructor(rootDir = join(homedir(), \".ainecto\")) {\n this.filePath = join(rootDir, \"tokens.json\");\n }\n\n async load(endpoint: string): Promise<StoredTokenSet | undefined> {\n const file = await this.readFile();\n return file[tokenKey(endpoint)];\n }\n\n async save(endpoint: string, token: StoredTokenSet): Promise<void> {\n const file = await this.readFile();\n file[tokenKey(endpoint)] = { ...token, endpoint, updatedAt: new Date().toISOString() };\n await this.writeFile(file);\n }\n\n async delete(endpoint: string): Promise<void> {\n const file = await this.readFile();\n delete file[tokenKey(endpoint)];\n await this.writeFile(file);\n }\n\n private async readFile(): Promise<TokenFile> {\n try {\n await this.hardenExistingPermissions();\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"Token file must contain an object.\");\n }\n return parsed as TokenFile;\n } catch (error) {\n if (isNodeError(error, \"ENOENT\")) {\n return {};\n }\n throw error;\n }\n }\n\n private async writeFile(file: TokenFile): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 });\n await chmod(dirname(this.filePath), 0o700);\n const tmpPath = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;\n await writeFile(tmpPath, `${JSON.stringify(file, null, 2)}\\n`, { mode: 0o600 });\n await chmod(tmpPath, 0o600);\n await rename(tmpPath, this.filePath);\n await chmod(this.filePath, 0o600);\n }\n\n private async hardenExistingPermissions(): Promise<void> {\n const dirPath = dirname(this.filePath);\n await chmodIfPermissive(dirPath, 0o700);\n await chmodIfPermissive(this.filePath, 0o600);\n }\n}\n\nexport function tokenKey(endpoint: string): string {\n return createHash(\"sha256\").update(endpoint).digest(\"hex\");\n}\n\nexport async function tokenStorePermissions(path: string): Promise<{ mode: number } | undefined> {\n try {\n const result = await stat(path);\n return { mode: result.mode & 0o777 };\n } catch (error) {\n if (isNodeError(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function tokenStoreDirectoryPermissions(path: string): Promise<{ mode: number } | undefined> {\n return tokenStorePermissions(dirname(path));\n}\n\nexport async function removeTokenStoreForTests(path: string): Promise<void> {\n await rm(dirname(path), { recursive: true, force: true });\n}\n\nfunction isNodeError(error: unknown, code: string): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error && error.code === code;\n}\n\nasync function chmodIfPermissive(path: string, mode: number): Promise<void> {\n try {\n const result = await stat(path);\n if ((result.mode & 0o077) !== 0) {\n await chmod(path, mode);\n }\n } catch (error) {\n if (isNodeError(error, \"ENOENT\")) {\n return;\n }\n throw error;\n }\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { spawn } from \"node:child_process\";\nimport { URLSearchParams } from \"node:url\";\nimport type { StoredTokenSet, TokenStore } from \"./tokenStore\";\nimport { registerPublicClient, type ClientRegistrationResult } from \"./clientRegistration\";\nimport { assertTrustedEndpointUrl, isDefaultEndpoint } from \"../config/endpoints\";\n\nexport interface OAuthClientOptions {\n endpoint: string;\n tokenStore: TokenStore;\n fetchImpl?: typeof fetch;\n envVars?: NodeJS.ProcessEnv;\n openBrowser?: (url: string) => Promise<void>;\n}\n\nexport interface OAuthMetadata {\n authorizationEndpoint: string;\n tokenEndpoint: string;\n registrationEndpoint?: string;\n issuer?: string;\n codeChallengeMethodsSupported: string[];\n}\n\nexport interface TokenProvider {\n getAccessToken(): Promise<string | undefined>;\n refreshAfterUnauthorized(): Promise<string | undefined>;\n}\n\nexport class OAuthClient implements TokenProvider {\n private readonly fetchImpl: typeof fetch;\n private readonly envVars: NodeJS.ProcessEnv;\n private readonly openBrowserImpl: (url: string) => Promise<void>;\n\n constructor(private readonly options: OAuthClientOptions) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.envVars = options.envVars ?? process.env;\n this.openBrowserImpl = options.openBrowser ?? openBrowser;\n }\n\n async getAccessToken(): Promise<string | undefined> {\n const envToken = this.envVars.AINECTO_TOKEN;\n if (envToken) {\n assertEnvTokenEndpointAllowed(this.options.endpoint, this.envVars);\n return envToken;\n }\n\n const stored = await this.options.tokenStore.load(this.options.endpoint);\n if (!stored) {\n return undefined;\n }\n\n if (!shouldRefresh(stored)) {\n return stored.accessToken;\n }\n\n return this.refreshStoredToken(stored);\n }\n\n async refreshAfterUnauthorized(): Promise<string | undefined> {\n const stored = await this.options.tokenStore.load(this.options.endpoint);\n if (!stored?.refreshToken) {\n return undefined;\n }\n return this.refreshStoredToken(stored);\n }\n\n async login(): Promise<StoredTokenSet> {\n const pkce = generatePkcePair();\n const state = generateOAuthState();\n const loopback = await createLoopbackReceiver(state);\n\n try {\n const metadata = await discoverOAuthMetadata(this.options.endpoint, this.fetchImpl);\n const registration = metadata.registrationEndpoint\n ? await registerPublicClient(metadata.registrationEndpoint, loopback.redirectUri, this.fetchImpl)\n : { clientId: \"ainecto-cli\" };\n const authorizeUrl = new URL(metadata.authorizationEndpoint);\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"client_id\", registration.clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", loopback.redirectUri);\n authorizeUrl.searchParams.set(\"code_challenge\", pkce.codeChallenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"resource\", this.options.endpoint);\n authorizeUrl.searchParams.set(\"state\", state);\n\n assertTrustedEndpointUrl(authorizeUrl, \"OAuth authorization URL\");\n await this.openBrowserImpl(authorizeUrl.toString());\n const code = await loopback.waitForCode();\n const token = await exchangeToken(metadata.tokenEndpoint, {\n grant_type: \"authorization_code\",\n code,\n redirect_uri: loopback.redirectUri,\n client_id: registration.clientId,\n code_verifier: pkce.codeVerifier,\n resource: this.options.endpoint,\n ...(registration.clientSecret ? { client_secret: registration.clientSecret } : {}),\n }, this.fetchImpl);\n\n const stored = toStoredToken(this.options.endpoint, token, metadata, registration);\n await this.options.tokenStore.save(this.options.endpoint, stored);\n return stored;\n } finally {\n await loopback.close();\n }\n }\n\n async logout(): Promise<void> {\n await this.options.tokenStore.delete(this.options.endpoint);\n }\n\n private async refreshStoredToken(stored: StoredTokenSet): Promise<string | undefined> {\n if (!stored.refreshToken) {\n return stored.accessToken;\n }\n const metadata = await discoverOAuthMetadata(this.options.endpoint, this.fetchImpl);\n const token = await exchangeToken(metadata.tokenEndpoint, {\n grant_type: \"refresh_token\",\n refresh_token: stored.refreshToken,\n client_id: stored.clientId ?? \"ainecto-cli\",\n ...(stored.clientSecret ? { client_secret: stored.clientSecret } : {}),\n resource: this.options.endpoint,\n }, this.fetchImpl);\n const next = toStoredToken(this.options.endpoint, token, metadata, stored);\n await this.options.tokenStore.save(this.options.endpoint, next);\n return next.accessToken;\n }\n}\n\nexport function generatePkcePair(): { codeVerifier: string; codeChallenge: string } {\n const codeVerifier = randomBytes(32).toString(\"base64url\");\n const codeChallenge = createHash(\"sha256\").update(codeVerifier).digest(\"base64url\");\n return { codeVerifier, codeChallenge };\n}\n\nexport function generateOAuthState(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function shouldRefresh(token: Pick<StoredTokenSet, \"expiresAt\">, now = Date.now()): boolean {\n if (!token.expiresAt) {\n return false;\n }\n return token.expiresAt - now < 60_000;\n}\n\nexport async function discoverOAuthMetadata(endpoint: string, fetchImpl: typeof fetch = fetch): Promise<OAuthMetadata> {\n assertTrustedEndpointUrl(endpoint, \"MCP endpoint\");\n const resourceMetadataUrl = await discoverResourceMetadataUrl(endpoint, fetchImpl);\n assertTrustedEndpointUrl(resourceMetadataUrl, \"OAuth protected resource metadata URL\");\n const resourceMetadata = await fetchJson<Record<string, unknown>>(resourceMetadataUrl, fetchImpl);\n const authorizationServers = resourceMetadata.authorization_servers;\n if (!Array.isArray(authorizationServers) || typeof authorizationServers[0] !== \"string\") {\n throw new Error(\"OAuth protected resource metadata did not include authorization_servers.\");\n }\n const authServer = authorizationServers[0];\n assertTrustedEndpointUrl(authServer, \"OAuth authorization server\");\n const metadataUrl = authServer.includes(\"/.well-known/\")\n ? authServer\n : `${authServer.replace(/\\/$/, \"\")}/.well-known/oauth-authorization-server`;\n assertTrustedEndpointUrl(metadataUrl, \"OAuth authorization server metadata URL\");\n const metadata = await fetchJson<Record<string, unknown>>(metadataUrl, fetchImpl);\n if (typeof metadata.authorization_endpoint !== \"string\" || typeof metadata.token_endpoint !== \"string\") {\n throw new Error(\"OAuth authorization server metadata is missing authorization_endpoint or token_endpoint.\");\n }\n assertTrustedEndpointUrl(metadata.authorization_endpoint, \"OAuth authorization endpoint\");\n assertTrustedEndpointUrl(metadata.token_endpoint, \"OAuth token endpoint\");\n if (typeof metadata.registration_endpoint === \"string\") {\n assertTrustedEndpointUrl(metadata.registration_endpoint, \"OAuth client registration endpoint\");\n }\n if (typeof metadata.issuer === \"string\") {\n assertTrustedEndpointUrl(metadata.issuer, \"OAuth issuer\");\n }\n const codeChallengeMethodsSupported = parseStringArray(metadata.code_challenge_methods_supported);\n if (!codeChallengeMethodsSupported.includes(\"S256\")) {\n throw new Error(\"OAuth authorization server metadata must support PKCE S256.\");\n }\n return {\n authorizationEndpoint: metadata.authorization_endpoint,\n tokenEndpoint: metadata.token_endpoint,\n registrationEndpoint: typeof metadata.registration_endpoint === \"string\" ? metadata.registration_endpoint : undefined,\n issuer: typeof metadata.issuer === \"string\" ? metadata.issuer : undefined,\n codeChallengeMethodsSupported,\n };\n}\n\nasync function discoverResourceMetadataUrl(endpoint: string, fetchImpl: typeof fetch): Promise<string> {\n const challengeUrl = new URL(endpoint);\n assertTrustedEndpointUrl(challengeUrl, \"MCP endpoint\");\n const response = await fetchImpl(challengeUrl, { method: \"GET\" });\n const challenge = response.headers.get(\"www-authenticate\");\n const fromChallenge = challenge ? parseBearerChallengeParam(challenge, \"resource_metadata\") : undefined;\n if (fromChallenge) {\n assertTrustedEndpointUrl(fromChallenge, \"OAuth protected resource metadata URL\");\n return fromChallenge;\n }\n const origin = new URL(endpoint).origin;\n const fallback = `${origin}/.well-known/oauth-protected-resource`;\n assertTrustedEndpointUrl(fallback, \"OAuth protected resource metadata URL\");\n return fallback;\n}\n\nexport function parseBearerChallengeParam(header: string, name: string): string | undefined {\n const pattern = new RegExp(`${name}=\"([^\"]+)\"`);\n return pattern.exec(header)?.[1];\n}\n\nasync function exchangeToken(\n tokenEndpoint: string,\n params: Record<string, string>,\n fetchImpl: typeof fetch,\n): Promise<Record<string, unknown>> {\n assertTrustedEndpointUrl(tokenEndpoint, \"OAuth token endpoint\");\n const response = await fetchImpl(tokenEndpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params),\n });\n if (!response.ok) {\n throw new Error(`OAuth token exchange failed with HTTP ${response.status}.`);\n }\n return response.json() as Promise<Record<string, unknown>>;\n}\n\ntype TokenContext = Partial<Pick<StoredTokenSet, \"refreshToken\" | \"tokenType\" | \"expiresAt\" | \"scope\" | \"clientId\" | \"clientSecret\">>\n & Partial<ClientRegistrationResult>;\n\nfunction toStoredToken(\n endpoint: string,\n token: Record<string, unknown>,\n metadata: OAuthMetadata,\n previous?: TokenContext,\n): StoredTokenSet {\n if (typeof token.access_token !== \"string\") {\n throw new Error(\"OAuth token response did not include access_token.\");\n }\n const expiresIn = typeof token.expires_in === \"number\" ? token.expires_in : undefined;\n return {\n endpoint,\n accessToken: token.access_token,\n refreshToken: typeof token.refresh_token === \"string\" ? token.refresh_token : previous?.refreshToken,\n tokenType: typeof token.token_type === \"string\" ? token.token_type : previous?.tokenType,\n expiresAt: expiresIn ? Date.now() + expiresIn * 1000 : previous?.expiresAt,\n scope: typeof token.scope === \"string\" ? token.scope : previous?.scope,\n clientId: previous?.clientId ?? \"ainecto-cli\",\n clientSecret: previous?.clientSecret,\n authorizationServer: metadata.issuer,\n updatedAt: new Date().toISOString(),\n };\n}\n\nasync function createLoopbackReceiver(expectedState: string): Promise<{\n redirectUri: string;\n waitForCode(): Promise<string>;\n close(): Promise<void>;\n}> {\n let resolveCode!: (code: string) => void;\n let rejectCode!: (error: Error) => void;\n const codePromise = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n codePromise.catch(() => undefined);\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const error = url.searchParams.get(\"error\");\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (error) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization failed. You can close this tab.\");\n rejectCode(new Error(`OAuth authorization failed: ${error}`));\n return;\n }\n if (!state || state !== expectedState) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization state mismatch. You can close this tab.\");\n rejectCode(new Error(\"OAuth state mismatch.\"));\n return;\n }\n if (!code) {\n res.writeHead(400, { \"content-type\": \"text/plain\" });\n res.end(\"Missing OAuth code.\");\n rejectCode(new Error(\"OAuth redirect did not include a code.\"));\n return;\n }\n res.writeHead(200, { \"content-type\": \"text/plain\" });\n res.end(\"Ainecto CLI authorization complete. You can close this tab.\");\n resolveCode(code);\n });\n\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"Loopback OAuth server did not bind to a TCP port.\");\n }\n return {\n redirectUri: `http://127.0.0.1:${address.port}/callback`,\n waitForCode: () => codePromise,\n close: () => new Promise<void>((resolve, reject) => server.close((error) => error ? reject(error) : resolve())),\n };\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nasync function fetchJson<T>(url: string, fetchImpl: typeof fetch): Promise<T> {\n assertTrustedEndpointUrl(url, \"OAuth metadata URL\");\n const response = await fetchImpl(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth metadata from ${url}: HTTP ${response.status}.`);\n }\n return response.json() as Promise<T>;\n}\n\nexport function getBrowserOpenCommand(\n url: string,\n platform: NodeJS.Platform = process.platform,\n): { command: string; args: string[] } {\n assertTrustedEndpointUrl(url, \"OAuth authorization URL\");\n if (platform === \"darwin\") {\n return { command: \"open\", args: [url] };\n }\n if (platform === \"win32\") {\n return { command: \"explorer.exe\", args: [url] };\n }\n return { command: \"xdg-open\", args: [url] };\n}\n\nasync function openBrowser(url: string): Promise<void> {\n const { command, args } = getBrowserOpenCommand(url);\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.unref();\n}\n\nfunction assertEnvTokenEndpointAllowed(endpoint: string, envVars: NodeJS.ProcessEnv): void {\n if (envVars.AINECTO_ALLOW_CUSTOM_ENDPOINT_TOKEN === \"1\") {\n return;\n }\n if (isDefaultEndpoint(endpoint)) {\n return;\n }\n throw new Error(\"AINECTO_TOKEN can only be used with the default prod/dev endpoints. Set AINECTO_ALLOW_CUSTOM_ENDPOINT_TOKEN=1 only when you intentionally trust the custom endpoint.\");\n}\n","import { assertLoopbackRedirectUrl, assertTrustedEndpointUrl } from \"../config/endpoints\";\n\nexport interface ClientRegistrationResult {\n clientId: string;\n clientSecret?: string;\n}\n\nexport async function registerPublicClient(\n registrationEndpoint: string,\n redirectUri: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<ClientRegistrationResult> {\n assertTrustedEndpointUrl(registrationEndpoint, \"OAuth client registration endpoint\");\n assertLoopbackRedirectUrl(redirectUri);\n const response = await fetchImpl(registrationEndpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", accept: \"application/json\" },\n body: JSON.stringify({\n client_name: \"Ainecto CLI\",\n redirect_uris: [redirectUri],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n }),\n });\n if (!response.ok) {\n throw new Error(`OAuth client registration failed with HTTP ${response.status}.`);\n }\n const body = await response.json() as unknown;\n if (!isRecord(body) || typeof body.client_id !== \"string\") {\n throw new Error(\"OAuth client registration response did not include client_id.\");\n }\n return {\n clientId: body.client_id,\n clientSecret: typeof body.client_secret === \"string\" ? body.client_secret : undefined,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import type { TokenProvider } from \"../auth/oauth\";\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n method: string;\n params?: unknown;\n}\n\nexport interface JsonRpcSuccess {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n result: unknown;\n}\n\nexport interface JsonRpcFailure {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n error: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport type JsonRpcResponse = JsonRpcSuccess | JsonRpcFailure;\n\nexport interface McpRpcClientOptions {\n endpoint: string;\n tokenProvider?: TokenProvider;\n fetchImpl?: typeof fetch;\n envVars?: NodeJS.ProcessEnv;\n}\n\nexport class McpRpcError extends Error {\n constructor(\n message: string,\n readonly code: string,\n readonly details?: unknown,\n ) {\n super(message);\n }\n}\n\nexport class McpRpcClient {\n private readonly fetchImpl: typeof fetch;\n private nextId = 1;\n\n constructor(private readonly options: McpRpcClientOptions) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n initialize(): Promise<unknown> {\n return this.request(\"initialize\", {\n protocolVersion: \"2024-11-05\",\n capabilities: {},\n clientInfo: { name: \"@ainecto/mcp\", version: \"0.1.0\" },\n });\n }\n\n async toolsList(): Promise<unknown[]> {\n const result = await this.request(\"tools/list\", {});\n if (!isRecord(result) || !Array.isArray(result.tools)) {\n throw new McpRpcError(\"tools/list response did not include a tools array.\", \"MCP_PROTOCOL_ERROR\", result);\n }\n return result.tools;\n }\n\n async toolsCall(name: string, args: unknown): Promise<unknown> {\n return this.request(\"tools/call\", { name, arguments: args ?? {} });\n }\n\n async request(method: string, params?: unknown): Promise<unknown> {\n const response = await this.sendRaw({\n jsonrpc: \"2.0\",\n id: this.nextId++,\n method,\n params,\n });\n if (!response) {\n return undefined;\n }\n if (\"error\" in response) {\n throw new McpRpcError(response.error.message, \"MCP_ERROR\", response.error);\n }\n return response.result;\n }\n\n async sendRaw(request: JsonRpcRequest): Promise<JsonRpcResponse | undefined> {\n const token = await this.options.tokenProvider?.getAccessToken();\n let response = await this.postJson(request, token);\n if (response.status === 401 && this.options.tokenProvider) {\n const refreshed = await this.options.tokenProvider.refreshAfterUnauthorized();\n if (refreshed) {\n response = await this.postJson(request, refreshed);\n }\n }\n\n if (response.status === 204 || response.status === 202) {\n return undefined;\n }\n const text = await response.text();\n if (!response.ok) {\n throw new McpRpcError(\n `MCP HTTP request failed with HTTP ${response.status}.`,\n \"MCP_HTTP_ERROR\",\n httpErrorDetails(response.status, text, this.options.envVars ?? process.env),\n );\n }\n if (!text.trim()) {\n return undefined;\n }\n const parsed = JSON.parse(text) as unknown;\n if (!isJsonRpcResponse(parsed)) {\n throw new McpRpcError(\"MCP response was not a JSON-RPC response.\", \"MCP_PROTOCOL_ERROR\", parsed);\n }\n return parsed;\n }\n\n private postJson(request: JsonRpcRequest, token: string | undefined): Promise<Response> {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n };\n if (token) {\n headers.authorization = `Bearer ${token}`;\n }\n return this.fetchImpl(this.options.endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n });\n }\n}\n\nfunction isJsonRpcResponse(value: unknown): value is JsonRpcResponse {\n return isRecord(value)\n && value.jsonrpc === \"2.0\"\n && (\"result\" in value || \"error\" in value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction httpErrorDetails(status: number, body: string, envVars: NodeJS.ProcessEnv): Record<string, unknown> {\n const details: Record<string, unknown> = { status };\n if (envVars.AINECTO_CLI_DEBUG === \"1\" || envVars.AINECTO_DEBUG === \"1\") {\n details.body = safeBodyPreview(body);\n }\n return details;\n}\n\nexport function safeBodyPreview(body: string): string {\n return body.length > 500 ? `${body.slice(0, 500)}...` : body;\n}\n","import { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport { McpRpcClient, type JsonRpcRequest } from \"./rpcClient\";\n\nexport interface StdioBridgeOptions {\n input: Readable;\n output: Writable;\n errorOutput: Writable;\n client: McpRpcClient;\n}\n\nexport async function runStdioBridge(options: StdioBridgeOptions): Promise<void> {\n const lines = createInterface({ input: options.input, crlfDelay: Infinity });\n\n for await (const line of lines) {\n if (!line.trim()) {\n continue;\n }\n try {\n const request = parseJsonRpcRequest(line);\n const response = await options.client.sendRaw(request);\n if (response && request.id !== undefined) {\n options.output.write(`${JSON.stringify(response)}\\n`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n options.output.write(`${JSON.stringify({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32603, message },\n })}\\n`);\n }\n }\n}\n\nfunction parseJsonRpcRequest(line: string): JsonRpcRequest {\n const parsed = JSON.parse(line) as unknown;\n if (!isRecord(parsed) || parsed.jsonrpc !== \"2.0\" || typeof parsed.method !== \"string\") {\n throw new Error(\"Invalid JSON-RPC request.\");\n }\n return {\n jsonrpc: \"2.0\",\n id: typeof parsed.id === \"string\" || typeof parsed.id === \"number\" || parsed.id === null ? parsed.id : undefined,\n method: parsed.method,\n params: parsed.params,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { FileTokenStore } from \"../../core/auth/tokenStore\";\nimport { OAuthClient } from \"../../core/auth/oauth\";\nimport { McpRpcClient } from \"../../core/mcp/rpcClient\";\nimport { runStdioBridge } from \"../../core/mcp/stdioBridge\";\nimport type { Readable, Writable } from \"node:stream\";\n\nexport interface ConnectorOptions {\n endpoint: string;\n input: Readable;\n output: Writable;\n errorOutput: Writable;\n}\n\nexport async function runConnector(options: ConnectorOptions): Promise<void> {\n const tokenStore = new FileTokenStore();\n const auth = new OAuthClient({ endpoint: options.endpoint, tokenStore });\n const client = new McpRpcClient({ endpoint: options.endpoint, tokenProvider: auth });\n await runStdioBridge({\n input: options.input,\n output: options.output,\n errorOutput: options.errorOutput,\n client,\n });\n}\n","export interface CliErrorShape {\n ok: false;\n error: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nexport interface CliSuccessShape {\n ok: true;\n data: unknown;\n warnings?: string[];\n}\n\nexport function renderSuccess(data: unknown, options: { json?: boolean; warnings?: string[] } = {}): string {\n if (options.json) {\n const shape: CliSuccessShape = { ok: true, data };\n if (options.warnings?.length) {\n shape.warnings = options.warnings;\n }\n return `${JSON.stringify(shape, null, 2)}\\n`;\n }\n const warnings = options.warnings?.length ? `${options.warnings.map((warning) => `Warning: ${warning}`).join(\"\\n\")}\\n` : \"\";\n return `${warnings}${renderHuman(data)}\\n`;\n}\n\nexport function renderError(error: unknown, options: { json?: boolean } = {}): string {\n const shape = toErrorShape(error);\n if (options.json) {\n return `${JSON.stringify(shape, null, 2)}\\n`;\n }\n return `Error: ${shape.error.message}\\n`;\n}\n\nexport function toErrorShape(error: unknown): CliErrorShape {\n if (error instanceof Error) {\n const maybe = error as Error & { code?: string; details?: unknown };\n return {\n ok: false,\n error: {\n code: maybe.code ?? \"CLI_ERROR\",\n message: error.message,\n details: redactSecrets(maybe.details),\n },\n };\n }\n return { ok: false, error: { code: \"CLI_ERROR\", message: String(error) } };\n}\n\nexport function redactSecrets(value: unknown): unknown {\n return redactSecretsInner(value, new WeakSet<object>());\n}\n\nfunction renderHuman(data: unknown): string {\n if (Array.isArray(data)) {\n return data.map((item) => renderHuman(item)).join(\"\\n\");\n }\n if (typeof data === \"string\") {\n return data;\n }\n return JSON.stringify(data, null, 2);\n}\n\nfunction redactSecretsInner(value: unknown, seen: WeakSet<object>): unknown {\n if (typeof value === \"string\") {\n return redactSecretString(value);\n }\n if (Array.isArray(value)) {\n return value.map((item) => redactSecretsInner(item, seen));\n }\n if (value && typeof value === \"object\") {\n if (seen.has(value)) {\n return \"[circular]\";\n }\n seen.add(value);\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n output[key] = isSecretKey(key) ? \"[redacted]\" : redactSecretsInner(child, seen);\n }\n return output;\n }\n return value;\n}\n\nfunction isSecretKey(key: string): boolean {\n const normalized = key.toLowerCase().replace(/-/g, \"_\");\n return normalized === \"authorization\"\n || normalized.includes(\"access_token\")\n || normalized.includes(\"refresh_token\")\n || normalized.includes(\"client_secret\")\n || normalized.includes(\"token\");\n}\n\nfunction redactSecretString(value: string): string {\n return value\n .replace(/(\"(?:authorization|access_token|refresh_token|client_secret|token)\"\\s*:\\s*\")([^\"]*)(\")/gi, \"$1[redacted]$3\")\n .replace(/((?:authorization|access_token|refresh_token|client_secret|token)=)([^&\\s\"']+)/gi, \"$1[redacted]\")\n .replace(/(authorization:\\s*bearer\\s+)([^\\s,}]+)/gi, \"$1[redacted]\")\n .replace(/(bearer\\s+)(eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)/gi, \"$1[redacted]\");\n}\n","import { assertEnv, type AinectoEnv } from \"../../core/config/endpoints\";\n\nexport interface McpBinArgs {\n env?: AinectoEnv;\n endpoint?: string;\n help: boolean;\n}\n\nexport function parseMcpArgs(argv: string[]): McpBinArgs {\n const result: McpBinArgs = { help: false };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (!arg) {\n continue;\n }\n if (arg === \"--env\") {\n result.env = assertEnv(requireFlagValue(arg, argv[++index]));\n } else if (arg === \"--endpoint\") {\n result.endpoint = requireFlagValue(arg, argv[++index]);\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.help = true;\n } else {\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n return result;\n}\n\nfunction requireFlagValue(flag: string, value: string | undefined): string {\n if (!value || value.startsWith(\"--\")) {\n throw new Error(`${flag} requires a value.`);\n }\n return value;\n}\n","#!/usr/bin/env node\nimport { resolveEndpoint } from \"../core/config/endpoints\";\nimport { runConnector } from \"../adapters/mcp/connector\";\nimport { renderError } from \"../core/output/render\";\nimport { parseMcpArgs } from \"../adapters/mcp/args\";\n\ntry {\n const args = parseMcpArgs(process.argv.slice(2));\n if (args.help) {\n process.stdout.write(\"Usage: mcp [--env prod|dev] [--endpoint URL]\\n\");\n process.exit(0);\n }\n const resolved = resolveEndpoint({ env: args.env, endpoint: args.endpoint });\n await runConnector({\n endpoint: resolved.endpoint,\n input: process.stdin,\n output: process.stdout,\n errorOutput: process.stderr,\n });\n} catch (error) {\n process.stderr.write(renderError(error));\n process.exitCode = 1;\n}\n"],"mappings":"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","names":["createHash","createHash","isRecord","isRecord"]}
|