@clawmasons/proxy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @clawmasons/proxy
2
+
3
+ Mason MCP proxy server
4
+
5
+ ## More Information
6
+
7
+ This package is part of the [Mason](https://github.com/clawmasons/mason) monorepo. See the [README](https://github.com/clawmasons/mason/blob/main/README.md) for full documentation.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAClF,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC9E,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC/E,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { ChapterProxyServer } from "./server.js";
2
+ export { ToolRouter, ResourceRouter, PromptRouter } from "./router.js";
3
+ export { UpstreamManager, createTransport } from "./upstream.js";
4
+ export { loadEnvFile, resolveEnvVars } from "./credentials.js";
5
+ export { openDatabase, insertAuditLog, queryAuditLog, createApprovalRequest, getApprovalRequest, updateApprovalStatus, generateId, } from "./db.js";
6
+ export { auditPreHook, auditPostHook, logDroppedServers } from "./hooks/audit.js";
7
+ export { matchesApprovalPattern, requestApproval } from "./hooks/approval.js";
8
+ export { SessionStore, handleConnectAgent } from "./handlers/connect-agent.js";
9
+ export { CredentialRelay } from "./handlers/credential-relay.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,IAAI,EAAE,IAAI,CAAC;CACZ;AAID,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAiC;gBAG7C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAClC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAqCtC,uDAAuD;IACvD,SAAS,IAAI,IAAI,EAAE;IAInB,qFAAqF;IACrF,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAIhD,iDAAiD;IACjD,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIjE,iEAAiE;IACjE,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;CAOxE;AAID,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAA+D;gBAEjE,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IAyBtD,iDAAiD;IACjD,aAAa,IAAI,QAAQ,EAAE;IAI3B,wFAAwF;IACxF,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAGzE;AAID,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAuC;gBAEzC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAmBlD,+CAA+C;IAC/C,WAAW,IAAI,MAAM,EAAE;IAIvB,8EAA8E;IAC9E,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;CAGvD"}
package/dist/router.js ADDED
@@ -0,0 +1,112 @@
1
+ import { getAppShortName } from "@clawmasons/shared";
2
+ // ── ToolRouter ─────────────────────────────────────────────────────────
3
+ export class ToolRouter {
4
+ routes = new Map();
5
+ constructor(upstreamTools, toolFilters) {
6
+ for (const [appName, tools] of upstreamTools) {
7
+ const filter = toolFilters.get(appName);
8
+ if (!filter)
9
+ continue; // No filter entry → exclude all tools from this app
10
+ const allowSet = new Set(filter.list);
11
+ const appShortName = getAppShortName(appName);
12
+ for (const tool of tools) {
13
+ if (!allowSet.has(tool.name))
14
+ continue;
15
+ const prefixedToolName = ToolRouter.prefixName(appShortName, tool.name);
16
+ const existing = this.routes.get(prefixedToolName);
17
+ if (existing) {
18
+ throw new Error(`Duplicate prefixed tool name "${prefixedToolName}" from apps "${existing.appName}" and "${appName}"`);
19
+ }
20
+ const prefixedTool = { ...tool, name: prefixedToolName };
21
+ this.routes.set(prefixedToolName, {
22
+ appName,
23
+ appShortName,
24
+ originalToolName: tool.name,
25
+ prefixedToolName,
26
+ tool: prefixedTool,
27
+ });
28
+ }
29
+ }
30
+ }
31
+ /** Returns all prefixed, filtered MCP Tool objects. */
32
+ listTools() {
33
+ return Array.from(this.routes.values()).map((entry) => entry.tool);
34
+ }
35
+ /** Resolves a prefixed tool name to its route entry, or null if unknown/filtered. */
36
+ resolve(prefixedName) {
37
+ return this.routes.get(prefixedName) ?? null;
38
+ }
39
+ /** Prefix a tool name with an app short name. */
40
+ static prefixName(appShortName, toolName) {
41
+ return `${appShortName}_${toolName}`;
42
+ }
43
+ /** Strip the app short name prefix from a prefixed tool name. */
44
+ static unprefixName(appShortName, prefixedName) {
45
+ const prefix = `${appShortName}_`;
46
+ if (prefixedName.startsWith(prefix)) {
47
+ return prefixedName.slice(prefix.length);
48
+ }
49
+ return prefixedName;
50
+ }
51
+ }
52
+ export class ResourceRouter {
53
+ entries = [];
54
+ uriMap = new Map();
55
+ constructor(upstreamResources) {
56
+ for (const [appName, resources] of upstreamResources) {
57
+ const appShortName = getAppShortName(appName);
58
+ for (const resource of resources) {
59
+ const prefixedName = ToolRouter.prefixName(appShortName, resource.name);
60
+ const prefixedResource = { ...resource, name: prefixedName };
61
+ this.entries.push({
62
+ appName,
63
+ appShortName,
64
+ originalName: resource.name,
65
+ prefixedName,
66
+ originalUri: resource.uri,
67
+ resource: prefixedResource,
68
+ });
69
+ // Map URI → app for read routing (first app wins on collision)
70
+ if (!this.uriMap.has(resource.uri)) {
71
+ this.uriMap.set(resource.uri, { appName, originalUri: resource.uri });
72
+ }
73
+ }
74
+ }
75
+ }
76
+ /** Returns all prefixed MCP Resource objects. */
77
+ listResources() {
78
+ return this.entries.map((e) => e.resource);
79
+ }
80
+ /** Resolves a resource URI to its upstream app and original URI, or null if unknown. */
81
+ resolveUri(uri) {
82
+ return this.uriMap.get(uri) ?? null;
83
+ }
84
+ }
85
+ export class PromptRouter {
86
+ routes = new Map();
87
+ constructor(upstreamPrompts) {
88
+ for (const [appName, prompts] of upstreamPrompts) {
89
+ const appShortName = getAppShortName(appName);
90
+ for (const prompt of prompts) {
91
+ const prefixedName = ToolRouter.prefixName(appShortName, prompt.name);
92
+ const prefixedPrompt = { ...prompt, name: prefixedName };
93
+ this.routes.set(prefixedName, {
94
+ appName,
95
+ appShortName,
96
+ originalName: prompt.name,
97
+ prefixedName,
98
+ prompt: prefixedPrompt,
99
+ });
100
+ }
101
+ }
102
+ }
103
+ /** Returns all prefixed MCP Prompt objects. */
104
+ listPrompts() {
105
+ return Array.from(this.routes.values()).map((e) => e.prompt);
106
+ }
107
+ /** Resolves a prefixed prompt name to its route entry, or null if unknown. */
108
+ resolve(prefixedName) {
109
+ return this.routes.get(prefixedName) ?? null;
110
+ }
111
+ }
112
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { ToolRouter, ResourceRouter, PromptRouter } from "./router.js";
3
+ import type { UpstreamManager } from "./upstream.js";
4
+ import type { ApprovalOptions } from "./hooks/approval.js";
5
+ import { SessionStore, type RiskLevel } from "./handlers/connect-agent.js";
6
+ import { CredentialRelay } from "./handlers/credential-relay.js";
7
+ export interface ChapterProxyServerConfig {
8
+ port?: number;
9
+ transport: "sse" | "streamable-http";
10
+ router: ToolRouter;
11
+ upstream: UpstreamManager;
12
+ db?: Database.Database;
13
+ agentName?: string;
14
+ authToken?: string;
15
+ approvalPatterns?: string[];
16
+ approvalOptions?: ApprovalOptions;
17
+ resourceRouter?: ResourceRouter;
18
+ promptRouter?: PromptRouter;
19
+ /** Token for authenticating credential service WebSocket connections. */
20
+ credentialProxyToken?: string;
21
+ /** Timeout for credential requests in milliseconds. Default: 30000. */
22
+ credentialRequestTimeoutMs?: number;
23
+ /** Agent's declared credential keys (for credential_request tool). */
24
+ declaredCredentials?: string[];
25
+ /** Role name for the agent session. */
26
+ roleName?: string;
27
+ /** Risk level for the agent's role. Controls connection limits. */
28
+ riskLevel?: RiskLevel;
29
+ /** Session type for audit logging (e.g., "acp" for ACP sessions). */
30
+ sessionType?: string;
31
+ /** ACP client editor name for audit logging (e.g., "zed", "jetbrains"). */
32
+ acpClient?: string;
33
+ /** Promise that resolves when upstream MCP servers and routing are ready.
34
+ * Health + connect-agent + credential_request work immediately;
35
+ * tool/resource/prompt handlers await this before processing. */
36
+ readyGate?: Promise<void>;
37
+ }
38
+ export declare class ChapterProxyServer {
39
+ private config;
40
+ private httpServer;
41
+ private activeTransports;
42
+ private sessionStore;
43
+ private credentialRelay;
44
+ constructor(config: ChapterProxyServerConfig);
45
+ /** Late-bind routing tables after upstream initialization completes. */
46
+ setRouting(opts: {
47
+ router: ToolRouter;
48
+ resourceRouter?: ResourceRouter;
49
+ promptRouter?: PromptRouter;
50
+ }): void;
51
+ /** Expose the session store for external access (e.g., risk-based limits in CHANGE 5). */
52
+ getSessionStore(): SessionStore;
53
+ /** Expose the credential relay for external access. */
54
+ getCredentialRelay(): CredentialRelay | null;
55
+ start(): Promise<void>;
56
+ stop(): Promise<void>;
57
+ private checkAuth;
58
+ private handleSseRequest;
59
+ private findSseTransport;
60
+ private handleStreamableHttpRequest;
61
+ private findStreamableTransport;
62
+ private createMcpServer;
63
+ }
64
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAsB,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAIjE,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,iBAAiB,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uEAAuE;IACvE,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;sEAEkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AA2BD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAA4F;IAC1G,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,gBAAgB,CAAsE;IAC9F,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAgC;gBAC3C,MAAM,EAAE,wBAAwB;IAY5C,wEAAwE;IACxE,UAAU,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,cAAc,CAAC,EAAE,cAAc,CAAC;QAAC,YAAY,CAAC,EAAE,YAAY,CAAA;KAAE,GAAG,IAAI;IAI5G,0FAA0F;IAC1F,eAAe,IAAI,YAAY;IAI/B,uDAAuD;IACvD,kBAAkB,IAAI,eAAe,GAAG,IAAI;IAItC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,2BAA2B;IAiCnC,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,eAAe;CAiMxB"}
package/dist/server.js ADDED
@@ -0,0 +1,388 @@
1
+ import { createServer } from "node:http";
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
4
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
+ import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
6
+ import { auditPreHook, auditPostHook } from "./hooks/audit.js";
7
+ import { matchesApprovalPattern, requestApproval } from "./hooks/approval.js";
8
+ import { SessionStore, handleConnectAgent } from "./handlers/connect-agent.js";
9
+ import { CredentialRelay } from "./handlers/credential-relay.js";
10
+ // ── credential_request Tool Definition ──────────────────────────────────
11
+ const CREDENTIAL_REQUEST_TOOL = {
12
+ name: "credential_request",
13
+ description: "Request a credential value from the credential service. Returns the resolved credential or an error.",
14
+ inputSchema: {
15
+ type: "object",
16
+ properties: {
17
+ key: {
18
+ type: "string",
19
+ description: "The credential key to request (e.g., OPENAI_API_KEY)",
20
+ },
21
+ session_token: {
22
+ type: "string",
23
+ description: "The agent session token received from connect-agent",
24
+ },
25
+ },
26
+ required: ["key", "session_token"],
27
+ },
28
+ };
29
+ // ── ChapterProxyServer ──────────────────────────────────────────────────
30
+ const DEFAULT_PORT = 9090;
31
+ export class ChapterProxyServer {
32
+ config;
33
+ httpServer = null;
34
+ activeTransports = new Set();
35
+ sessionStore;
36
+ credentialRelay = null;
37
+ constructor(config) {
38
+ this.config = { ...config, port: config.port ?? DEFAULT_PORT };
39
+ this.sessionStore = new SessionStore(config.riskLevel);
40
+ if (config.credentialProxyToken) {
41
+ this.credentialRelay = new CredentialRelay({
42
+ credentialProxyToken: config.credentialProxyToken,
43
+ requestTimeoutMs: config.credentialRequestTimeoutMs,
44
+ });
45
+ }
46
+ }
47
+ /** Late-bind routing tables after upstream initialization completes. */
48
+ setRouting(opts) {
49
+ this.config = { ...this.config, ...opts };
50
+ }
51
+ /** Expose the session store for external access (e.g., risk-based limits in CHANGE 5). */
52
+ getSessionStore() {
53
+ return this.sessionStore;
54
+ }
55
+ /** Expose the credential relay for external access. */
56
+ getCredentialRelay() {
57
+ return this.credentialRelay;
58
+ }
59
+ async start() {
60
+ const { port, transport } = this.config;
61
+ this.httpServer = createServer((req, res) => {
62
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
63
+ // Health endpoint — no auth required
64
+ if (req.method === "GET" && url.pathname === "/health") {
65
+ res.writeHead(200, { "Content-Type": "text/plain" });
66
+ res.end("ok");
67
+ return;
68
+ }
69
+ // Connect-agent endpoint — uses its own auth (MCP_PROXY_TOKEN)
70
+ if (url.pathname === "/connect-agent") {
71
+ if (this.config.authToken) {
72
+ handleConnectAgent(req, res, this.config.authToken, this.sessionStore, this.config.agentName, this.config.roleName);
73
+ }
74
+ else {
75
+ res.writeHead(500, { "Content-Type": "application/json" });
76
+ res.end(JSON.stringify({ error: "Proxy not configured with auth token" }));
77
+ }
78
+ return;
79
+ }
80
+ // Auth check — before any MCP handling
81
+ if (this.config.authToken && !this.checkAuth(req)) {
82
+ res.writeHead(401, { "Content-Type": "application/json" });
83
+ res.end(JSON.stringify({ error: "Unauthorized" }));
84
+ return;
85
+ }
86
+ if (transport === "sse") {
87
+ this.handleSseRequest(req, res);
88
+ }
89
+ else {
90
+ this.handleStreamableHttpRequest(req, res);
91
+ }
92
+ });
93
+ // WebSocket upgrade handler for credential service
94
+ if (this.credentialRelay) {
95
+ const relay = this.credentialRelay;
96
+ this.httpServer.on("upgrade", (req, socket, head) => {
97
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
98
+ if (url.pathname === "/ws/credentials") {
99
+ relay.handleUpgrade(req, socket, head);
100
+ }
101
+ else {
102
+ socket.destroy();
103
+ }
104
+ });
105
+ }
106
+ const server = this.httpServer;
107
+ return new Promise((resolve, reject) => {
108
+ server.on("error", reject);
109
+ server.listen(port, () => {
110
+ server.removeListener("error", reject);
111
+ resolve();
112
+ });
113
+ });
114
+ }
115
+ async stop() {
116
+ // Close credential relay first
117
+ if (this.credentialRelay) {
118
+ this.credentialRelay.close();
119
+ }
120
+ const closePromises = Array.from(this.activeTransports).map(async (t) => {
121
+ try {
122
+ await t.close();
123
+ }
124
+ catch {
125
+ // Best-effort close
126
+ }
127
+ });
128
+ await Promise.all(closePromises);
129
+ this.activeTransports.clear();
130
+ const httpServer = this.httpServer;
131
+ if (httpServer) {
132
+ await new Promise((resolve, reject) => {
133
+ httpServer.close((err) => (err ? reject(err) : resolve()));
134
+ });
135
+ this.httpServer = null;
136
+ }
137
+ }
138
+ // ── Auth ─────────────────────────────────────────────────────────
139
+ checkAuth(req) {
140
+ const auth = req.headers.authorization;
141
+ if (!auth)
142
+ return false;
143
+ const [scheme, token] = auth.split(" ", 2);
144
+ return scheme === "Bearer" && token === this.config.authToken;
145
+ }
146
+ // ── SSE Transport ──────────────────────────────────────────────────
147
+ handleSseRequest(req, res) {
148
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
149
+ if (req.method === "GET" && url.pathname === "/sse") {
150
+ const transport = new SSEServerTransport("/messages", res);
151
+ this.activeTransports.add(transport);
152
+ transport.onclose = () => this.activeTransports.delete(transport);
153
+ const server = this.createMcpServer();
154
+ server.connect(transport).catch(() => {
155
+ this.activeTransports.delete(transport);
156
+ });
157
+ return;
158
+ }
159
+ if (req.method === "POST" && url.pathname === "/messages") {
160
+ const sessionId = url.searchParams.get("sessionId");
161
+ const transport = this.findSseTransport(sessionId);
162
+ if (!transport) {
163
+ res.writeHead(400, { "Content-Type": "application/json" });
164
+ res.end(JSON.stringify({ error: "No active SSE session" }));
165
+ return;
166
+ }
167
+ transport.handlePostMessage(req, res);
168
+ return;
169
+ }
170
+ res.writeHead(404);
171
+ res.end();
172
+ }
173
+ findSseTransport(sessionId) {
174
+ if (!sessionId)
175
+ return undefined;
176
+ for (const t of this.activeTransports) {
177
+ if (t instanceof SSEServerTransport && t.sessionId === sessionId) {
178
+ return t;
179
+ }
180
+ }
181
+ return undefined;
182
+ }
183
+ // ── Streamable HTTP Transport ──────────────────────────────────────
184
+ handleStreamableHttpRequest(req, res) {
185
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
186
+ if (url.pathname === "/mcp") {
187
+ // For streamable-http, we create a transport per session via the initialize request
188
+ // The transport handles session management internally
189
+ if (req.method === "POST" || req.method === "GET" || req.method === "DELETE") {
190
+ const sessionId = req.headers["mcp-session-id"];
191
+ let transport = this.findStreamableTransport(sessionId);
192
+ if (!transport) {
193
+ const newTransport = new StreamableHTTPServerTransport({
194
+ sessionIdGenerator: () => crypto.randomUUID(),
195
+ });
196
+ this.activeTransports.add(newTransport);
197
+ newTransport.onclose = () => this.activeTransports.delete(newTransport);
198
+ const server = this.createMcpServer();
199
+ server.connect(newTransport).catch(() => {
200
+ this.activeTransports.delete(newTransport);
201
+ });
202
+ transport = newTransport;
203
+ }
204
+ transport.handleRequest(req, res);
205
+ return;
206
+ }
207
+ }
208
+ res.writeHead(404);
209
+ res.end();
210
+ }
211
+ findStreamableTransport(sessionId) {
212
+ if (!sessionId)
213
+ return undefined;
214
+ for (const t of this.activeTransports) {
215
+ if (t instanceof StreamableHTTPServerTransport && t.sessionId === sessionId) {
216
+ return t;
217
+ }
218
+ }
219
+ return undefined;
220
+ }
221
+ // ── MCP Server Factory ────────────────────────────────────────────
222
+ createMcpServer() {
223
+ // Destructure only stable (non-late-bound) fields.
224
+ // router, upstream, resourceRouter, promptRouter are accessed via
225
+ // this.config.* so they pick up values set by setRouting().
226
+ const { db, agentName, approvalPatterns, approvalOptions } = this.config;
227
+ const capabilities = {
228
+ tools: {},
229
+ resources: {},
230
+ prompts: {},
231
+ };
232
+ const server = new Server({ name: "chapter", version: "0.1.0" }, { capabilities });
233
+ // ── Tool Handlers ───────────────────────────────────────────────
234
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
235
+ // Wait for upstream MCP servers to connect and routing tables to be built
236
+ if (this.config.readyGate)
237
+ await this.config.readyGate;
238
+ const tools = this.config.router.listTools();
239
+ if (this.credentialRelay) {
240
+ tools.push(CREDENTIAL_REQUEST_TOOL);
241
+ }
242
+ return { tools };
243
+ });
244
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
245
+ const { name, arguments: args } = request.params;
246
+ // Handle internal credential_request tool — no readyGate needed
247
+ if (name === "credential_request" && this.credentialRelay) {
248
+ const key = args?.key;
249
+ const sessionToken = args?.session_token;
250
+ if (!key || !sessionToken) {
251
+ return {
252
+ content: [{ type: "text", text: "Missing required arguments: key, session_token" }],
253
+ isError: true,
254
+ };
255
+ }
256
+ const result = await this.credentialRelay.handleCredentialRequest(this.sessionStore, key, sessionToken, this.config.declaredCredentials);
257
+ if (result.error) {
258
+ return {
259
+ content: [{ type: "text", text: `Credential error: ${result.error}` }],
260
+ isError: true,
261
+ };
262
+ }
263
+ return {
264
+ content: [{ type: "text", text: JSON.stringify({ key: result.key, value: result.value }) }],
265
+ };
266
+ }
267
+ // All other tools require upstreams to be ready
268
+ if (this.config.readyGate)
269
+ await this.config.readyGate;
270
+ const { router, upstream } = this.config;
271
+ const route = router.resolve(name);
272
+ if (!route) {
273
+ if (db) {
274
+ const ctx = {
275
+ agentName: agentName ?? "unknown",
276
+ roleName: "unknown",
277
+ appName: "unknown",
278
+ toolName: name,
279
+ prefixedToolName: name,
280
+ arguments: args,
281
+ sessionType: this.config.sessionType,
282
+ acpClient: this.config.acpClient,
283
+ };
284
+ const pre = auditPreHook(ctx);
285
+ auditPostHook(ctx, pre, `Unknown tool: ${name}`, "denied", db);
286
+ }
287
+ return {
288
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
289
+ isError: true,
290
+ };
291
+ }
292
+ const ctx = db
293
+ ? {
294
+ agentName: agentName ?? "unknown",
295
+ roleName: "unknown",
296
+ appName: route.appName,
297
+ toolName: route.originalToolName,
298
+ prefixedToolName: route.prefixedToolName,
299
+ arguments: args,
300
+ sessionType: this.config.sessionType,
301
+ acpClient: this.config.acpClient,
302
+ }
303
+ : undefined;
304
+ const pre = ctx ? auditPreHook(ctx) : undefined;
305
+ // Approval check — between audit pre-hook and upstream call
306
+ if (db && ctx && approvalPatterns?.length && matchesApprovalPattern(route.prefixedToolName, approvalPatterns)) {
307
+ const approval = await requestApproval(ctx, db, approvalOptions);
308
+ if (approval === "denied") {
309
+ const msg = `Tool call denied: ${route.prefixedToolName} requires approval`;
310
+ if (pre) {
311
+ auditPostHook(ctx, pre, msg, "denied", db);
312
+ }
313
+ return {
314
+ content: [{ type: "text", text: msg }],
315
+ isError: true,
316
+ };
317
+ }
318
+ if (approval === "timeout") {
319
+ const ttl = approvalOptions?.ttlSeconds ?? 300;
320
+ const msg = `Tool call timed out: ${route.prefixedToolName} approval expired after ${ttl} seconds`;
321
+ if (pre) {
322
+ auditPostHook(ctx, pre, msg, "timeout", db);
323
+ }
324
+ return {
325
+ content: [{ type: "text", text: msg }],
326
+ isError: true,
327
+ };
328
+ }
329
+ // approval === "approved" — fall through to upstream call
330
+ }
331
+ try {
332
+ const result = await upstream.callTool(route.appName, route.originalToolName, args);
333
+ if (db && ctx && pre) {
334
+ auditPostHook(ctx, pre, result, "success", db);
335
+ }
336
+ return result;
337
+ }
338
+ catch (err) {
339
+ const message = err instanceof Error ? err.message : String(err);
340
+ if (db && ctx && pre) {
341
+ auditPostHook(ctx, pre, message, "error", db);
342
+ }
343
+ return {
344
+ content: [{ type: "text", text: message }],
345
+ isError: true,
346
+ };
347
+ }
348
+ });
349
+ // ── Resource Handlers ──────────────────────────────────────────────
350
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
351
+ if (this.config.readyGate)
352
+ await this.config.readyGate;
353
+ const { resourceRouter } = this.config;
354
+ return { resources: resourceRouter ? resourceRouter.listResources() : [] };
355
+ });
356
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
357
+ if (this.config.readyGate)
358
+ await this.config.readyGate;
359
+ const { resourceRouter, upstream } = this.config;
360
+ const { uri } = request.params;
361
+ const route = resourceRouter?.resolveUri(uri);
362
+ if (!route) {
363
+ throw new Error(`Unknown resource: ${uri}`);
364
+ }
365
+ return upstream.readResource(route.appName, route.originalUri);
366
+ });
367
+ // ── Prompt Handlers ────────────────────────────────────────────────
368
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
369
+ if (this.config.readyGate)
370
+ await this.config.readyGate;
371
+ const { promptRouter } = this.config;
372
+ return { prompts: promptRouter ? promptRouter.listPrompts() : [] };
373
+ });
374
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
375
+ if (this.config.readyGate)
376
+ await this.config.readyGate;
377
+ const { promptRouter, upstream } = this.config;
378
+ const { name, arguments: args } = request.params;
379
+ const route = promptRouter?.resolve(name);
380
+ if (!route) {
381
+ throw new Error(`Unknown prompt: ${name}`);
382
+ }
383
+ return upstream.getPrompt(route.appName, route.originalName, args);
384
+ });
385
+ return server;
386
+ }
387
+ }
388
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAEL,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,WAAW,CAAS;gBAEhB,IAAI,EAAE,iBAAiB,EAAE;IAW/B,UAAU,CAAC,SAAS,GAAE,MAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAY1C,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYlD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAY9C,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,cAAc,CAAC;IAKpB,YAAY,CAChB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC;IAKxB,SAAS,CACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,eAAe,CAAC;IAKrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B,OAAO,CAAC,aAAa;CAOtB;AAID,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,GACxB,oBAAoB,GAAG,kBAAkB,GAAG,6BAA6B,CA+C3E"}
@@ -0,0 +1,156 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
4
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
+ import { CallToolResultSchema, } from "@modelcontextprotocol/sdk/types.js";
6
+ // ── UpstreamManager ────────────────────────────────────────────────────
7
+ const DEFAULT_TIMEOUT_MS = 30_000;
8
+ export class UpstreamManager {
9
+ configs;
10
+ clients = new Map();
11
+ initialized = false;
12
+ constructor(apps) {
13
+ const names = apps.map((a) => a.name);
14
+ const dupes = names.filter((n, i) => names.indexOf(n) !== i);
15
+ if (dupes.length > 0) {
16
+ throw new Error(`Duplicate app names: ${[...new Set(dupes)].join(", ")}`);
17
+ }
18
+ this.configs = apps;
19
+ }
20
+ async initialize(timeoutMs = DEFAULT_TIMEOUT_MS) {
21
+ if (this.initialized) {
22
+ throw new Error("UpstreamManager is already initialized. Call shutdown() first.");
23
+ }
24
+ const connectPromises = this.configs.map(async (config) => {
25
+ const transport = createTransport(config);
26
+ const client = new Client({ name: "chapter-upstream", version: "0.1.0" });
27
+ await client.connect(transport);
28
+ this.clients.set(config.name, client);
29
+ });
30
+ let timer;
31
+ const timeout = new Promise((_, reject) => {
32
+ timer = setTimeout(() => {
33
+ const connected = new Set(this.clients.keys());
34
+ const failed = this.configs
35
+ .map((c) => c.name)
36
+ .filter((name) => !connected.has(name));
37
+ reject(new Error(`Upstream initialization timed out after ${timeoutMs}ms. Failed: ${failed.join(", ")}`));
38
+ }, timeoutMs);
39
+ });
40
+ try {
41
+ await Promise.race([Promise.all(connectPromises), timeout]);
42
+ this.initialized = true;
43
+ }
44
+ catch (err) {
45
+ await this.shutdown();
46
+ throw err;
47
+ }
48
+ finally {
49
+ if (timer)
50
+ clearTimeout(timer);
51
+ }
52
+ }
53
+ async getTools(appName) {
54
+ const client = this.requireClient(appName);
55
+ const tools = [];
56
+ let cursor;
57
+ do {
58
+ const result = await client.listTools({ cursor });
59
+ tools.push(...result.tools);
60
+ cursor = result.nextCursor;
61
+ } while (cursor);
62
+ return tools;
63
+ }
64
+ async getResources(appName) {
65
+ const client = this.requireClient(appName);
66
+ const resources = [];
67
+ let cursor;
68
+ do {
69
+ const result = await client.listResources({ cursor });
70
+ resources.push(...result.resources);
71
+ cursor = result.nextCursor;
72
+ } while (cursor);
73
+ return resources;
74
+ }
75
+ async getPrompts(appName) {
76
+ const client = this.requireClient(appName);
77
+ const prompts = [];
78
+ let cursor;
79
+ do {
80
+ const result = await client.listPrompts({ cursor });
81
+ prompts.push(...result.prompts);
82
+ cursor = result.nextCursor;
83
+ } while (cursor);
84
+ return prompts;
85
+ }
86
+ async callTool(appName, toolName, args) {
87
+ const client = this.requireClient(appName);
88
+ return client.callTool({ name: toolName, arguments: args }, CallToolResultSchema);
89
+ }
90
+ async readResource(appName, uri) {
91
+ const client = this.requireClient(appName);
92
+ return client.readResource({ uri });
93
+ }
94
+ async getPrompt(appName, name, args) {
95
+ const client = this.requireClient(appName);
96
+ return client.getPrompt({ name, arguments: args });
97
+ }
98
+ async shutdown() {
99
+ const closePromises = Array.from(this.clients.entries()).map(async ([name, client]) => {
100
+ try {
101
+ await client.close();
102
+ }
103
+ catch {
104
+ // Swallow shutdown errors — best-effort close
105
+ console.error(`Error closing upstream client "${name}"`);
106
+ }
107
+ });
108
+ await Promise.all(closePromises);
109
+ this.clients.clear();
110
+ this.initialized = false;
111
+ }
112
+ requireClient(appName) {
113
+ const client = this.clients.get(appName);
114
+ if (!client) {
115
+ throw new Error(`Unknown app: ${appName}`);
116
+ }
117
+ return client;
118
+ }
119
+ }
120
+ // ── Transport Factory ──────────────────────────────────────────────────
121
+ export function createTransport(config) {
122
+ const { app, env } = config;
123
+ switch (app.transport) {
124
+ case "stdio": {
125
+ if (!app.command) {
126
+ throw new Error(`App "${config.name}" has transport "stdio" but no command specified`);
127
+ }
128
+ return new StdioClientTransport({
129
+ command: app.command,
130
+ args: app.args,
131
+ env: env
132
+ ? {
133
+ ...Object.fromEntries(Object.entries(process.env).filter((e) => e[1] != null)),
134
+ ...env,
135
+ }
136
+ : undefined,
137
+ cwd: config.cwd,
138
+ });
139
+ }
140
+ case "sse": {
141
+ if (!app.url) {
142
+ throw new Error(`App "${config.name}" has transport "sse" but no url specified`);
143
+ }
144
+ return new SSEClientTransport(new URL(app.url));
145
+ }
146
+ case "streamable-http": {
147
+ if (!app.url) {
148
+ throw new Error(`App "${config.name}" has transport "streamable-http" but no url specified`);
149
+ }
150
+ return new StreamableHTTPClientTransport(new URL(app.url));
151
+ }
152
+ default:
153
+ throw new Error(`App "${config.name}" has unsupported transport: ${app.transport}`);
154
+ }
155
+ }
156
+ //# sourceMappingURL=upstream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream.js","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@clawmasons/proxy",
3
+ "version": "0.1.0",
4
+ "description": "Clawmasons Chapter MCP proxy server",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.build.json",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "@clawmasons/shared": "0.1.0",
24
+ "@modelcontextprotocol/sdk": "^1.27.1",
25
+ "better-sqlite3": "^12.6.2",
26
+ "ws": "^8.19.0"
27
+ }
28
+ }