@ainecto/mcp 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/mcp.js CHANGED
@@ -2,9 +2,13 @@
2
2
 
3
3
  // src/core/config/endpoints.ts
4
4
  var DEFAULT_ENDPOINTS = {
5
- prod: "https://ainecto.com/mcp",
6
- dev: "https://dev.ainecto.com/mcp"
5
+ prod: "https://ai-erd.com/mcp",
6
+ dev: "https://dev.ai-erd.com/mcp"
7
7
  };
8
+ var LEGACY_DEFAULT_ENDPOINTS = [
9
+ "https://ainecto.com/mcp",
10
+ "https://dev.ainecto.com/mcp"
11
+ ];
8
12
  function resolveEndpoint(input = {}) {
9
13
  const envVars = input.envVars ?? process.env;
10
14
  const env = input.env ?? "prod";
@@ -24,7 +28,7 @@ function normalizeEndpoint(endpoint) {
24
28
  }
25
29
  function isDefaultEndpoint(endpoint) {
26
30
  const normalized = normalizeEndpoint(endpoint);
27
- return Object.values(DEFAULT_ENDPOINTS).includes(normalized);
31
+ return Object.values(DEFAULT_ENDPOINTS).includes(normalized) || LEGACY_DEFAULT_ENDPOINTS.includes(normalized);
28
32
  }
29
33
  function assertTrustedEndpointUrl(value, label = "URL") {
30
34
  const url = typeof value === "string" ? new URL(value) : value;
@@ -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 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"]}
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\n/**\n * 기본 MCP 엔드포인트.\n *\n * ★2026-09-21 도메인 전환으로 ai-erd.com 이 «사람이 보는 주소»가 됐고, /mcp 는 두 도메인\n * 모두에서 동일하게 서빙된다(둘 다 같은 인스턴스). 그래서 기본값을 새 도메인으로 옮긴다.\n *\n * ⚠단, OAuth 메타데이터는 아직 ainecto.com 을 가리킨다:\n * WWW-Authenticate resource_metadata=https://ainecto.com/.well-known/oauth-protected-resource/mcp\n * protected-resource resource=https://ainecto.com/mcp · authorization_servers=[https://ainecto.com]\n * authorization-server issuer=https://ainecto.com\n * issuer 는 «발급자 이름»이라 바꾸면 기존 토큰이 전부 무효가 되어 동결돼 있다(전환 계획서 §4-1).\n *\n * 이 CLI 는 issuer/resource 를 요청 호스트와 «대조하지 않고» 서버가 준 메타데이터를 그대로\n * 따라가므로 영향이 없다. ⚠엄격하게 대조하는 다른 MCP 클라이언트는 resource 불일치를\n * 문제 삼을 수 있다 — 그때는 --endpoint 나 AINECTO_MCP_ENDPOINT 로 옛 주소를 쓸 수 있다.\n *\n * 옛 주소도 계속 동작한다. 끊지 않는다.\n */\nconst DEFAULT_ENDPOINTS: Record<AinectoEnv, string> = {\n prod: \"https://ai-erd.com/mcp\",\n dev: \"https://dev.ai-erd.com/mcp\",\n};\n\n/** 옛 기본값 — 이미 설정에 적어둔 사용자가 있다. isDefaultEndpoint 가 이것도 «기본»으로 본다. */\nconst LEGACY_DEFAULT_ENDPOINTS: readonly string[] = [\n \"https://ainecto.com/mcp\",\n \"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 || LEGACY_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"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ainecto/mcp",
3
- "version": "0.1.4",
4
- "description": "Ainecto MCP connector and first-party CLI.",
3
+ "version": "0.2.0",
4
+ "description": "AI-ERD MCP connector and first-party CLI.",
5
5
  "mcpName": "io.github.codelives/ainecto",
6
6
  "type": "module",
7
7
  "private": false,
@@ -17,7 +17,9 @@
17
17
  "bin": {
18
18
  "mcp": "dist/bin/mcp.js",
19
19
  "ainecto-mcp": "dist/bin/mcp.js",
20
- "ainecto": "dist/bin/ainecto.js"
20
+ "ainecto": "dist/bin/ainecto.js",
21
+ "ai-erd": "dist/bin/ainecto.js",
22
+ "ai-erd-mcp": "dist/bin/mcp.js"
21
23
  },
22
24
  "files": [
23
25
  "dist"
@@ -30,7 +32,8 @@
30
32
  "smoke:mcp": "tsx scripts/smoke-mcp.ts",
31
33
  "smoke:attachments": "tsx scripts/smoke-attachment-upload.ts",
32
34
  "catalog:fixture": "vitest run test/catalog.test.ts",
33
- "prepack": "npm run typecheck && npm test && npm run build"
35
+ "prepack": "npm run typecheck && npm test && npm run build",
36
+ "publish:both": "node scripts/publish-both.mjs"
34
37
  },
35
38
  "devDependencies": {
36
39
  "@types/node": "^20.19.8",