@studiometa/forge-mcp 0.4.5 → 0.4.6
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/formatters.d.ts +12 -0
- package/dist/formatters.d.ts.map +1 -1
- package/dist/handlers/daemons.d.ts.map +1 -1
- package/dist/handlers/help.d.ts.map +1 -1
- package/dist/handlers/index.d.ts.map +1 -1
- package/dist/handlers/schema.d.ts.map +1 -1
- package/dist/handlers/services.d.ts +2 -0
- package/dist/handlers/services.d.ts.map +1 -0
- package/dist/{http-DVoeL5Wa.js → http-CwlifGMb.js} +2 -2
- package/dist/{http-DVoeL5Wa.js.map → http-CwlifGMb.js.map} +1 -1
- package/dist/http.js +1 -1
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/dist/tools.d.ts +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/{version-BdjPN_IX.js → version-BS77BDou.js} +132 -9
- package/dist/version-BS77BDou.js.map +1 -0
- package/package.json +3 -3
- package/dist/version-BdjPN_IX.js.map +0 -1
package/dist/formatters.d.ts
CHANGED
|
@@ -107,6 +107,10 @@ export declare function formatDaemonList(daemons: (BackgroundProcessAttributes &
|
|
|
107
107
|
export declare function formatDaemon(daemon: BackgroundProcessAttributes & {
|
|
108
108
|
id: number;
|
|
109
109
|
}): string;
|
|
110
|
+
/**
|
|
111
|
+
* Format a daemon log.
|
|
112
|
+
*/
|
|
113
|
+
export declare function formatDaemonLog(daemonId: string, log: string): string;
|
|
110
114
|
/**
|
|
111
115
|
* Format a list of firewall rules.
|
|
112
116
|
*/
|
|
@@ -241,6 +245,14 @@ export declare function formatEnv(content: string): string;
|
|
|
241
245
|
export declare function formatUser(user: UserAttributes & {
|
|
242
246
|
id: number;
|
|
243
247
|
}): string;
|
|
248
|
+
/**
|
|
249
|
+
* Format a list of services with their derived availability.
|
|
250
|
+
*/
|
|
251
|
+
export declare function formatServiceList(services: {
|
|
252
|
+
service: string;
|
|
253
|
+
available: boolean;
|
|
254
|
+
detail: string | null;
|
|
255
|
+
}[]): string;
|
|
244
256
|
/**
|
|
245
257
|
* Format a deleted resource confirmation.
|
|
246
258
|
*/
|
package/dist/formatters.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemons.d.ts","sourceRoot":"","sources":["../../src/handlers/daemons.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"daemons.d.ts","sourceRoot":"","sources":["../../src/handlers/daemons.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,aAAa,+IAgDxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/handlers/help.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/handlers/help.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAyuB7C;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAQvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CAa/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAA8B,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAA8B,UAAU,EAAE,MAAM,YAAY,CAAC;AAiCzE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA4E7C;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D,OAAO,CAAC,UAAU,CAAC,CA+HrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/handlers/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/handlers/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA4V7C;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAWzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,CAWjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/handlers/services.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,+IA0BzB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as INSTRUCTIONS, i as getTools, n as executeToolWithCredentials, t as VERSION } from "./version-
|
|
1
|
+
import { a as INSTRUCTIONS, i as getTools, n as executeToolWithCredentials, t as VERSION } from "./version-BS77BDou.js";
|
|
2
2
|
import { parseAuthHeader } from "./auth.js";
|
|
3
3
|
import { authorizeGetHandler, authorizePostHandler, oauthMetadataHandler, protectedResourceHandler, registerHandler, tokenHandler } from "./oauth.js";
|
|
4
4
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -302,4 +302,4 @@ function createHealthApp() {
|
|
|
302
302
|
//#endregion
|
|
303
303
|
export { SessionManager as a, handleMcpRequest as i, createMcpRequestHandler as n, createMcpServer as r, createHealthApp as t };
|
|
304
304
|
|
|
305
|
-
//# sourceMappingURL=http-
|
|
305
|
+
//# sourceMappingURL=http-CwlifGMb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-DVoeL5Wa.js","names":[],"sources":["../src/sessions.ts","../src/http.ts"],"sourcesContent":["/* eslint-disable typescript-eslint/no-deprecated -- Using low-level Server type for session management */\n/**\n * Session manager for multi-tenant Streamable HTTP transport.\n *\n * Each MCP client session gets its own transport + server pair.\n * Sessions are identified by UUID and tracked in a Map.\n *\n * Supports automatic TTL-based cleanup of idle sessions to prevent\n * memory leaks from abandoned clients.\n */\n\n// Using low-level Server type for advanced transport handling\n// eslint-disable-next-line typescript-eslint/no-deprecated\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\n\n/**\n * A managed session: transport + MCP server pair.\n */\nexport interface ManagedSession {\n transport: StreamableHTTPServerTransport;\n server: Server;\n createdAt: number;\n lastActiveAt: number;\n}\n\nexport interface SessionManagerOptions {\n /**\n * Maximum idle time in milliseconds before a session is reaped.\n * Default: 30 minutes. Set to 0 to disable automatic cleanup.\n */\n ttl?: number;\n\n /**\n * How often to check for expired sessions, in milliseconds.\n * Default: 60 seconds.\n */\n sweepInterval?: number;\n}\n\nconst DEFAULT_TTL = 30 * 60 * 1000; // 30 minutes\nconst DEFAULT_SWEEP_INTERVAL = 60 * 1000; // 60 seconds\n\nexport class SessionManager {\n private sessions = new Map<string, ManagedSession>();\n // eslint-disable-next-line typescript-eslint/no-redundant-type-constituents -- NodeJS.Timeout resolves correctly at runtime\n private sweepTimer: ReturnType<typeof setInterval> | undefined;\n private readonly ttl: number;\n\n constructor(options?: SessionManagerOptions) {\n this.ttl = options?.ttl ?? DEFAULT_TTL;\n\n if (this.ttl > 0) {\n const interval = options?.sweepInterval ?? DEFAULT_SWEEP_INTERVAL;\n this.sweepTimer = setInterval(() => {\n this.sweep();\n }, interval);\n // Don't keep the process alive just for the sweep timer\n this.sweepTimer.unref();\n }\n }\n\n /**\n * Register a session after its ID has been assigned by the transport.\n */\n register(transport: StreamableHTTPServerTransport, server: Server): void {\n const sessionId = transport.sessionId;\n if (sessionId) {\n const now = Date.now();\n this.sessions.set(sessionId, {\n transport,\n server,\n createdAt: now,\n lastActiveAt: now,\n });\n }\n }\n\n /**\n * Look up a session by its ID and refresh its activity timestamp.\n */\n get(sessionId: string): ManagedSession | undefined {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.lastActiveAt = Date.now();\n }\n return session;\n }\n\n /**\n * Remove a session and close its transport + server.\n */\n async remove(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (session) {\n this.sessions.delete(sessionId);\n await session.transport.close();\n await session.server.close();\n }\n }\n\n /**\n * Get the number of active sessions.\n */\n get size(): number {\n return this.sessions.size;\n }\n\n /**\n * Sweep expired sessions. Called automatically by the sweep timer.\n * Returns the number of sessions reaped.\n */\n sweep(): number {\n if (this.ttl <= 0) return 0;\n\n const now = Date.now();\n const expired: string[] = [];\n\n for (const [id, session] of this.sessions) {\n if (now - session.lastActiveAt > this.ttl) {\n expired.push(id);\n }\n }\n\n for (const id of expired) {\n // Fire-and-forget cleanup — don't block the sweep\n /* v8 ignore start */\n this.remove(id).catch(() => {});\n /* v8 ignore stop */\n }\n\n return expired.length;\n }\n\n /**\n * Close all sessions, stop the sweep timer, and clean up.\n */\n async closeAll(): Promise<void> {\n if (this.sweepTimer) {\n clearInterval(this.sweepTimer);\n this.sweepTimer = undefined;\n }\n\n const promises: Promise<void>[] = [];\n for (const [, session] of this.sessions) {\n promises.push(session.transport.close());\n promises.push(session.server.close());\n }\n await Promise.all(promises);\n this.sessions.clear();\n }\n}\n","/* eslint-disable typescript-eslint/no-deprecated -- Using low-level Server for StreamableHTTPServerTransport */\n/**\n * Streamable HTTP transport for Forge MCP Server\n *\n * Implements the official MCP Streamable HTTP transport specification (2025-03-26)\n * using the SDK's StreamableHTTPServerTransport.\n *\n * Architecture:\n * - Stateful mode with per-session transport+server pairs (multi-tenant)\n * - Auth via Bearer token → authInfo.token → handler extra.authInfo\n * - Session manager (injected) maps session IDs to transport+server instances\n * - Health/status endpoints handled by h3, MCP endpoint by the SDK transport\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\n\n// Using low-level Server for advanced transport handling (StreamableHTTPServerTransport)\n// eslint-disable-next-line typescript-eslint/no-deprecated\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { getOrganizationSlug } from \"@studiometa/forge-api\";\nimport { H3, defineEventHandler } from \"h3\";\n\nimport { parseAuthHeader } from \"./auth.ts\";\nimport { executeToolWithCredentials } from \"./handlers/index.ts\";\nimport { INSTRUCTIONS } from \"./instructions.ts\";\nimport {\n oauthMetadataHandler,\n protectedResourceHandler,\n registerHandler,\n authorizeGetHandler,\n authorizePostHandler,\n tokenHandler,\n} from \"./oauth.ts\";\nimport { SessionManager } from \"./sessions.ts\";\nimport { getTools } from \"./tools.ts\";\nimport { VERSION } from \"./version.ts\";\n\nexport { SessionManager } from \"./sessions.ts\";\n\n/**\n * Options for the HTTP MCP server.\n */\nexport interface HttpServerOptions {\n /** When true, forge_write tool is not registered and write operations are rejected. */\n readOnly?: boolean;\n}\n\n/**\n * Create a configured MCP Server instance for HTTP transport.\n *\n * Unlike stdio, HTTP mode does NOT include forge_configure/forge_get_config\n * because API tokens come from the Authorization header per-request.\n * Organization slug still falls back to FORGE_ORG/config when omitted.\n */\nexport function createMcpServer(options?: HttpServerOptions): Server {\n const readOnly = options?.readOnly ?? false;\n const tools = getTools({ readOnly });\n\n const server = new Server(\n {\n name: \"forge-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n instructions: INSTRUCTIONS,\n },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const { name, arguments: args } = request.params;\n const authInfo = extra.authInfo as { token?: string; organizationSlug?: string } | undefined;\n const token = authInfo?.token;\n const organizationSlugFromAuth =\n typeof authInfo?.organizationSlug === \"string\" ? authInfo.organizationSlug : undefined;\n\n /* v8 ignore start */\n if (!token) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: Authentication required. No token found in request.\",\n },\n ],\n structuredContent: {\n success: false,\n error: \"Authentication required. No token found in request.\",\n },\n isError: true,\n };\n }\n /* v8 ignore stop */\n\n // Reject write operations in read-only mode\n if (readOnly && name === \"forge_write\") {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: Server is running in read-only mode. Write operations are disabled.\",\n },\n ],\n structuredContent: {\n success: false,\n error: \"Server is running in read-only mode. Write operations are disabled.\",\n },\n isError: true,\n };\n }\n\n try {\n // Organization slug can come from:\n // 1. Tool args (per-request override, highest priority)\n // 2. Auth token (configured during OAuth flow)\n // 3. FORGE_ORG / config fallback\n /* v8 ignore next 2 -- defensive type guard */\n const orgSlugFromArgs =\n typeof args?.organizationSlug === \"string\" ? args.organizationSlug : undefined;\n const result = await executeToolWithCredentials(name, /* v8 ignore next */ args ?? {}, {\n apiToken: token,\n organizationSlug:\n orgSlugFromArgs ?? organizationSlugFromAuth ?? getOrganizationSlug() ?? undefined,\n });\n return result as CallToolResult;\n } catch (error) {\n /* v8 ignore start */\n const message = error instanceof Error ? error.message : String(error);\n /* v8 ignore stop */\n return {\n content: [{ type: \"text\" as const, text: `Error: ${message}` }],\n structuredContent: { success: false, error: message },\n isError: true,\n };\n }\n });\n\n return server;\n}\n\n/**\n * Handle an MCP request using the Streamable HTTP transport.\n *\n * Routes requests based on whether they have a session ID:\n * - No session ID + initialize request → create new session\n * - Has session ID → route to existing session's transport\n *\n * @param req - Node.js IncomingMessage\n * @param res - Node.js ServerResponse\n * @param sessions - Session manager instance (injected)\n * @param options - Server options (read-only mode, etc.)\n */\nexport async function handleMcpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n sessions: SessionManager,\n options?: HttpServerOptions,\n): Promise<void> {\n // Extract and validate auth\n const authHeader = req.headers.authorization;\n const credentials = parseAuthHeader(authHeader);\n\n if (!credentials) {\n // Build resource_metadata URL for the WWW-Authenticate header (RFC 9728)\n const host = req.headers.host || \"localhost:3000\";\n const proto = req.headers[\"x-forwarded-proto\"];\n const protocol = (typeof proto === \"string\" ? proto : undefined) || \"http\";\n const resourceMetadataUrl = `${protocol}://${host}/.well-known/oauth-protected-resource`;\n\n res.writeHead(401, {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": `Bearer resource_metadata=\"${resourceMetadataUrl}\"`,\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Authentication required. Provide a Bearer token with your Forge API token.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n // Inject auth info for the SDK transport (MCP SDK expects auth on request)\n // Include organizationSlug in extra for downstream handlers\n Object.assign(req, {\n auth: {\n token: credentials.apiToken,\n organizationSlug: credentials.organizationSlug,\n clientId: \"forge-http-client\",\n scopes: [],\n extra: {\n organizationSlug: credentials.organizationSlug,\n },\n },\n });\n\n const sessionHeader = req.headers[\"mcp-session-id\"];\n const sessionId = typeof sessionHeader === \"string\" ? sessionHeader : undefined;\n\n if (sessionId) {\n // Existing session — route to its transport\n const session = sessions.get(sessionId);\n if (!session) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Session not found. The session may have expired or been terminated.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n await session.transport.handleRequest(req, res);\n return;\n }\n\n // No session ID — this should be an initialize request.\n // Create a new transport + server pair.\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n\n const server = createMcpServer(options);\n await server.connect(transport);\n\n // Set up cleanup on close\n // eslint-disable-next-line unicorn/prefer-add-event-listener -- MCP SDK uses property assignment\n transport.onclose = () => {\n const sid = transport.sessionId;\n /* v8 ignore start */\n if (sid) {\n sessions.remove(sid).catch(() => {\n // Ignore cleanup errors\n });\n }\n /* v8 ignore stop */\n };\n\n // Handle the request (this will set transport.sessionId during initialize)\n await transport.handleRequest(req, res);\n\n // After handling, register the session if the transport got a session ID\n /* v8 ignore start */\n if (transport.sessionId) {\n sessions.register(transport, server);\n } else {\n // No session was created (e.g., invalid request) — clean up\n await transport.close();\n await server.close();\n }\n /* v8 ignore stop */\n}\n\n/**\n * Create a request handler bound to a SessionManager instance.\n * Convenience factory for server.ts.\n */\nexport function createMcpRequestHandler(\n sessions: SessionManager,\n options?: HttpServerOptions,\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n /* v8 ignore start */\n return (req, res) => handleMcpRequest(req, res, sessions, options);\n /* v8 ignore stop */\n}\n\n/**\n * Create h3 app for health check, service info, and OAuth endpoints.\n * The MCP endpoint is handled separately by handleMcpRequest.\n */\nexport function createHealthApp(): H3 {\n const app = new H3();\n\n // Service info & health\n app.get(\n \"/\",\n defineEventHandler(() => {\n return { status: \"ok\", service: \"forge-mcp\", version: VERSION };\n }),\n );\n\n app.get(\n \"/health\",\n defineEventHandler(() => {\n return { status: \"ok\" };\n }),\n );\n\n // OAuth 2.1 endpoints\n app.get(\"/.well-known/oauth-authorization-server\", oauthMetadataHandler);\n app.get(\"/.well-known/oauth-protected-resource\", protectedResourceHandler);\n app.post(\"/register\", registerHandler);\n app.get(\"/authorize\", authorizeGetHandler);\n app.post(\"/authorize\", authorizePostHandler);\n app.post(\"/token\", tokenHandler);\n\n return app;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"http-CwlifGMb.js","names":[],"sources":["../src/sessions.ts","../src/http.ts"],"sourcesContent":["/* eslint-disable typescript-eslint/no-deprecated -- Using low-level Server type for session management */\n/**\n * Session manager for multi-tenant Streamable HTTP transport.\n *\n * Each MCP client session gets its own transport + server pair.\n * Sessions are identified by UUID and tracked in a Map.\n *\n * Supports automatic TTL-based cleanup of idle sessions to prevent\n * memory leaks from abandoned clients.\n */\n\n// Using low-level Server type for advanced transport handling\n// eslint-disable-next-line typescript-eslint/no-deprecated\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\n\n/**\n * A managed session: transport + MCP server pair.\n */\nexport interface ManagedSession {\n transport: StreamableHTTPServerTransport;\n server: Server;\n createdAt: number;\n lastActiveAt: number;\n}\n\nexport interface SessionManagerOptions {\n /**\n * Maximum idle time in milliseconds before a session is reaped.\n * Default: 30 minutes. Set to 0 to disable automatic cleanup.\n */\n ttl?: number;\n\n /**\n * How often to check for expired sessions, in milliseconds.\n * Default: 60 seconds.\n */\n sweepInterval?: number;\n}\n\nconst DEFAULT_TTL = 30 * 60 * 1000; // 30 minutes\nconst DEFAULT_SWEEP_INTERVAL = 60 * 1000; // 60 seconds\n\nexport class SessionManager {\n private sessions = new Map<string, ManagedSession>();\n // eslint-disable-next-line typescript-eslint/no-redundant-type-constituents -- NodeJS.Timeout resolves correctly at runtime\n private sweepTimer: ReturnType<typeof setInterval> | undefined;\n private readonly ttl: number;\n\n constructor(options?: SessionManagerOptions) {\n this.ttl = options?.ttl ?? DEFAULT_TTL;\n\n if (this.ttl > 0) {\n const interval = options?.sweepInterval ?? DEFAULT_SWEEP_INTERVAL;\n this.sweepTimer = setInterval(() => {\n this.sweep();\n }, interval);\n // Don't keep the process alive just for the sweep timer\n this.sweepTimer.unref();\n }\n }\n\n /**\n * Register a session after its ID has been assigned by the transport.\n */\n register(transport: StreamableHTTPServerTransport, server: Server): void {\n const sessionId = transport.sessionId;\n if (sessionId) {\n const now = Date.now();\n this.sessions.set(sessionId, {\n transport,\n server,\n createdAt: now,\n lastActiveAt: now,\n });\n }\n }\n\n /**\n * Look up a session by its ID and refresh its activity timestamp.\n */\n get(sessionId: string): ManagedSession | undefined {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.lastActiveAt = Date.now();\n }\n return session;\n }\n\n /**\n * Remove a session and close its transport + server.\n */\n async remove(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (session) {\n this.sessions.delete(sessionId);\n await session.transport.close();\n await session.server.close();\n }\n }\n\n /**\n * Get the number of active sessions.\n */\n get size(): number {\n return this.sessions.size;\n }\n\n /**\n * Sweep expired sessions. Called automatically by the sweep timer.\n * Returns the number of sessions reaped.\n */\n sweep(): number {\n if (this.ttl <= 0) return 0;\n\n const now = Date.now();\n const expired: string[] = [];\n\n for (const [id, session] of this.sessions) {\n if (now - session.lastActiveAt > this.ttl) {\n expired.push(id);\n }\n }\n\n for (const id of expired) {\n // Fire-and-forget cleanup — don't block the sweep\n /* v8 ignore start */\n this.remove(id).catch(() => {});\n /* v8 ignore stop */\n }\n\n return expired.length;\n }\n\n /**\n * Close all sessions, stop the sweep timer, and clean up.\n */\n async closeAll(): Promise<void> {\n if (this.sweepTimer) {\n clearInterval(this.sweepTimer);\n this.sweepTimer = undefined;\n }\n\n const promises: Promise<void>[] = [];\n for (const [, session] of this.sessions) {\n promises.push(session.transport.close());\n promises.push(session.server.close());\n }\n await Promise.all(promises);\n this.sessions.clear();\n }\n}\n","/* eslint-disable typescript-eslint/no-deprecated -- Using low-level Server for StreamableHTTPServerTransport */\n/**\n * Streamable HTTP transport for Forge MCP Server\n *\n * Implements the official MCP Streamable HTTP transport specification (2025-03-26)\n * using the SDK's StreamableHTTPServerTransport.\n *\n * Architecture:\n * - Stateful mode with per-session transport+server pairs (multi-tenant)\n * - Auth via Bearer token → authInfo.token → handler extra.authInfo\n * - Session manager (injected) maps session IDs to transport+server instances\n * - Health/status endpoints handled by h3, MCP endpoint by the SDK transport\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\n\n// Using low-level Server for advanced transport handling (StreamableHTTPServerTransport)\n// eslint-disable-next-line typescript-eslint/no-deprecated\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { getOrganizationSlug } from \"@studiometa/forge-api\";\nimport { H3, defineEventHandler } from \"h3\";\n\nimport { parseAuthHeader } from \"./auth.ts\";\nimport { executeToolWithCredentials } from \"./handlers/index.ts\";\nimport { INSTRUCTIONS } from \"./instructions.ts\";\nimport {\n oauthMetadataHandler,\n protectedResourceHandler,\n registerHandler,\n authorizeGetHandler,\n authorizePostHandler,\n tokenHandler,\n} from \"./oauth.ts\";\nimport { SessionManager } from \"./sessions.ts\";\nimport { getTools } from \"./tools.ts\";\nimport { VERSION } from \"./version.ts\";\n\nexport { SessionManager } from \"./sessions.ts\";\n\n/**\n * Options for the HTTP MCP server.\n */\nexport interface HttpServerOptions {\n /** When true, forge_write tool is not registered and write operations are rejected. */\n readOnly?: boolean;\n}\n\n/**\n * Create a configured MCP Server instance for HTTP transport.\n *\n * Unlike stdio, HTTP mode does NOT include forge_configure/forge_get_config\n * because API tokens come from the Authorization header per-request.\n * Organization slug still falls back to FORGE_ORG/config when omitted.\n */\nexport function createMcpServer(options?: HttpServerOptions): Server {\n const readOnly = options?.readOnly ?? false;\n const tools = getTools({ readOnly });\n\n const server = new Server(\n {\n name: \"forge-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n instructions: INSTRUCTIONS,\n },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const { name, arguments: args } = request.params;\n const authInfo = extra.authInfo as { token?: string; organizationSlug?: string } | undefined;\n const token = authInfo?.token;\n const organizationSlugFromAuth =\n typeof authInfo?.organizationSlug === \"string\" ? authInfo.organizationSlug : undefined;\n\n /* v8 ignore start */\n if (!token) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: Authentication required. No token found in request.\",\n },\n ],\n structuredContent: {\n success: false,\n error: \"Authentication required. No token found in request.\",\n },\n isError: true,\n };\n }\n /* v8 ignore stop */\n\n // Reject write operations in read-only mode\n if (readOnly && name === \"forge_write\") {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: Server is running in read-only mode. Write operations are disabled.\",\n },\n ],\n structuredContent: {\n success: false,\n error: \"Server is running in read-only mode. Write operations are disabled.\",\n },\n isError: true,\n };\n }\n\n try {\n // Organization slug can come from:\n // 1. Tool args (per-request override, highest priority)\n // 2. Auth token (configured during OAuth flow)\n // 3. FORGE_ORG / config fallback\n /* v8 ignore next 2 -- defensive type guard */\n const orgSlugFromArgs =\n typeof args?.organizationSlug === \"string\" ? args.organizationSlug : undefined;\n const result = await executeToolWithCredentials(name, /* v8 ignore next */ args ?? {}, {\n apiToken: token,\n organizationSlug:\n orgSlugFromArgs ?? organizationSlugFromAuth ?? getOrganizationSlug() ?? undefined,\n });\n return result as CallToolResult;\n } catch (error) {\n /* v8 ignore start */\n const message = error instanceof Error ? error.message : String(error);\n /* v8 ignore stop */\n return {\n content: [{ type: \"text\" as const, text: `Error: ${message}` }],\n structuredContent: { success: false, error: message },\n isError: true,\n };\n }\n });\n\n return server;\n}\n\n/**\n * Handle an MCP request using the Streamable HTTP transport.\n *\n * Routes requests based on whether they have a session ID:\n * - No session ID + initialize request → create new session\n * - Has session ID → route to existing session's transport\n *\n * @param req - Node.js IncomingMessage\n * @param res - Node.js ServerResponse\n * @param sessions - Session manager instance (injected)\n * @param options - Server options (read-only mode, etc.)\n */\nexport async function handleMcpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n sessions: SessionManager,\n options?: HttpServerOptions,\n): Promise<void> {\n // Extract and validate auth\n const authHeader = req.headers.authorization;\n const credentials = parseAuthHeader(authHeader);\n\n if (!credentials) {\n // Build resource_metadata URL for the WWW-Authenticate header (RFC 9728)\n const host = req.headers.host || \"localhost:3000\";\n const proto = req.headers[\"x-forwarded-proto\"];\n const protocol = (typeof proto === \"string\" ? proto : undefined) || \"http\";\n const resourceMetadataUrl = `${protocol}://${host}/.well-known/oauth-protected-resource`;\n\n res.writeHead(401, {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": `Bearer resource_metadata=\"${resourceMetadataUrl}\"`,\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Authentication required. Provide a Bearer token with your Forge API token.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n // Inject auth info for the SDK transport (MCP SDK expects auth on request)\n // Include organizationSlug in extra for downstream handlers\n Object.assign(req, {\n auth: {\n token: credentials.apiToken,\n organizationSlug: credentials.organizationSlug,\n clientId: \"forge-http-client\",\n scopes: [],\n extra: {\n organizationSlug: credentials.organizationSlug,\n },\n },\n });\n\n const sessionHeader = req.headers[\"mcp-session-id\"];\n const sessionId = typeof sessionHeader === \"string\" ? sessionHeader : undefined;\n\n if (sessionId) {\n // Existing session — route to its transport\n const session = sessions.get(sessionId);\n if (!session) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Session not found. The session may have expired or been terminated.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n await session.transport.handleRequest(req, res);\n return;\n }\n\n // No session ID — this should be an initialize request.\n // Create a new transport + server pair.\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n\n const server = createMcpServer(options);\n await server.connect(transport);\n\n // Set up cleanup on close\n // eslint-disable-next-line unicorn/prefer-add-event-listener -- MCP SDK uses property assignment\n transport.onclose = () => {\n const sid = transport.sessionId;\n /* v8 ignore start */\n if (sid) {\n sessions.remove(sid).catch(() => {\n // Ignore cleanup errors\n });\n }\n /* v8 ignore stop */\n };\n\n // Handle the request (this will set transport.sessionId during initialize)\n await transport.handleRequest(req, res);\n\n // After handling, register the session if the transport got a session ID\n /* v8 ignore start */\n if (transport.sessionId) {\n sessions.register(transport, server);\n } else {\n // No session was created (e.g., invalid request) — clean up\n await transport.close();\n await server.close();\n }\n /* v8 ignore stop */\n}\n\n/**\n * Create a request handler bound to a SessionManager instance.\n * Convenience factory for server.ts.\n */\nexport function createMcpRequestHandler(\n sessions: SessionManager,\n options?: HttpServerOptions,\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n /* v8 ignore start */\n return (req, res) => handleMcpRequest(req, res, sessions, options);\n /* v8 ignore stop */\n}\n\n/**\n * Create h3 app for health check, service info, and OAuth endpoints.\n * The MCP endpoint is handled separately by handleMcpRequest.\n */\nexport function createHealthApp(): H3 {\n const app = new H3();\n\n // Service info & health\n app.get(\n \"/\",\n defineEventHandler(() => {\n return { status: \"ok\", service: \"forge-mcp\", version: VERSION };\n }),\n );\n\n app.get(\n \"/health\",\n defineEventHandler(() => {\n return { status: \"ok\" };\n }),\n );\n\n // OAuth 2.1 endpoints\n app.get(\"/.well-known/oauth-authorization-server\", oauthMetadataHandler);\n app.get(\"/.well-known/oauth-protected-resource\", protectedResourceHandler);\n app.post(\"/register\", registerHandler);\n app.get(\"/authorize\", authorizeGetHandler);\n app.post(\"/authorize\", authorizePostHandler);\n app.post(\"/token\", tokenHandler);\n\n return app;\n}\n"],"mappings":";;;;;;;;;;AAwCA,IAAM,cAAc,OAAU;AAC9B,IAAM,yBAAyB,KAAK;AAEpC,IAAa,iBAAb,MAA4B;CAC1B,2BAAmB,IAAI,IAA4B;CAEnD;CACA;CAEA,YAAY,SAAiC;EAC3C,KAAK,MAAM,SAAS,OAAO;EAE3B,IAAI,KAAK,MAAM,GAAG;GAChB,MAAM,WAAW,SAAS,iBAAiB;GAC3C,KAAK,aAAa,kBAAkB;IAClC,KAAK,MAAM;GACb,GAAG,QAAQ;GAEX,KAAK,WAAW,MAAM;EACxB;CACF;;;;CAKA,SAAS,WAA0C,QAAsB;EACvE,MAAM,YAAY,UAAU;EAC5B,IAAI,WAAW;GACb,MAAM,MAAM,KAAK,IAAI;GACrB,KAAK,SAAS,IAAI,WAAW;IAC3B;IACA;IACA,WAAW;IACX,cAAc;GAChB,CAAC;EACH;CACF;;;;CAKA,IAAI,WAA+C;EACjD,MAAM,UAAU,KAAK,SAAS,IAAI,SAAS;EAC3C,IAAI,SACF,QAAQ,eAAe,KAAK,IAAI;EAElC,OAAO;CACT;;;;CAKA,MAAM,OAAO,WAAkC;EAC7C,MAAM,UAAU,KAAK,SAAS,IAAI,SAAS;EAC3C,IAAI,SAAS;GACX,KAAK,SAAS,OAAO,SAAS;GAC9B,MAAM,QAAQ,UAAU,MAAM;GAC9B,MAAM,QAAQ,OAAO,MAAM;EAC7B;CACF;;;;CAKA,IAAI,OAAe;EACjB,OAAO,KAAK,SAAS;CACvB;;;;;CAMA,QAAgB;EACd,IAAI,KAAK,OAAO,GAAG,OAAO;EAE1B,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,UAAoB,CAAC;EAE3B,KAAK,MAAM,CAAC,IAAI,YAAY,KAAK,UAC/B,IAAI,MAAM,QAAQ,eAAe,KAAK,KACpC,QAAQ,KAAK,EAAE;EAInB,KAAK,MAAM,MAAM;;EAGf,KAAK,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;EAIhC,OAAO,QAAQ;CACjB;;;;CAKA,MAAM,WAA0B;EAC9B,IAAI,KAAK,YAAY;GACnB,cAAc,KAAK,UAAU;GAC7B,KAAK,aAAa,KAAA;EACpB;EAEA,MAAM,WAA4B,CAAC;EACnC,KAAK,MAAM,GAAG,YAAY,KAAK,UAAU;GACvC,SAAS,KAAK,QAAQ,UAAU,MAAM,CAAC;GACvC,SAAS,KAAK,QAAQ,OAAO,MAAM,CAAC;EACtC;EACA,MAAM,QAAQ,IAAI,QAAQ;EAC1B,KAAK,SAAS,MAAM;CACtB;AACF;;;;;;;;;;;;;;;;;;;;;;AC1FA,SAAgB,gBAAgB,SAAqC;CACnE,MAAM,WAAW,SAAS,YAAY;CACtC,MAAM,QAAQ,SAAS,EAAE,SAAS,CAAC;CAEnC,MAAM,SAAS,IAAI,OACjB;EACE,MAAM;EACN,SAAS;CACX,GACA;EACE,cAAc,EACZ,OAAO,CAAC,EACV;EACA,cAAc;CAChB,CACF;CAEA,OAAO,kBAAkB,wBAAwB,YAAY;EAC3D,OAAO,EAAE,MAAM;CACjB,CAAC;CAED,OAAO,kBAAkB,uBAAuB,OAAO,SAAS,UAAU;EACxE,MAAM,EAAE,MAAM,WAAW,SAAS,QAAQ;EAC1C,MAAM,WAAW,MAAM;EACvB,MAAM,QAAQ,UAAU;EACxB,MAAM,2BACJ,OAAO,UAAU,qBAAqB,WAAW,SAAS,mBAAmB,KAAA;;EAG/E,IAAI,CAAC,OACH,OAAO;GACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;GACR,CACF;GACA,mBAAmB;IACjB,SAAS;IACT,OAAO;GACT;GACA,SAAS;EACX;;EAKF,IAAI,YAAY,SAAS,eACvB,OAAO;GACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;GACR,CACF;GACA,mBAAmB;IACjB,SAAS;IACT,OAAO;GACT;GACA,SAAS;EACX;EAGF,IAAI;;GAMF,MAAM,kBACJ,OAAO,MAAM,qBAAqB,WAAW,KAAK,mBAAmB,KAAA;GAMvE,OAAO,MALc;IAA2B;;IAA2B,QAAQ,CAAC;IAAG;KACrF,UAAU;KACV,kBACE,mBAAmB,4BAA4B,oBAAoB,KAAK,KAAA;IAC5E;GAAC;EAEH,SAAS,OAAO;;GAEd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;;GAErE,OAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAiB,MAAM,UAAU;IAAU,CAAC;IAC9D,mBAAmB;KAAE,SAAS;KAAO,OAAO;IAAQ;IACpD,SAAS;GACX;EACF;CACF,CAAC;CAED,OAAO;AACT;;;;;;;;;;;;;AAcA,eAAsB,iBACpB,KACA,KACA,UACA,SACe;CAEf,MAAM,aAAa,IAAI,QAAQ;CAC/B,MAAM,cAAc,gBAAgB,UAAU;CAE9C,IAAI,CAAC,aAAa;EAEhB,MAAM,OAAO,IAAI,QAAQ,QAAQ;EACjC,MAAM,QAAQ,IAAI,QAAQ;EAE1B,MAAM,sBAAsB,IADV,OAAO,UAAU,WAAW,QAAQ,KAAA,MAAc,OAC5B,KAAK,KAAK;EAElD,IAAI,UAAU,KAAK;GACjB,gBAAgB;GAChB,oBAAoB,6BAA6B,oBAAoB;EACvE,CAAC;EACD,IAAI,IACF,KAAK,UAAU;GACb,SAAS;GACT,OAAO;IACL,MAAM;IACN,SAAS;GACX;GACA,IAAI;EACN,CAAC,CACH;EACA;CACF;CAIA,OAAO,OAAO,KAAK,EACjB,MAAM;EACJ,OAAO,YAAY;EACnB,kBAAkB,YAAY;EAC9B,UAAU;EACV,QAAQ,CAAC;EACT,OAAO,EACL,kBAAkB,YAAY,iBAChC;CACF,EACF,CAAC;CAED,MAAM,gBAAgB,IAAI,QAAQ;CAClC,MAAM,YAAY,OAAO,kBAAkB,WAAW,gBAAgB,KAAA;CAEtE,IAAI,WAAW;EAEb,MAAM,UAAU,SAAS,IAAI,SAAS;EACtC,IAAI,CAAC,SAAS;GACZ,IAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;GACzD,IAAI,IACF,KAAK,UAAU;IACb,SAAS;IACT,OAAO;KACL,MAAM;KACN,SAAS;IACX;IACA,IAAI;GACN,CAAC,CACH;GACA;EACF;EAEA,MAAM,QAAQ,UAAU,cAAc,KAAK,GAAG;EAC9C;CACF;CAIA,MAAM,YAAY,IAAI,8BAA8B,EAClD,0BAA0B,WAAW,EACvC,CAAC;CAED,MAAM,SAAS,gBAAgB,OAAO;CACtC,MAAM,OAAO,QAAQ,SAAS;CAI9B,UAAU,gBAAgB;EACxB,MAAM,MAAM,UAAU;;EAEtB,IAAI,KACF,SAAS,OAAO,GAAG,CAAC,CAAC,YAAY,CAEjC,CAAC;;CAGL;CAGA,MAAM,UAAU,cAAc,KAAK,GAAG;;CAItC,IAAI,UAAU,WACZ,SAAS,SAAS,WAAW,MAAM;MAC9B;EAEL,MAAM,UAAU,MAAM;EACtB,MAAM,OAAO,MAAM;CACrB;;AAEF;;;;;AAMA,SAAgB,wBACd,UACA,SAC8D;;CAE9D,QAAQ,KAAK,QAAQ,iBAAiB,KAAK,KAAK,UAAU,OAAO;;AAEnE;;;;;AAMA,SAAgB,kBAAsB;CACpC,MAAM,MAAM,IAAI,GAAG;CAGnB,IAAI,IACF,KACA,yBAAyB;EACvB,OAAO;GAAE,QAAQ;GAAM,SAAS;GAAa,SAAS;EAAQ;CAChE,CAAC,CACH;CAEA,IAAI,IACF,WACA,yBAAyB;EACvB,OAAO,EAAE,QAAQ,KAAK;CACxB,CAAC,CACH;CAGA,IAAI,IAAI,2CAA2C,oBAAoB;CACvE,IAAI,IAAI,yCAAyC,wBAAwB;CACzE,IAAI,KAAK,aAAa,eAAe;CACrC,IAAI,IAAI,cAAc,mBAAmB;CACzC,IAAI,KAAK,cAAc,oBAAoB;CAC3C,IAAI,KAAK,UAAU,YAAY;CAE/B,OAAO;AACT"}
|
package/dist/http.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as SessionManager, i as handleMcpRequest, n as createMcpRequestHandler, r as createMcpServer, t as createHealthApp } from "./http-
|
|
1
|
+
import { a as SessionManager, i as handleMcpRequest, n as createMcpRequestHandler, r as createMcpServer, t as createHealthApp } from "./http-CwlifGMb.js";
|
|
2
2
|
export { SessionManager, createHealthApp, createMcpRequestHandler, createMcpServer, handleMcpRequest };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as parseReadOnlyFlag } from "./flags-CIh56cQ7.js";
|
|
3
|
-
import { a as INSTRUCTIONS, i as getTools, n as executeToolWithCredentials, r as STDIO_ONLY_TOOLS, t as VERSION } from "./version-
|
|
3
|
+
import { a as INSTRUCTIONS, i as getTools, n as executeToolWithCredentials, r as STDIO_ONLY_TOOLS, t as VERSION } from "./version-BS77BDou.js";
|
|
4
4
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as parseReadOnlyFlag } from "./flags-CIh56cQ7.js";
|
|
3
|
-
import { t as VERSION } from "./version-
|
|
4
|
-
import { a as SessionManager, n as createMcpRequestHandler, t as createHealthApp } from "./http-
|
|
3
|
+
import { t as VERSION } from "./version-BS77BDou.js";
|
|
4
|
+
import { a as SessionManager, n as createMcpRequestHandler, t as createHealthApp } from "./http-CwlifGMb.js";
|
|
5
5
|
import { toNodeHandler } from "h3/node";
|
|
6
6
|
import { createServer } from "node:http";
|
|
7
7
|
//#region src/server.ts
|
package/dist/tools.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Read-only actions — safe operations that don't modify server state.
|
|
4
4
|
*/
|
|
5
|
-
export declare const READ_ACTIONS: readonly ["list", "get", "resolve", "help", "schema", "context"];
|
|
5
|
+
export declare const READ_ACTIONS: readonly ["list", "get", "resolve", "help", "schema", "context", "log"];
|
|
6
6
|
/**
|
|
7
7
|
* Write actions — operations that modify server state.
|
|
8
8
|
* These are separated into the `forge_write` tool for safety.
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI/D;;GAEG;AACH,eAAO,MAAM,YAAY,YAAI,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI/D;;GAEG;AACH,eAAO,MAAM,YAAY,YAAI,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAU,CAAC;AAEpG;;;GAGG;AACH,eAAO,MAAM,aAAa,YACxB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,WAAW,CAEnE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,UAAU,CAEjE;AAgRD;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,EAAE,IAAI,EAAwC,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,EAAE,CAK1D;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,IAAI,EA2DlC,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { HttpClient, isForgeApiError } from "@studiometa/forge-api";
|
|
5
|
-
import { RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
|
|
5
|
+
import { RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDaemonLog, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listServices, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, restartService, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
|
|
6
6
|
//#region src/instructions.ts
|
|
7
7
|
/**
|
|
8
8
|
* MCP Server Instructions
|
|
@@ -564,6 +564,12 @@ function formatDaemon(daemon) {
|
|
|
564
564
|
return `Daemon: ${daemon.command} (ID: ${daemon.id})\nUser: ${daemon.user}\nProcesses: ${daemon.processes}\nStatus: ${daemon.status}`;
|
|
565
565
|
}
|
|
566
566
|
/**
|
|
567
|
+
* Format a daemon log.
|
|
568
|
+
*/
|
|
569
|
+
function formatDaemonLog(daemonId, log) {
|
|
570
|
+
return `Daemon ${daemonId} log:\n${log}`;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
567
573
|
* Format a list of firewall rules.
|
|
568
574
|
*/
|
|
569
575
|
function formatFirewallRuleList(rules) {
|
|
@@ -745,6 +751,17 @@ function formatUser(user) {
|
|
|
745
751
|
`Created: ${user.created_at}`
|
|
746
752
|
].join("\n");
|
|
747
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* Format a list of services with their derived availability.
|
|
756
|
+
*/
|
|
757
|
+
function formatServiceList(services) {
|
|
758
|
+
const lines = services.map((s) => {
|
|
759
|
+
const status = s.available ? "available" : "unavailable";
|
|
760
|
+
const detail = s.detail ? ` (${s.detail})` : "";
|
|
761
|
+
return `• ${s.service} — ${status}${detail}`;
|
|
762
|
+
});
|
|
763
|
+
return `${services.length} service(s):\n${lines.join("\n")}`;
|
|
764
|
+
}
|
|
748
765
|
//#endregion
|
|
749
766
|
//#region src/errors.ts
|
|
750
767
|
/**
|
|
@@ -960,7 +977,8 @@ var READ_ACTIONS = [
|
|
|
960
977
|
"resolve",
|
|
961
978
|
"help",
|
|
962
979
|
"schema",
|
|
963
|
-
"context"
|
|
980
|
+
"context",
|
|
981
|
+
"log"
|
|
964
982
|
];
|
|
965
983
|
/**
|
|
966
984
|
* Write actions — operations that modify server state.
|
|
@@ -1224,6 +1242,14 @@ var TOOLS = [{
|
|
|
1224
1242
|
type: "array",
|
|
1225
1243
|
description: "Server IDs to run a recipe on (e.g. [123, 456])",
|
|
1226
1244
|
items: { type: "number" }
|
|
1245
|
+
},
|
|
1246
|
+
service: {
|
|
1247
|
+
type: "string",
|
|
1248
|
+
description: "Service to restart (services: nginx, php, mysql, postgres, redis, supervisor)"
|
|
1249
|
+
},
|
|
1250
|
+
version: {
|
|
1251
|
+
type: "string",
|
|
1252
|
+
description: "PHP version required when restarting the php service (e.g. php83)"
|
|
1227
1253
|
}
|
|
1228
1254
|
},
|
|
1229
1255
|
required: ["resource", "action"]
|
|
@@ -1876,7 +1902,8 @@ var handleDaemons = createResourceHandler({
|
|
|
1876
1902
|
"create",
|
|
1877
1903
|
"update",
|
|
1878
1904
|
"delete",
|
|
1879
|
-
"restart"
|
|
1905
|
+
"restart",
|
|
1906
|
+
"log"
|
|
1880
1907
|
],
|
|
1881
1908
|
inputSchemas: {
|
|
1882
1909
|
list: /* @__PURE__ */ object({ server_id: /* @__PURE__ */ string() }),
|
|
@@ -1884,6 +1911,10 @@ var handleDaemons = createResourceHandler({
|
|
|
1884
1911
|
server_id: /* @__PURE__ */ string(),
|
|
1885
1912
|
id: /* @__PURE__ */ string()
|
|
1886
1913
|
}),
|
|
1914
|
+
log: /* @__PURE__ */ object({
|
|
1915
|
+
server_id: /* @__PURE__ */ string(),
|
|
1916
|
+
id: /* @__PURE__ */ string()
|
|
1917
|
+
}),
|
|
1887
1918
|
create: /* @__PURE__ */ object({
|
|
1888
1919
|
server_id: /* @__PURE__ */ string(),
|
|
1889
1920
|
command: /* @__PURE__ */ string()
|
|
@@ -1909,7 +1940,8 @@ var handleDaemons = createResourceHandler({
|
|
|
1909
1940
|
create: createDaemon,
|
|
1910
1941
|
update: updateDaemon,
|
|
1911
1942
|
delete: deleteDaemon,
|
|
1912
|
-
restart: restartDaemon
|
|
1943
|
+
restart: restartDaemon,
|
|
1944
|
+
log: getDaemonLog
|
|
1913
1945
|
},
|
|
1914
1946
|
hints: (_data, id, args) => getDaemonHints(String(args.server_id), id),
|
|
1915
1947
|
formatResult: (action, data, args) => {
|
|
@@ -1920,6 +1952,7 @@ var handleDaemons = createResourceHandler({
|
|
|
1920
1952
|
case "update": return formatDaemon(data);
|
|
1921
1953
|
case "delete": return `Daemon ${args.id} deleted.`;
|
|
1922
1954
|
case "restart": return `Daemon ${args.id} restarted.`;
|
|
1955
|
+
case "log": return formatDaemonLog(String(args.id), data);
|
|
1923
1956
|
/* v8 ignore next */
|
|
1924
1957
|
default: return "Done.";
|
|
1925
1958
|
}
|
|
@@ -2499,7 +2532,8 @@ var RESOURCE_HELP = {
|
|
|
2499
2532
|
get: "Get daemon details",
|
|
2500
2533
|
create: "Create a new daemon",
|
|
2501
2534
|
delete: "Delete a daemon",
|
|
2502
|
-
restart: "Restart a daemon"
|
|
2535
|
+
restart: "Restart a daemon",
|
|
2536
|
+
log: "Get the latest daemon log output"
|
|
2503
2537
|
},
|
|
2504
2538
|
fields: {
|
|
2505
2539
|
command: "Shell command to run",
|
|
@@ -2534,6 +2568,58 @@ var RESOURCE_HELP = {
|
|
|
2534
2568
|
server_id: "123",
|
|
2535
2569
|
id: "456"
|
|
2536
2570
|
}
|
|
2571
|
+
},
|
|
2572
|
+
{
|
|
2573
|
+
description: "Get daemon log output",
|
|
2574
|
+
params: {
|
|
2575
|
+
resource: "daemons",
|
|
2576
|
+
action: "log",
|
|
2577
|
+
server_id: "123",
|
|
2578
|
+
id: "456"
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
]
|
|
2582
|
+
},
|
|
2583
|
+
services: {
|
|
2584
|
+
description: "List and restart server services (nginx, php, mysql, postgres, redis, supervisor)",
|
|
2585
|
+
scope: "server (requires server_id)",
|
|
2586
|
+
actions: {
|
|
2587
|
+
list: "List services with a derived availability flag (heuristic — the API has no services GET endpoint)",
|
|
2588
|
+
restart: "Restart a service (maps to the API action reboot). The php service requires a version."
|
|
2589
|
+
},
|
|
2590
|
+
fields: {
|
|
2591
|
+
service: "One of: nginx, php, mysql, postgres, redis, supervisor",
|
|
2592
|
+
available: "Heuristic derived from the server object attributes",
|
|
2593
|
+
detail: "Extra info (php_version, database_type, redis_status) when relevant",
|
|
2594
|
+
version: "PHP version (e.g. php83) — required when restarting php"
|
|
2595
|
+
},
|
|
2596
|
+
examples: [
|
|
2597
|
+
{
|
|
2598
|
+
description: "List services",
|
|
2599
|
+
params: {
|
|
2600
|
+
resource: "services",
|
|
2601
|
+
action: "list",
|
|
2602
|
+
server_id: "123"
|
|
2603
|
+
}
|
|
2604
|
+
},
|
|
2605
|
+
{
|
|
2606
|
+
description: "Restart nginx",
|
|
2607
|
+
params: {
|
|
2608
|
+
resource: "services",
|
|
2609
|
+
action: "restart",
|
|
2610
|
+
server_id: "123",
|
|
2611
|
+
service: "nginx"
|
|
2612
|
+
}
|
|
2613
|
+
},
|
|
2614
|
+
{
|
|
2615
|
+
description: "Restart php (version required)",
|
|
2616
|
+
params: {
|
|
2617
|
+
resource: "services",
|
|
2618
|
+
action: "restart",
|
|
2619
|
+
server_id: "123",
|
|
2620
|
+
service: "php",
|
|
2621
|
+
version: "php83"
|
|
2622
|
+
}
|
|
2537
2623
|
}
|
|
2538
2624
|
]
|
|
2539
2625
|
},
|
|
@@ -3470,7 +3556,8 @@ var RESOURCE_SCHEMAS = {
|
|
|
3470
3556
|
"get",
|
|
3471
3557
|
"create",
|
|
3472
3558
|
"delete",
|
|
3473
|
-
"restart"
|
|
3559
|
+
"restart",
|
|
3560
|
+
"log"
|
|
3474
3561
|
],
|
|
3475
3562
|
scope: "server",
|
|
3476
3563
|
required: {
|
|
@@ -3478,7 +3565,8 @@ var RESOURCE_SCHEMAS = {
|
|
|
3478
3565
|
get: ["server_id", "id"],
|
|
3479
3566
|
create: ["server_id", "command"],
|
|
3480
3567
|
delete: ["server_id", "id"],
|
|
3481
|
-
restart: ["server_id", "id"]
|
|
3568
|
+
restart: ["server_id", "id"],
|
|
3569
|
+
log: ["server_id", "id"]
|
|
3482
3570
|
},
|
|
3483
3571
|
create: {
|
|
3484
3572
|
command: {
|
|
@@ -3499,6 +3587,14 @@ var RESOURCE_SCHEMAS = {
|
|
|
3499
3587
|
}
|
|
3500
3588
|
}
|
|
3501
3589
|
},
|
|
3590
|
+
services: {
|
|
3591
|
+
actions: ["list", "restart"],
|
|
3592
|
+
scope: "server",
|
|
3593
|
+
required: {
|
|
3594
|
+
list: ["server_id"],
|
|
3595
|
+
restart: ["server_id", "service"]
|
|
3596
|
+
}
|
|
3597
|
+
},
|
|
3502
3598
|
"firewall-rules": {
|
|
3503
3599
|
actions: [
|
|
3504
3600
|
"list",
|
|
@@ -4123,6 +4219,32 @@ async function handleServers(action, args, ctx) {
|
|
|
4123
4219
|
return _handleServers(action, args, ctx);
|
|
4124
4220
|
}
|
|
4125
4221
|
//#endregion
|
|
4222
|
+
//#region src/handlers/services.ts
|
|
4223
|
+
var handleServices = createResourceHandler({
|
|
4224
|
+
resource: "services",
|
|
4225
|
+
actions: ["list", "restart"],
|
|
4226
|
+
inputSchemas: {
|
|
4227
|
+
list: /* @__PURE__ */ object({ server_id: /* @__PURE__ */ string() }),
|
|
4228
|
+
restart: /* @__PURE__ */ object({
|
|
4229
|
+
server_id: /* @__PURE__ */ string(),
|
|
4230
|
+
service: /* @__PURE__ */ string(),
|
|
4231
|
+
version: /* @__PURE__ */ optional(/* @__PURE__ */ string())
|
|
4232
|
+
})
|
|
4233
|
+
},
|
|
4234
|
+
executors: {
|
|
4235
|
+
list: listServices,
|
|
4236
|
+
restart: restartService
|
|
4237
|
+
},
|
|
4238
|
+
formatResult: (action, data, args) => {
|
|
4239
|
+
switch (action) {
|
|
4240
|
+
case "list": return formatServiceList(data);
|
|
4241
|
+
case "restart": return `${String(args.service)} restart initiated on server ${String(args.server_id)}.`;
|
|
4242
|
+
/* v8 ignore next */
|
|
4243
|
+
default: return "Done.";
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
});
|
|
4247
|
+
//#endregion
|
|
4126
4248
|
//#region src/handlers/sites.ts
|
|
4127
4249
|
var _handleSites = createResourceHandler({
|
|
4128
4250
|
resource: "sites",
|
|
@@ -4378,6 +4500,7 @@ function routeToHandler(resource, action, args, ctx) {
|
|
|
4378
4500
|
case "backups": return handleBackups(action, args, ctx);
|
|
4379
4501
|
case "commands": return handleCommands(action, args, ctx);
|
|
4380
4502
|
case "scheduled-jobs": return handleScheduledJobs(action, args, ctx);
|
|
4503
|
+
case "services": return handleServices(action, args, ctx);
|
|
4381
4504
|
case "user": return handleUser(action, args, ctx);
|
|
4382
4505
|
case "batch": return handleBatch(action, args, ctx, routeToHandler);
|
|
4383
4506
|
/* v8 ignore next 6 -- all valid resources are handled above; unreachable in practice */
|
|
@@ -4467,8 +4590,8 @@ async function executeToolWithCredentials(name, args, credentials) {
|
|
|
4467
4590
|
}
|
|
4468
4591
|
//#endregion
|
|
4469
4592
|
//#region src/version.ts
|
|
4470
|
-
var VERSION = "0.4.
|
|
4593
|
+
var VERSION = "0.4.6";
|
|
4471
4594
|
//#endregion
|
|
4472
4595
|
export { INSTRUCTIONS as a, getTools as i, executeToolWithCredentials as n, STDIO_ONLY_TOOLS as r, VERSION as t };
|
|
4473
4596
|
|
|
4474
|
-
//# sourceMappingURL=version-
|
|
4597
|
+
//# sourceMappingURL=version-BS77BDou.js.map
|