@01.software/cli 0.10.0 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/{chunk-CADO6WG6.js → chunk-VSMPWKVX.js} +754 -158
- package/dist/mcp/chunk-VSMPWKVX.js.map +1 -0
- package/dist/mcp/http.js +18 -8
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/stdio.js +1 -1
- package/dist/mcp/vercel.js +772 -166
- package/package.json +17 -9
- package/dist/mcp/chunk-CADO6WG6.js.map +0 -1
package/dist/mcp/http.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
mcpServicePublicJwks,
|
|
12
12
|
requestContext,
|
|
13
13
|
runWithMcpTelemetry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VSMPWKVX.js";
|
|
15
15
|
|
|
16
16
|
// src/transport/http.ts
|
|
17
17
|
import { createServer as createServer2 } from "http";
|
|
@@ -220,7 +220,10 @@ function setCors(res) {
|
|
|
220
220
|
"Access-Control-Allow-Headers",
|
|
221
221
|
"Authorization, Content-Type, mcp-session-id"
|
|
222
222
|
);
|
|
223
|
-
res.setHeader(
|
|
223
|
+
res.setHeader(
|
|
224
|
+
"Access-Control-Expose-Headers",
|
|
225
|
+
"Mcp-Session-Id, Mcp-Protocol-Version"
|
|
226
|
+
);
|
|
224
227
|
}
|
|
225
228
|
function getHeaderValue(headers, name) {
|
|
226
229
|
const value = headers[name.toLowerCase()];
|
|
@@ -300,7 +303,7 @@ HTTP OAuth Tools
|
|
|
300
303
|
----------------
|
|
301
304
|
|
|
302
305
|
Schema get-collection-schema
|
|
303
|
-
Context get-tenant-context
|
|
306
|
+
Context get-tenant-context, check-feature-progress
|
|
304
307
|
Field Config list-configurable-fields, update-field-config
|
|
305
308
|
Guidance sdk-get-recipe, sdk-search-docs, sdk-get-auth-setup, sdk-get-collection-pattern
|
|
306
309
|
|
|
@@ -319,9 +322,9 @@ Resources (12): config, collections-schema, getting-started, guides, api, query-
|
|
|
319
322
|
Links
|
|
320
323
|
-----
|
|
321
324
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
Integrations https://docs.01.software/integrations
|
|
326
|
+
Readiness https://docs.01.software/readiness
|
|
327
|
+
OpenAPI https://docs.01.software/api/openapi
|
|
325
328
|
Console https://console.01.software
|
|
326
329
|
`;
|
|
327
330
|
var PROTECTED_RESOURCE_METADATA = JSON.stringify({
|
|
@@ -344,7 +347,9 @@ function writeOAuthError(res, status, error, description) {
|
|
|
344
347
|
function acceptsEventStream(req) {
|
|
345
348
|
const accept = getHeaderValue(req.headers, "accept");
|
|
346
349
|
if (!accept) return false;
|
|
347
|
-
return accept.split(",").some(
|
|
350
|
+
return accept.split(",").some(
|
|
351
|
+
(entry) => entry.trim().split(";")[0]?.toLowerCase() === "text/event-stream"
|
|
352
|
+
);
|
|
348
353
|
}
|
|
349
354
|
async function handler(req, res) {
|
|
350
355
|
setCors(res);
|
|
@@ -396,7 +401,12 @@ async function handler(req, res) {
|
|
|
396
401
|
getHeaderValue(req.headers, "authorization")
|
|
397
402
|
);
|
|
398
403
|
if (!auth.valid) {
|
|
399
|
-
writeOAuthError(
|
|
404
|
+
writeOAuthError(
|
|
405
|
+
res,
|
|
406
|
+
auth.error === "insufficient_scope" ? 403 : 401,
|
|
407
|
+
auth.error,
|
|
408
|
+
auth.errorDescription
|
|
409
|
+
);
|
|
400
410
|
return;
|
|
401
411
|
}
|
|
402
412
|
const server = createServer({ toolSurface: "oauth" });
|
package/dist/mcp/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transport/http.ts","../src/handler.ts","../src/auth.ts"],"sourcesContent":["import { createServer } from 'node:http'\nimport handler from '../handler'\n\nconst port = parseInt(process.env.PORT || '3001', 10)\n\ncreateServer(handler).listen(port, () => {\n console.log(`MCP server listening on http://localhost:${port}`)\n})\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport {\n MCP_OAUTH_ISSUER,\n MCP_PROTECTED_RESOURCE_METADATA_PATH,\n MCP_RESOURCE_AUDIENCE,\n MCP_SCOPES,\n} from '@01.software/auth-contracts'\nimport { createServer } from './server'\nimport { requestContext } from './lib/request-context'\nimport { validateBearerAuthorizationHeaderAsync } from './auth'\nimport { mcpServicePublicJwks } from './service-auth'\nimport {\n createMcpTelemetrySummary,\n flushMcpTelemetrySummary,\n runWithMcpTelemetry,\n} from './lib/mcp-telemetry'\n\nconst MAX_REQUEST_BODY_BYTES = 1024 * 1024\nconst MCP_ALLOWED_BROWSER_ORIGIN = 'https://01.software'\nconst METHOD_NOT_ALLOWED = JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed.',\n },\n id: null,\n})\n\nfunction setCors(res: ServerResponse) {\n res.setHeader('Access-Control-Allow-Origin', MCP_ALLOWED_BROWSER_ORIGIN)\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Authorization, Content-Type, mcp-session-id',\n )\n res.setHeader('Access-Control-Expose-Headers', 'Mcp-Session-Id, Mcp-Protocol-Version')\n}\n\nfunction getHeaderValue(\n headers: IncomingMessage['headers'],\n name: string,\n): string | undefined {\n const value = headers[name.toLowerCase()]\n if (Array.isArray(value)) return value[0]\n return value\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n req.on('data', (chunk: Buffer) => {\n size += chunk.length\n if (size > MAX_REQUEST_BODY_BYTES) {\n req.destroy()\n reject(new Error('Request body too large'))\n return\n }\n chunks.push(chunk)\n })\n req.on('end', () => resolve(Buffer.concat(chunks).toString()))\n req.on('error', reject)\n })\n}\n\nconst HOME_PAGE = `01.software MCP Server\n======================\n\nMCP server for AI agents to interact with the 01.software API.\nConnect over HTTP with OAuth, or use the local CLI stdio transport for full\nserver-key operations.\n\n\nAuthentication\n--------------\n\nHTTP MCP uses OAuth discovery and Authorization Code + PKCE.\nClients should connect to:\n\nConnect\n-------\n\nClaude Code:\n\n claude mcp add --transport http 01software https://mcp.01.software/mcp\n\nCodex (.codex/config.toml):\n\n [mcp_servers.01software]\n url = \"https://mcp.01.software/mcp\"\n\nCursor / Claude Desktop / other JSON clients:\n\n {\n \"mcpServers\": {\n \"01software\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.01.software/mcp\"\n }\n }\n }\n\nWindsurf (~/.codeium/windsurf/mcp_config.json):\n\n {\n \"mcpServers\": {\n \"01software\": {\n \"serverUrl\": \"https://mcp.01.software/mcp\"\n }\n }\n }\n\nCLI (stdio):\n\n npx @01.software/cli mcp\n\n\nHTTP OAuth Tools\n----------------\n\nSchema get-collection-schema\nContext get-tenant-context\nField Config list-configurable-fields, update-field-config\nGuidance sdk-get-recipe, sdk-search-docs, sdk-get-auth-setup, sdk-get-collection-pattern\n\nFull Tool Surface\n-----------------\n\nThe local CLI stdio transport exposes CRUD, commerce, cart, validation, product,\nschema, context, field-config, and guidance tools:\n\n npx @01.software/cli mcp\n\nPrompts (4): sdk-usage-guide, collection-query-help, order-flow-guide, feature-setup-guide\nResources (12): config, collections-schema, getting-started, guides, api, query-builder, react-query, server-api, customer-auth, browser-vs-server, file-upload, webhook\n\n\nLinks\n-----\n\nDocs https://docs.01.software/docs/developers/integrations/mcp\nSDK https://docs.01.software/docs/developers/sdk/client\nAPI Reference https://docs.01.software/docs/developers/api/rest-api\nConsole https://console.01.software\n`\n\nconst PROTECTED_RESOURCE_METADATA = JSON.stringify({\n resource: MCP_RESOURCE_AUDIENCE,\n authorization_servers: [MCP_OAUTH_ISSUER],\n scopes_supported: [MCP_SCOPES.read, MCP_SCOPES.write],\n})\nconst PROTECTED_RESOURCE_METADATA_URL = new URL(\n MCP_PROTECTED_RESOURCE_METADATA_PATH,\n MCP_RESOURCE_AUDIENCE,\n).toString()\nconst SERVICE_JWKS_PATH = '/.well-known/service-jwks.json'\n\nfunction writeOAuthError(res: ServerResponse, status: number, error: string, description: string) {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': `Bearer resource_metadata=\"${PROTECTED_RESOURCE_METADATA_URL}\", error=\"${error}\", error_description=\"${description}\"`,\n })\n res.end(JSON.stringify({ error, error_description: description }))\n}\n\nfunction acceptsEventStream(req: IncomingMessage): boolean {\n const accept = getHeaderValue(req.headers, 'accept')\n if (!accept) return false\n return accept\n .split(',')\n .some((entry) => entry.trim().split(';')[0]?.toLowerCase() === 'text/event-stream')\n}\n\nexport default async function handler(req: IncomingMessage, res: ServerResponse) {\n setCors(res)\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method === 'GET') {\n const pathname = new URL(req.url ?? '/', MCP_RESOURCE_AUDIENCE).pathname\n if (pathname === MCP_PROTECTED_RESOURCE_METADATA_PATH) {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(PROTECTED_RESOURCE_METADATA)\n return\n }\n\n if (pathname === SERVICE_JWKS_PATH) {\n res.setHeader('Access-Control-Allow-Origin', '*')\n try {\n res.writeHead(200, {\n 'Cache-Control': 'public, max-age=60',\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify(mcpServicePublicJwks()))\n } catch {\n res.writeHead(503, {\n 'Cache-Control': 'no-store',\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify({ keys: [] }))\n }\n return\n }\n\n if (acceptsEventStream(req)) {\n res.writeHead(405, { 'Content-Type': 'application/json' })\n res.end(METHOD_NOT_ALLOWED)\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })\n res.end(HOME_PAGE)\n return\n }\n\n // Stateless Streamable HTTP should only accept POST requests.\n if (req.method !== 'POST') {\n res.writeHead(405, { 'Content-Type': 'application/json' })\n res.end(METHOD_NOT_ALLOWED)\n return\n }\n\n const auth = await validateBearerAuthorizationHeaderAsync(\n getHeaderValue(req.headers, 'authorization'),\n )\n if (!auth.valid) {\n writeOAuthError(res, auth.error === 'insufficient_scope' ? 403 : 401, auth.error, auth.errorDescription)\n return\n }\n\n const server = createServer({ toolSurface: 'oauth' })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n let closed = false\n\n const close = async () => {\n if (closed) return\n closed = true\n await transport.close()\n await server.close()\n }\n\n res.on('close', () => {\n void close()\n })\n\n await server.connect(transport)\n\n const headers = new Headers()\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') headers.set(key, value)\n else if (Array.isArray(value)) headers.set(key, value.join(', '))\n }\n\n const telemetrySummary = createMcpTelemetrySummary('http')\n\n await requestContext.run({ headers, auth: auth.context }, async () => {\n try {\n await runWithMcpTelemetry(telemetrySummary, async () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const body = (req as any).body ?? JSON.parse(await readBody(req))\n await transport.handleRequest(req, res, body)\n })\n } catch (err) {\n writeRequestError(res, err)\n } finally {\n telemetrySummary.durationMs =\n Date.now() - telemetrySummary.startedAtMs\n await close()\n await flushMcpTelemetrySummary(telemetrySummary)\n }\n })\n}\n\nfunction writeRequestError(res: ServerResponse, err: unknown) {\n if (res.headersSent) return\n if (err instanceof SyntaxError) {\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n return\n }\n if (err instanceof Error && err.message === 'Request body too large') {\n res.writeHead(413, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Request body too large' }))\n return\n }\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Internal server error' }))\n}\n","import { createPublicKey, verify as verifySignature } from 'node:crypto'\nimport {\n MCP_OAUTH_ISSUER,\n MCP_RESOURCE_AUDIENCE,\n MCP_SCOPES,\n MCP_TENANT_CLAIM,\n MCP_TENANT_ROLE_CLAIM,\n} from '@01.software/auth-contracts'\n\nconst ALLOWED_ALGORITHMS = new Set(['RS256', 'ES256'])\nconst DEFAULT_CLOCK_SKEW_SECONDS = 30\nconst DEFAULT_JWKS_URI = `${MCP_OAUTH_ISSUER}/.well-known/jwks.json`\nconst MAX_ACCESS_TOKEN_LIFETIME_SECONDS = 300\ntype McpScope = (typeof MCP_SCOPES)[keyof typeof MCP_SCOPES]\ntype McpTenantRole = 'tenant-admin' | 'tenant-editor' | 'tenant-viewer'\n\ninterface JwtHeader {\n alg?: unknown\n kid?: unknown\n}\n\ninterface JwtPayload {\n aud?: unknown\n exp?: unknown\n iat?: unknown\n iss?: unknown\n nbf?: unknown\n scope?: unknown\n scp?: unknown\n sub?: unknown\n [MCP_TENANT_CLAIM]?: unknown\n [MCP_TENANT_ROLE_CLAIM]?: unknown\n}\n\nexport interface TenantAuthContext {\n tenantId: string\n principalId?: string\n scopes: McpScope[]\n tenantRole: McpTenantRole\n authMode: 'oauth'\n}\n\nexport type AuthResult =\n | {\n valid: true\n context: TenantAuthContext\n }\n | {\n valid: false\n error: 'invalid_token' | 'insufficient_scope'\n errorDescription: string\n context?: undefined\n }\n\nexport interface JsonWebKeySet {\n keys: Array<Record<string, unknown>>\n}\n\nexport interface ValidateAccessTokenOptions {\n audience?: string\n clockSkewSeconds?: number\n fetchImpl?: typeof fetch\n issuer?: string\n jwks?: JsonWebKeySet\n jwksUri?: string\n now?: Date\n requiredScopes?: McpScope[]\n}\n\nfunction invalid(errorDescription: string): AuthResult {\n return { valid: false, error: 'invalid_token', errorDescription }\n}\n\nfunction isProduction(): boolean {\n return process.env.NODE_ENV === 'production'\n}\n\nfunction insufficientScope(errorDescription: string): AuthResult {\n return { valid: false, error: 'insufficient_scope', errorDescription }\n}\n\nfunction decodeBase64UrlJson<T>(value: string): T | null {\n try {\n return JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as T\n } catch {\n return null\n }\n}\n\nfunction parseScopes(payload: JwtPayload): McpScope[] {\n const rawScopes =\n typeof payload.scope === 'string'\n ? payload.scope.split(/\\s+/).filter(Boolean)\n : Array.isArray(payload.scp)\n ? payload.scp\n : []\n\n return rawScopes.filter(\n (scope): scope is McpScope =>\n scope === MCP_SCOPES.read || scope === MCP_SCOPES.write,\n )\n}\n\nfunction audienceMatches(aud: unknown, expected: string): boolean {\n if (typeof aud === 'string') return aud === expected\n return Array.isArray(aud) && aud.includes(expected)\n}\n\nfunction verifyJwtSignature(\n alg: string,\n jwk: Record<string, unknown>,\n signingInput: string,\n signature: Buffer,\n): boolean {\n const key = createPublicKey({ key: jwk, format: 'jwk' })\n const input = Buffer.from(signingInput)\n\n if (alg === 'RS256') {\n return verifySignature('RSA-SHA256', input, key, signature)\n }\n\n if (alg === 'ES256') {\n return verifySignature('SHA256', input, { key, dsaEncoding: 'ieee-p1363' }, signature)\n }\n\n return false\n}\n\nlet cachedRemoteJwks:\n | { expiresAt: number; jwks: JsonWebKeySet; uri: string }\n | null = null\n\nfunction jwksUriFor(options: ValidateAccessTokenOptions): string | null {\n const raw = isProduction()\n ? DEFAULT_JWKS_URI\n : options.jwksUri ?? DEFAULT_JWKS_URI\n let url: URL\n try {\n url = new URL(raw)\n } catch {\n return null\n }\n if (\n url.protocol !== 'https:' ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n ) {\n return null\n }\n return url.toString()\n}\n\nasync function remoteJwks(\n options: ValidateAccessTokenOptions = {},\n forceRefresh = false,\n): Promise<JsonWebKeySet | null> {\n const uri = jwksUriFor(options)\n if (!uri) return null\n const now = Date.now()\n if (\n !forceRefresh &&\n cachedRemoteJwks &&\n cachedRemoteJwks.uri === uri &&\n cachedRemoteJwks.expiresAt > now\n ) {\n return cachedRemoteJwks.jwks\n }\n\n const fetchImpl = options.fetchImpl ?? fetch\n let response: Response\n try {\n response = await fetchImpl(uri, {\n headers: { Accept: 'application/json' },\n })\n } catch {\n return null\n }\n if (!response.ok) return null\n const parsed = (await response.json().catch(() => null)) as JsonWebKeySet | null\n if (!parsed || !Array.isArray(parsed.keys)) return null\n cachedRemoteJwks = {\n expiresAt: now + 300_000,\n jwks: parsed,\n uri,\n }\n return parsed\n}\n\nexport function validateAccessToken(\n token: string,\n options: ValidateAccessTokenOptions = {},\n): AuthResult {\n const parts = token.split('.')\n if (parts.length !== 3 || parts.some((part) => part.length === 0)) {\n return invalid('Bearer token must be a compact JWT')\n }\n\n const [encodedHeader, encodedPayload, encodedSignature] = parts\n const header = decodeBase64UrlJson<JwtHeader>(encodedHeader)\n const payload = decodeBase64UrlJson<JwtPayload>(encodedPayload)\n if (!header || !payload) return invalid('Bearer token contains invalid JSON')\n\n if (typeof header.alg !== 'string' || !ALLOWED_ALGORITHMS.has(header.alg)) {\n return invalid('Bearer token uses an unsupported signing algorithm')\n }\n\n if (typeof header.kid !== 'string' || header.kid.length === 0) {\n return invalid('Bearer token is missing kid')\n }\n\n const jwks = options.jwks\n if (!jwks) return invalid('JWKS is not configured')\n\n const jwk = jwks.keys.find((key) => key.kid === header.kid)\n if (!jwk) return invalid('Bearer token kid is unknown')\n\n const signingInput = `${encodedHeader}.${encodedPayload}`\n const signature = Buffer.from(encodedSignature, 'base64url')\n if (!verifyJwtSignature(header.alg, jwk, signingInput, signature)) {\n return invalid('Bearer token signature is invalid')\n }\n\n const issuer = options.issuer ?? MCP_OAUTH_ISSUER\n if (payload.iss !== issuer) return invalid('Bearer token issuer is invalid')\n\n const audience = options.audience ?? MCP_RESOURCE_AUDIENCE\n if (!audienceMatches(payload.aud, audience)) {\n return invalid('Bearer token audience is invalid')\n }\n\n if (typeof payload.iat !== 'number') return invalid('Bearer token is missing iat')\n if (typeof payload.exp !== 'number') return invalid('Bearer token is missing exp')\n if (payload.exp <= payload.iat) {\n return invalid('Bearer token lifetime is invalid')\n }\n if (payload.exp - payload.iat > MAX_ACCESS_TOKEN_LIFETIME_SECONDS) {\n return invalid('Bearer token lifetime exceeds 300 seconds')\n }\n\n const nowSeconds = Math.floor((options.now ?? new Date()).getTime() / 1000)\n const leeway = options.clockSkewSeconds ?? DEFAULT_CLOCK_SKEW_SECONDS\n if (payload.iat > nowSeconds + leeway) {\n return invalid('Bearer token iat is too far in the future')\n }\n if (typeof payload.nbf === 'number' && payload.nbf > nowSeconds + leeway) {\n return invalid('Bearer token is not yet valid')\n }\n if (payload.exp < nowSeconds - leeway) return invalid('Bearer token is expired')\n\n const tenantId = payload[MCP_TENANT_CLAIM]\n if (typeof tenantId !== 'string' || tenantId.length === 0) {\n return invalid('Bearer token tenant_id claim is invalid')\n }\n\n const tenantRole = payload[MCP_TENANT_ROLE_CLAIM]\n if (\n tenantRole !== 'tenant-admin' &&\n tenantRole !== 'tenant-editor' &&\n tenantRole !== 'tenant-viewer'\n ) {\n return invalid('Bearer token tenant_role claim is invalid')\n }\n\n if (typeof payload.sub !== 'string' || payload.sub.length === 0) {\n return invalid('Bearer token subject claim is invalid')\n }\n\n const scopes = parseScopes(payload)\n const requiredScopes = options.requiredScopes ?? [MCP_SCOPES.read]\n const missingScope = requiredScopes.find((scope) => !scopes.includes(scope))\n if (missingScope) return insufficientScope(`Bearer token is missing ${missingScope}`)\n\n return {\n valid: true,\n context: {\n tenantId,\n principalId: payload.sub,\n scopes,\n tenantRole,\n authMode: 'oauth',\n },\n }\n}\n\nexport function validateBearerAuthorizationHeader(\n authorization: string | null | undefined,\n options?: ValidateAccessTokenOptions,\n): AuthResult {\n if (!authorization) return invalid('Authorization Bearer token is required')\n\n const match = authorization.match(/^Bearer\\s+(.+)$/i)\n if (!match) return invalid('Authorization header must use Bearer')\n\n return validateAccessToken(match[1], options)\n}\n\nfunction shouldRefreshRemoteJwks(result: AuthResult): boolean {\n return (\n !result.valid &&\n (\n result.errorDescription === 'Bearer token kid is unknown' ||\n result.errorDescription === 'Bearer token signature is invalid'\n )\n )\n}\n\nexport async function validateBearerAuthorizationHeaderAsync(\n authorization: string | null | undefined,\n options?: ValidateAccessTokenOptions,\n): Promise<AuthResult> {\n if (!authorization) return invalid('Authorization Bearer token is required')\n\n const match = authorization.match(/^Bearer\\s+(.+)$/i)\n if (!match) return invalid('Authorization header must use Bearer')\n\n if (options?.jwks) {\n return validateAccessToken(match[1], options)\n }\n\n const jwks = await remoteJwks(options)\n const result = validateAccessToken(match[1], {\n ...options,\n jwks: jwks ?? undefined,\n })\n\n if (shouldRefreshRemoteJwks(result)) {\n const refreshedJwks = await remoteJwks(options, true)\n if (refreshedJwks) {\n return validateAccessToken(match[1], {\n ...options,\n jwks: refreshedJwks,\n })\n }\n }\n\n return result\n}\n"],"mappings":"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","names":["createServer","createServer"]}
|
|
1
|
+
{"version":3,"sources":["../src/transport/http.ts","../src/handler.ts","../src/auth.ts"],"sourcesContent":["import { createServer } from 'node:http'\nimport handler from '../handler'\n\nconst port = parseInt(process.env.PORT || '3001', 10)\n\ncreateServer(handler).listen(port, () => {\n console.log(`MCP server listening on http://localhost:${port}`)\n})\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport {\n MCP_OAUTH_ISSUER,\n MCP_PROTECTED_RESOURCE_METADATA_PATH,\n MCP_RESOURCE_AUDIENCE,\n MCP_SCOPES,\n} from '@01.software/auth-contracts'\nimport { createServer } from './server'\nimport { requestContext } from './lib/request-context'\nimport { validateBearerAuthorizationHeaderAsync } from './auth'\nimport { mcpServicePublicJwks } from './service-auth'\nimport {\n createMcpTelemetrySummary,\n flushMcpTelemetrySummary,\n runWithMcpTelemetry,\n} from './lib/mcp-telemetry'\n\nconst MAX_REQUEST_BODY_BYTES = 1024 * 1024\nconst MCP_ALLOWED_BROWSER_ORIGIN = 'https://01.software'\nconst METHOD_NOT_ALLOWED = JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed.',\n },\n id: null,\n})\n\nfunction setCors(res: ServerResponse) {\n res.setHeader('Access-Control-Allow-Origin', MCP_ALLOWED_BROWSER_ORIGIN)\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Authorization, Content-Type, mcp-session-id',\n )\n res.setHeader(\n 'Access-Control-Expose-Headers',\n 'Mcp-Session-Id, Mcp-Protocol-Version',\n )\n}\n\nfunction getHeaderValue(\n headers: IncomingMessage['headers'],\n name: string,\n): string | undefined {\n const value = headers[name.toLowerCase()]\n if (Array.isArray(value)) return value[0]\n return value\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n req.on('data', (chunk: Buffer) => {\n size += chunk.length\n if (size > MAX_REQUEST_BODY_BYTES) {\n req.destroy()\n reject(new Error('Request body too large'))\n return\n }\n chunks.push(chunk)\n })\n req.on('end', () => resolve(Buffer.concat(chunks).toString()))\n req.on('error', reject)\n })\n}\n\nconst HOME_PAGE = `01.software MCP Server\n======================\n\nMCP server for AI agents to interact with the 01.software API.\nConnect over HTTP with OAuth, or use the local CLI stdio transport for full\nserver-key operations.\n\n\nAuthentication\n--------------\n\nHTTP MCP uses OAuth discovery and Authorization Code + PKCE.\nClients should connect to:\n\nConnect\n-------\n\nClaude Code:\n\n claude mcp add --transport http 01software https://mcp.01.software/mcp\n\nCodex (.codex/config.toml):\n\n [mcp_servers.01software]\n url = \"https://mcp.01.software/mcp\"\n\nCursor / Claude Desktop / other JSON clients:\n\n {\n \"mcpServers\": {\n \"01software\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.01.software/mcp\"\n }\n }\n }\n\nWindsurf (~/.codeium/windsurf/mcp_config.json):\n\n {\n \"mcpServers\": {\n \"01software\": {\n \"serverUrl\": \"https://mcp.01.software/mcp\"\n }\n }\n }\n\nCLI (stdio):\n\n npx @01.software/cli mcp\n\n\nHTTP OAuth Tools\n----------------\n\nSchema get-collection-schema\nContext get-tenant-context, check-feature-progress\nField Config list-configurable-fields, update-field-config\nGuidance sdk-get-recipe, sdk-search-docs, sdk-get-auth-setup, sdk-get-collection-pattern\n\nFull Tool Surface\n-----------------\n\nThe local CLI stdio transport exposes CRUD, commerce, cart, validation, product,\nschema, context, field-config, and guidance tools:\n\n npx @01.software/cli mcp\n\nPrompts (4): sdk-usage-guide, collection-query-help, order-flow-guide, feature-setup-guide\nResources (12): config, collections-schema, getting-started, guides, api, query-builder, react-query, server-api, customer-auth, browser-vs-server, file-upload, webhook\n\n\nLinks\n-----\n\nIntegrations https://docs.01.software/integrations\nReadiness https://docs.01.software/readiness\nOpenAPI https://docs.01.software/api/openapi\nConsole https://console.01.software\n`\n\nconst PROTECTED_RESOURCE_METADATA = JSON.stringify({\n resource: MCP_RESOURCE_AUDIENCE,\n authorization_servers: [MCP_OAUTH_ISSUER],\n scopes_supported: [MCP_SCOPES.read, MCP_SCOPES.write],\n})\nconst PROTECTED_RESOURCE_METADATA_URL = new URL(\n MCP_PROTECTED_RESOURCE_METADATA_PATH,\n MCP_RESOURCE_AUDIENCE,\n).toString()\nconst SERVICE_JWKS_PATH = '/.well-known/service-jwks.json'\n\nfunction writeOAuthError(\n res: ServerResponse,\n status: number,\n error: string,\n description: string,\n) {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': `Bearer resource_metadata=\"${PROTECTED_RESOURCE_METADATA_URL}\", error=\"${error}\", error_description=\"${description}\"`,\n })\n res.end(JSON.stringify({ error, error_description: description }))\n}\n\nfunction acceptsEventStream(req: IncomingMessage): boolean {\n const accept = getHeaderValue(req.headers, 'accept')\n if (!accept) return false\n return accept\n .split(',')\n .some(\n (entry) =>\n entry.trim().split(';')[0]?.toLowerCase() === 'text/event-stream',\n )\n}\n\nexport default async function handler(\n req: IncomingMessage,\n res: ServerResponse,\n) {\n setCors(res)\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method === 'GET') {\n const pathname = new URL(req.url ?? '/', MCP_RESOURCE_AUDIENCE).pathname\n if (pathname === MCP_PROTECTED_RESOURCE_METADATA_PATH) {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(PROTECTED_RESOURCE_METADATA)\n return\n }\n\n if (pathname === SERVICE_JWKS_PATH) {\n res.setHeader('Access-Control-Allow-Origin', '*')\n try {\n res.writeHead(200, {\n 'Cache-Control': 'public, max-age=60',\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify(mcpServicePublicJwks()))\n } catch {\n res.writeHead(503, {\n 'Cache-Control': 'no-store',\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify({ keys: [] }))\n }\n return\n }\n\n if (acceptsEventStream(req)) {\n res.writeHead(405, { 'Content-Type': 'application/json' })\n res.end(METHOD_NOT_ALLOWED)\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })\n res.end(HOME_PAGE)\n return\n }\n\n // Stateless Streamable HTTP should only accept POST requests.\n if (req.method !== 'POST') {\n res.writeHead(405, { 'Content-Type': 'application/json' })\n res.end(METHOD_NOT_ALLOWED)\n return\n }\n\n const auth = await validateBearerAuthorizationHeaderAsync(\n getHeaderValue(req.headers, 'authorization'),\n )\n if (!auth.valid) {\n writeOAuthError(\n res,\n auth.error === 'insufficient_scope' ? 403 : 401,\n auth.error,\n auth.errorDescription,\n )\n return\n }\n\n const server = createServer({ toolSurface: 'oauth' })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n let closed = false\n\n const close = async () => {\n if (closed) return\n closed = true\n await transport.close()\n await server.close()\n }\n\n res.on('close', () => {\n void close()\n })\n\n await server.connect(transport)\n\n const headers = new Headers()\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') headers.set(key, value)\n else if (Array.isArray(value)) headers.set(key, value.join(', '))\n }\n\n const telemetrySummary = createMcpTelemetrySummary('http')\n\n await requestContext.run({ headers, auth: auth.context }, async () => {\n try {\n await runWithMcpTelemetry(telemetrySummary, async () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const body = (req as any).body ?? JSON.parse(await readBody(req))\n await transport.handleRequest(req, res, body)\n })\n } catch (err) {\n writeRequestError(res, err)\n } finally {\n telemetrySummary.durationMs = Date.now() - telemetrySummary.startedAtMs\n await close()\n await flushMcpTelemetrySummary(telemetrySummary)\n }\n })\n}\n\nfunction writeRequestError(res: ServerResponse, err: unknown) {\n if (res.headersSent) return\n if (err instanceof SyntaxError) {\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n return\n }\n if (err instanceof Error && err.message === 'Request body too large') {\n res.writeHead(413, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Request body too large' }))\n return\n }\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Internal server error' }))\n}\n","import { createPublicKey, verify as verifySignature } from 'node:crypto'\nimport {\n MCP_OAUTH_ISSUER,\n MCP_RESOURCE_AUDIENCE,\n MCP_SCOPES,\n MCP_TENANT_CLAIM,\n MCP_TENANT_ROLE_CLAIM,\n} from '@01.software/auth-contracts'\n\nconst ALLOWED_ALGORITHMS = new Set(['RS256', 'ES256'])\nconst DEFAULT_CLOCK_SKEW_SECONDS = 30\nconst DEFAULT_JWKS_URI = `${MCP_OAUTH_ISSUER}/.well-known/jwks.json`\nconst MAX_ACCESS_TOKEN_LIFETIME_SECONDS = 300\ntype McpScope = (typeof MCP_SCOPES)[keyof typeof MCP_SCOPES]\ntype McpTenantRole = 'tenant-admin' | 'tenant-editor' | 'tenant-viewer'\n\ninterface JwtHeader {\n alg?: unknown\n kid?: unknown\n}\n\ninterface JwtPayload {\n aud?: unknown\n exp?: unknown\n iat?: unknown\n iss?: unknown\n nbf?: unknown\n scope?: unknown\n scp?: unknown\n sub?: unknown\n [MCP_TENANT_CLAIM]?: unknown\n [MCP_TENANT_ROLE_CLAIM]?: unknown\n}\n\nexport interface TenantAuthContext {\n tenantId: string\n principalId?: string\n scopes: McpScope[]\n tenantRole: McpTenantRole\n authMode: 'oauth'\n}\n\nexport type AuthResult =\n | {\n valid: true\n context: TenantAuthContext\n }\n | {\n valid: false\n error: 'invalid_token' | 'insufficient_scope'\n errorDescription: string\n context?: undefined\n }\n\nexport interface JsonWebKeySet {\n keys: Array<Record<string, unknown>>\n}\n\nexport interface ValidateAccessTokenOptions {\n audience?: string\n clockSkewSeconds?: number\n fetchImpl?: typeof fetch\n issuer?: string\n jwks?: JsonWebKeySet\n jwksUri?: string\n now?: Date\n requiredScopes?: McpScope[]\n}\n\nfunction invalid(errorDescription: string): AuthResult {\n return { valid: false, error: 'invalid_token', errorDescription }\n}\n\nfunction isProduction(): boolean {\n return process.env.NODE_ENV === 'production'\n}\n\nfunction insufficientScope(errorDescription: string): AuthResult {\n return { valid: false, error: 'insufficient_scope', errorDescription }\n}\n\nfunction decodeBase64UrlJson<T>(value: string): T | null {\n try {\n return JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as T\n } catch {\n return null\n }\n}\n\nfunction parseScopes(payload: JwtPayload): McpScope[] {\n const rawScopes =\n typeof payload.scope === 'string'\n ? payload.scope.split(/\\s+/).filter(Boolean)\n : Array.isArray(payload.scp)\n ? payload.scp\n : []\n\n return rawScopes.filter(\n (scope): scope is McpScope =>\n scope === MCP_SCOPES.read || scope === MCP_SCOPES.write,\n )\n}\n\nfunction audienceMatches(aud: unknown, expected: string): boolean {\n if (typeof aud === 'string') return aud === expected\n return Array.isArray(aud) && aud.includes(expected)\n}\n\nfunction verifyJwtSignature(\n alg: string,\n jwk: Record<string, unknown>,\n signingInput: string,\n signature: Buffer,\n): boolean {\n const key = createPublicKey({ key: jwk, format: 'jwk' })\n const input = Buffer.from(signingInput)\n\n if (alg === 'RS256') {\n return verifySignature('RSA-SHA256', input, key, signature)\n }\n\n if (alg === 'ES256') {\n return verifySignature('SHA256', input, { key, dsaEncoding: 'ieee-p1363' }, signature)\n }\n\n return false\n}\n\nlet cachedRemoteJwks:\n | { expiresAt: number; jwks: JsonWebKeySet; uri: string }\n | null = null\n\nfunction jwksUriFor(options: ValidateAccessTokenOptions): string | null {\n const raw = isProduction()\n ? DEFAULT_JWKS_URI\n : options.jwksUri ?? DEFAULT_JWKS_URI\n let url: URL\n try {\n url = new URL(raw)\n } catch {\n return null\n }\n if (\n url.protocol !== 'https:' ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n ) {\n return null\n }\n return url.toString()\n}\n\nasync function remoteJwks(\n options: ValidateAccessTokenOptions = {},\n forceRefresh = false,\n): Promise<JsonWebKeySet | null> {\n const uri = jwksUriFor(options)\n if (!uri) return null\n const now = Date.now()\n if (\n !forceRefresh &&\n cachedRemoteJwks &&\n cachedRemoteJwks.uri === uri &&\n cachedRemoteJwks.expiresAt > now\n ) {\n return cachedRemoteJwks.jwks\n }\n\n const fetchImpl = options.fetchImpl ?? fetch\n let response: Response\n try {\n response = await fetchImpl(uri, {\n headers: { Accept: 'application/json' },\n })\n } catch {\n return null\n }\n if (!response.ok) return null\n const parsed = (await response.json().catch(() => null)) as JsonWebKeySet | null\n if (!parsed || !Array.isArray(parsed.keys)) return null\n cachedRemoteJwks = {\n expiresAt: now + 300_000,\n jwks: parsed,\n uri,\n }\n return parsed\n}\n\nexport function validateAccessToken(\n token: string,\n options: ValidateAccessTokenOptions = {},\n): AuthResult {\n const parts = token.split('.')\n if (parts.length !== 3 || parts.some((part) => part.length === 0)) {\n return invalid('Bearer token must be a compact JWT')\n }\n\n const [encodedHeader, encodedPayload, encodedSignature] = parts\n const header = decodeBase64UrlJson<JwtHeader>(encodedHeader)\n const payload = decodeBase64UrlJson<JwtPayload>(encodedPayload)\n if (!header || !payload) return invalid('Bearer token contains invalid JSON')\n\n if (typeof header.alg !== 'string' || !ALLOWED_ALGORITHMS.has(header.alg)) {\n return invalid('Bearer token uses an unsupported signing algorithm')\n }\n\n if (typeof header.kid !== 'string' || header.kid.length === 0) {\n return invalid('Bearer token is missing kid')\n }\n\n const jwks = options.jwks\n if (!jwks) return invalid('JWKS is not configured')\n\n const jwk = jwks.keys.find((key) => key.kid === header.kid)\n if (!jwk) return invalid('Bearer token kid is unknown')\n\n const signingInput = `${encodedHeader}.${encodedPayload}`\n const signature = Buffer.from(encodedSignature, 'base64url')\n if (!verifyJwtSignature(header.alg, jwk, signingInput, signature)) {\n return invalid('Bearer token signature is invalid')\n }\n\n const issuer = options.issuer ?? MCP_OAUTH_ISSUER\n if (payload.iss !== issuer) return invalid('Bearer token issuer is invalid')\n\n const audience = options.audience ?? MCP_RESOURCE_AUDIENCE\n if (!audienceMatches(payload.aud, audience)) {\n return invalid('Bearer token audience is invalid')\n }\n\n if (typeof payload.iat !== 'number') return invalid('Bearer token is missing iat')\n if (typeof payload.exp !== 'number') return invalid('Bearer token is missing exp')\n if (payload.exp <= payload.iat) {\n return invalid('Bearer token lifetime is invalid')\n }\n if (payload.exp - payload.iat > MAX_ACCESS_TOKEN_LIFETIME_SECONDS) {\n return invalid('Bearer token lifetime exceeds 300 seconds')\n }\n\n const nowSeconds = Math.floor((options.now ?? new Date()).getTime() / 1000)\n const leeway = options.clockSkewSeconds ?? DEFAULT_CLOCK_SKEW_SECONDS\n if (payload.iat > nowSeconds + leeway) {\n return invalid('Bearer token iat is too far in the future')\n }\n if (typeof payload.nbf === 'number' && payload.nbf > nowSeconds + leeway) {\n return invalid('Bearer token is not yet valid')\n }\n if (payload.exp < nowSeconds - leeway) return invalid('Bearer token is expired')\n\n const tenantId = payload[MCP_TENANT_CLAIM]\n if (typeof tenantId !== 'string' || tenantId.length === 0) {\n return invalid('Bearer token tenant_id claim is invalid')\n }\n\n const tenantRole = payload[MCP_TENANT_ROLE_CLAIM]\n if (\n tenantRole !== 'tenant-admin' &&\n tenantRole !== 'tenant-editor' &&\n tenantRole !== 'tenant-viewer'\n ) {\n return invalid('Bearer token tenant_role claim is invalid')\n }\n\n if (typeof payload.sub !== 'string' || payload.sub.length === 0) {\n return invalid('Bearer token subject claim is invalid')\n }\n\n const scopes = parseScopes(payload)\n const requiredScopes = options.requiredScopes ?? [MCP_SCOPES.read]\n const missingScope = requiredScopes.find((scope) => !scopes.includes(scope))\n if (missingScope) return insufficientScope(`Bearer token is missing ${missingScope}`)\n\n return {\n valid: true,\n context: {\n tenantId,\n principalId: payload.sub,\n scopes,\n tenantRole,\n authMode: 'oauth',\n },\n }\n}\n\nexport function validateBearerAuthorizationHeader(\n authorization: string | null | undefined,\n options?: ValidateAccessTokenOptions,\n): AuthResult {\n if (!authorization) return invalid('Authorization Bearer token is required')\n\n const match = authorization.match(/^Bearer\\s+(.+)$/i)\n if (!match) return invalid('Authorization header must use Bearer')\n\n return validateAccessToken(match[1], options)\n}\n\nfunction shouldRefreshRemoteJwks(result: AuthResult): boolean {\n return (\n !result.valid &&\n (\n result.errorDescription === 'Bearer token kid is unknown' ||\n result.errorDescription === 'Bearer token signature is invalid'\n )\n )\n}\n\nexport async function validateBearerAuthorizationHeaderAsync(\n authorization: string | null | undefined,\n options?: ValidateAccessTokenOptions,\n): Promise<AuthResult> {\n if (!authorization) return invalid('Authorization Bearer token is required')\n\n const match = authorization.match(/^Bearer\\s+(.+)$/i)\n if (!match) return invalid('Authorization header must use Bearer')\n\n if (options?.jwks) {\n return validateAccessToken(match[1], options)\n }\n\n const jwks = await remoteJwks(options)\n const result = validateAccessToken(match[1], {\n ...options,\n jwks: jwks ?? undefined,\n })\n\n if (shouldRefreshRemoteJwks(result)) {\n const refreshedJwks = await remoteJwks(options, true)\n if (refreshedJwks) {\n return validateAccessToken(match[1], {\n ...options,\n jwks: refreshedJwks,\n })\n }\n }\n\n return result\n}\n"],"mappings":"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","names":["createServer","createServer"]}
|