{"_id":"@cyanmycelium/mcp-broker","_rev":"16-a574f5298f174f64c9fd96ecb827d92e","name":"@cyanmycelium/mcp-broker","dist-tags":{"latest":"1.6.1"},"versions":{"0.1.0":{"name":"@cyanmycelium/mcp-broker","version":"0.1.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@0.1.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"79120e611bd51e8dad729b6486ea7952f5837417","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-0.1.0.tgz","fileCount":78,"integrity":"sha512-/XyygK75caQXTFmZ5H+mEntVvbEbt/0tfC7fVcuCvmwdq4OGVqmIcHU26ePIILiHTEUTIv8BsSdhu5RueIWLhA==","signatures":[{"sig":"MEQCIGzjZgq9Nl28/cM9Vfczva180RRlG8kOqVPpFa320ZyzAiAesnurLmDdm3FPCeCluJcab0500bhM2WXvVecCiepcDg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":351898},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"82712dec17f1080ede6c43bd1771a09ad27b307d","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"npm run clean && npm run compile && npm run copy:assets","clean":"rimraf dist tsconfig.build.tsbuildinfo","start":"node dist/bin.js","watch":"tsc -b tsconfig.build.json -w","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","compile":"tsc -b tsconfig.build.json","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test"},"_npmUser":{"name":"gaume","email":"gaume.pelletier@gmail.com"},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node"},"_npmVersion":"10.9.3","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"22.20.0","dependencies":{"ws":"^8.18.0","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^1.6.0","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_0.1.0_1779211688336_0.2926501220464792","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cyanmycelium/mcp-broker","version":"0.2.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@0.2.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"adcfc2494ba5eafc920e4742b173a75fef0d10e6","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-0.2.0.tgz","fileCount":78,"integrity":"sha512-7vQ5ZnqLmPTSMqTkxMRrQ9N+cX6dlneXnZvXmQG3t/9/3dRp+3jlkt+wG48N6J2Czb4aSnBNOqG7kxmZUXNyOg==","signatures":[{"sig":"MEYCIQDE/oXBS038WqZK8k2g9i6j2XtVJVVF1+qtOg6++TO2EgIhAO3S6naBSEGcqsBG/vCRauKdCdp1EGJyG8aXkXg9Ikcn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":351898},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"e493263e6db4fbe6233835be10d6022cf90dbcb3","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"npm run clean && npm run compile && npm run copy:assets","clean":"rimraf dist tsconfig.build.tsbuildinfo","start":"node dist/bin.js","watch":"tsc -b tsconfig.build.json -w","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","compile":"tsc -b tsconfig.build.json","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node"},"_npmVersion":"11.14.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^1.6.0","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_0.2.0_1779212950108_0.7011440586412341","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cyanmycelium/mcp-broker","version":"0.3.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@0.3.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"df5805cfb3cc16abc7fecffa1705e315edd17def","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-0.3.0.tgz","fileCount":112,"integrity":"sha512-x9QdVUd4MQ/yAhwjkIna7cm7qnBJwgc8m5bol9HBimAutpYA6UmiJFJVbbRmQer44Ov3AOHdVNGvDrj2GEXS5g==","signatures":[{"sig":"MEUCIQCDBmBA9cDn+9xw64ZK4otEB0q8D1Cq86mB3ts8OTKgugIgL0K4Jmuu+uN3i5k82yGPsZnmx6K5Po5dpu8kBB91isE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":520120},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"80d7477a0d6cc1b0e0da27812b76fa4faeb8621a","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"npm run clean && npm run compile && npm run copy:assets","clean":"rimraf dist tsconfig.build.tsbuildinfo","start":"node dist/bin.js","watch":"tsc -b tsconfig.build.json -w","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","compile":"tsc -b tsconfig.build.json","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node"},"_npmVersion":"11.15.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.2.1"},"_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^1.6.0","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_0.3.0_1779464986167_0.966374999874708","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@cyanmycelium/mcp-broker","version":"0.4.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@0.4.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"94349484bb7951e52e7cfe5ef04554befd7445c7","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-0.4.0.tgz","fileCount":112,"integrity":"sha512-Y0y3a7p1IlyeOuyHZUaVjD5BNydwE956sHrx57GCDSPQft3w/dVbIhlvXE06/VK5RGbS8peT0vVkprVnn2SBaw==","signatures":[{"sig":"MEQCIDf+gFDR0iF4rSSnJ1P1cXCY3DOD00uof7gwWX714KjYAiA0YsQJMc7LU8NHsJj9Oq4q6FPqWtlyzMaetHJOp86m4w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":507745},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"d9f0f748c00476da6d2f30046082d522fb1cbef3","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"npm run clean && npm run compile && npm run copy:assets","clean":"rimraf dist tsconfig.build.tsbuildinfo","start":"node dist/bin.js","watch":"tsc -b tsconfig.build.json -w","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","compile":"tsc -b tsconfig.build.json","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node"},"_npmVersion":"11.16.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^1.6.0","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_0.4.0_1779949413422_0.6208806272484677","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@cyanmycelium/mcp-broker","version":"1.0.1","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.0.1","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"28c55af00c6ad53fb939c6b05aad1e08f562654b","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.0.1.tgz","fileCount":202,"integrity":"sha512-HPGVAL6OLYxJ3la05FvDbMfzgfkOj2G4QlCssOF2qtMbSpvq2FvCGbNHsbFvqvBW7SERL9mp/u1rTLOr/rLO2g==","signatures":[{"sig":"MEQCIDIpzi51LlUGG3hQu+R4TbxydbBgJxix1t1MucvardS+AiB0qQSCRbMSUUGu+nHj6Cnub5ArJjBUWM3iEOx1u2yaYw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1268357},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"db5dea7f4089d43511c17c9859013fb061d090d4","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"npm run clean && npm run compile && npm run copy:assets","clean":"rimraf dist tsconfig.build.tsbuildinfo","start":"node dist/bin.js","watch":"tsc -b tsconfig.build.json -w","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","compile":"tsc -b tsconfig.build.json","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node"},"_npmVersion":"11.18.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.0.1_1785162007559_0.02064597858960604","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@cyanmycelium/mcp-broker","version":"1.2.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.2.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"d5cb82606feaeeb22dce702488db9412f4c7d184","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.2.0.tgz","fileCount":94,"integrity":"sha512-xdM5BiB6Vkviud/ARte8fQEJCzVmKpcfz+NoXVeIT5Xi3gs84RqBcRYY+W7HMrqnRIrJyjHZADBqfmnWMR6Hhw==","signatures":[{"sig":"MEYCIQCIjb7gDux55cYf3gDiAYFrwfZ3JqWKm6xtGLjYYgOo+gIhAN1XU5Guygm4kT4dOPRngWdpbB56h/pJ0P/OICUa/QFD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1449692},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"352af21280295ae5739e21b769a87c3d614556ed","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.18.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.7.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.2.0_1785255810990_0.04947576721558611","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@cyanmycelium/mcp-broker","version":"1.2.1","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.2.1","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"362c9ede6779f2175b37f107e9df646a6bb71899","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.2.1.tgz","fileCount":94,"integrity":"sha512-UvZ945kV7+buYeeyvdFnvyxXhA9Glk8+z445ntKV1k4si4z4wD1m8/tlaeSI5W/Sc1sMjQm163K4e4BdW6xg2g==","signatures":[{"sig":"MEYCIQDOSMVRlnttYSK6BUqaxe2JKfQIdzJYZ8uTHbCZT/L5GwIhAM/G3cam9jzXjMGWCd8o6U9fKXY5PmU7t+yB89qsmeBd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1457610},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"2cec3d36ee74deec62d53d1da2b9a2560483d0db","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^0.7.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.2.1_1788285077887_0.4818073619719654","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@cyanmycelium/mcp-broker","version":"1.3.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.3.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"99b743c91fe11057d1aed69facee0e93a0914b83","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.3.0.tgz","fileCount":102,"integrity":"sha512-IFuq8PAwZ/04LKhED33HWqlrp3kEi3LKMXs4exJTWOlauqiMvMtCmUu+E8cRSeUIuzWzf50pvr6JZlytIAXR8Q==","signatures":[{"sig":"MEUCIBAd2MTDWr8cR0azP+dFu8gsgk15qSxm0OH2udB9jOlHAiEAuXHpyfVkRrdu3Nk+r0BopG1WVISuz2K8XnrjIG5ueNs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQD89Do2NPTg4ZmHMO9j01VO/4z1r4vO8gzMVBodeaCxxAIgPGMuHvSBpRbvQlSd4LdBzj45CQb0Kx82LaQK1BzSjm0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2211812},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"a3370839484d80fdb26df14d6411644e2df9b64a","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.3.0_1789231768149_0.88458017900902","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@cyanmycelium/mcp-broker","version":"1.3.1","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.3.1","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"102c97950dda5f4fee7b20d94eb67eb04c559095","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.3.1.tgz","fileCount":102,"integrity":"sha512-8BW1IYdd7LWchA2YVf2c9XV+B/ejBtdhX2/jb/fyZHJlFM6NYR5jIWrnGwPFRRHE7mO/A0lraZYEqA66UqUEYg==","signatures":[{"sig":"MEQCIAyWaJTuPTzHUvKC/jQweg6ArrsF3+O2gOeXnVC/QdJWAiATYCVpNOOFdwYlAioJOVHa045hyfX/LCTMuQiMd7AzKw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDrG2fk+DgxJHjiLm1eiRW8GK7ew2MaW0c7mOX1lXvNzQIhAO3sAq/drzM27e7k15lNd1tNX4POwM6YixIieR6X1TnA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2215915},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"b4c69535c22cbdcef77e591acd1dfb6194748685","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.3.1_1789300855219_0.06018669964543455","host":"s3://npm-registry-packages-npm-production"}},"1.3.2":{"name":"@cyanmycelium/mcp-broker","version":"1.3.2","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.3.2","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"5e72f4a56b339b531086075de07b9285e1f23293","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.3.2.tgz","fileCount":103,"integrity":"sha512-ft6B1P9PGdbtoY3NS5bA+driUfdrZ2CRpcHSW9+LgAGKWTtdk7vsKW1aItOwrTB52Miqso6ccjlUtN8XgSgY6A==","signatures":[{"sig":"MEYCIQDxjimQBSicdXPHk0sTfNKYbclSKMGM+5xeglmEKvZdUgIhAIDSBjMub9AGuneZ0YF1v3wJlEC0gt+swGxoPFR3Hshn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCyfxfCN6y43KszSzQbXrUdP6d6cP1tF0pCrXn9Ouh7jAIgBwPsn7oFgU8QjfHzozirdZcXF1AAnPgUEOL7yoJnEm8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2230245},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"863588828b37f238445f7fa6ac46ea4bbf2985e2","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.3.2_1789378662151_0.8674555769079464","host":"s3://npm-registry-packages-npm-production"}},"1.3.3":{"name":"@cyanmycelium/mcp-broker","version":"1.3.3","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.3.3","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"1dc687eeb73a5c455a45aaa0d0924178589635ad","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.3.3.tgz","fileCount":103,"integrity":"sha512-Peh94B0EX6VJ4iMZRNbKmU3DXRDrzH7chVOfiivZ9ae7FIBAu37MHpsIFBVZ/aidCKwNzPYbCXpJ5Ppg9j4n2Q==","signatures":[{"sig":"MEYCIQCjZz0mCwsuDtvVDq1DERkOa80o6+GS7s2pFw4Bcm2SbgIhAMCOteWb/E1mNS9PW3esWyOmhpBVUhFOn8aAdaXZGsIr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICUlTm2jsapHYtPcWWAyXNLeUG0P/JqGDf5bC8IVylCLAiBCg9df0XRQ1BvpPq45mxLFgIXFJC5L2684Uf85HziWBg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.3.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2230245},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"0f150eafbe58cd5401fff891a3f2ea45eeb71c76","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.3.3_1789982289912_0.8175070582704211","host":"s3://npm-registry-packages-npm-production"}},"1.3.4":{"name":"@cyanmycelium/mcp-broker","version":"1.3.4","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.3.4","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"be6b32cfb0d23e50468345b6ff5d011581f95e1e","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.3.4.tgz","fileCount":103,"integrity":"sha512-mgYEWGYb81/HEtC1CPI4lpnbC8hu39bkZafHcQx4aR8aDB/m2rPlh2hmqgAiXceArdnTlBs7iv4i6FyEvSEKLQ==","signatures":[{"sig":"MEUCIQCyBQrucsouddqBk+0BrSftZppXgZ2R2VyUj7/h94s/ugIgPdyOfStxrDt9wXQh57ugBf0+d7GCQDqsVOVsufvOaX4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBNBTIG1PH9CwHGM/g8twTOLq1MjoCoCAHNsU3+InZFRAiEAsTQSaIUz1s31MRV+0j7lsXib7HMKci73ErSp7OiTEfA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.3.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2230245},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"b7092a243b2e7cdc1d2de21a5df9ed077b77827c","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.19.1","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.2.1"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.3.4_1789992976741_0.2234573280960055","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@cyanmycelium/mcp-broker","version":"1.4.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.4.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"ddcdbf3944a309f687878fd6ab667fa7741ab0e6","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.4.0.tgz","fileCount":104,"integrity":"sha512-1QG27Z1JjGY1+of5yjwqGoKw7NfxY97OAXZJiiN2NdPN1jGghkEotrEAIXFNgtGltAiF0cMAFuHP94SRqGaD1Q==","signatures":[{"sig":"MEUCIQDt4D27TXvXm8+JjhKmd+VdSZRKxyYg9wb4H41ohQ1MOQIgPkYKsg7I9fIJTGYZtiv0ThhDw9+Aq0fASeC1sZR5D0c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCfTOdqSgaVOgs2pwgRBOhfnRtkDNiE4QXj5+umzDDZEgIhAL5pgk2LDhGyHfq6RrKfZVTBMplcVKhCEpahqDO5qHgi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2391996},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"ce0eec0d91ce81f0aff177e4141023c6ed894945","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.20.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.4.0_1790767214452_0.969394999854821","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@cyanmycelium/mcp-broker","version":"1.5.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.5.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"da4a5321a354b7dfdb8cc1656c27e093dc5e9cc5","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.5.0.tgz","fileCount":119,"integrity":"sha512-svJ1qbiLoUFckGm2J6clWzYDoiAzfI8YvSepg1KpzGFrj2XogKlGDSIqMNQnwJXE2bIYfquzPQM0lcBI5T4Z6A==","signatures":[{"sig":"MEYCIQDbOiwqswiCrvkg0bo2MfhgFP0pLXkvdlwCBwr7V2rgOAIhAIVHopcjeqPn7aVhxreSRKOtiBymemEFCR0fNTjN1/b/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIFegkEdnPiOasBKHZGyl1BZmBuJm/wMSPXvais8dTbu0AiA77Q1hH8FiJEk2bkGVqXumM/bRwOpOG/V4KcQEDX5AwA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2949955},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js","default":"./dist/testing/index.js"}},"gitHead":"e9aa44be137a2c77f83c7454b6e96f3e774179b7","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.21.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.4.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.5.0_1790875467652_0.8962546023352618","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@cyanmycelium/mcp-broker","version":"1.6.0","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","_id":"@cyanmycelium/mcp-broker@1.6.0","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"homepage":"https://github.com/pandaGaume/mcp-broker#readme","bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"bin":{"mcp-broker":"dist/bin.js"},"dist":{"shasum":"2bca21cfeeed5482e5fb75e4465688660bde1d6b","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.6.0.tgz","fileCount":120,"integrity":"sha512-KmlYece7COT5pUkF4+vkdVc4j7NSMWco3gj+PVgRE9ZwE1tNk60hd4Q+AHyoUXh280kFSFiyO0hTEBS/+/XOuA==","signatures":[{"sig":"MEUCIQCTIp8eGw0uq/mHjdoBB7LL4KwRxWt3EEspYmKSb5wifAIgXqyzRuQ53RLCWXm08z/kRpQbeBovhHvkAxEwaT2mC8g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCzGM6fY/MgZHZRj9WcMPEhr4Jjt6Ar8M/Jqcv5xgsw9QIgbDuuMvLh0/lIQgwbrp4ZapVLNFbZlQzaxP8/qZamG2Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3077771},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js","default":"./dist/testing/index.js"}},"gitHead":"dab20e8c5a1d79d7b86b3aaf566d3a4e49781175","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.21.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.4.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.3.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-broker_1.6.0_1790942782449_0.16149497188373507","host":"s3://npm-registry-packages-npm-production"}},"1.6.1":{"_id":"@cyanmycelium/mcp-broker@1.6.1","bin":{"mcp-broker":"dist/bin.js"},"bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"dist":{"shasum":"5d7b06b9ed27b0c03a01a8fdd2b7d19ad5e5ec53","tarball":"https://registry.npmjs.org/@cyanmycelium/mcp-broker/-/mcp-broker-1.6.1.tgz","fileCount":122,"integrity":"sha512-F2TK5PIqdD39Q7spughHr4q0uY6vSpZPvXeEqEnjGM0xORRXWNH9jsj8tQAJYNvwuUe9dlE4g0Iz0uo1j5GYQQ==","signatures":[{"sig":"MEUCIGbm+vhTT9ODGPnrQFoDCF7zZYl+jKTj/nRP+rvU6prtAiEA+wTu4yqhN7t/TnqjRgPsn3TESznNdEi5b1ngzHEa5Lc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEvdt4VA8laEm9Hckyj0vpyqWHK8D8V+Q3M27LGILc3UAiEAq+yJLLSiHzOe0CoSeMqU3Aj/7PRm9qGJPWKtaS4cKy8="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cyanmycelium%2fmcp-broker@1.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3144140},"main":"./dist/index.js","name":"@cyanmycelium/mcp-broker","type":"module","types":"./dist/index.d.ts","author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"module":"./dist/index.js","engines":{"node":">=20.11.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js","default":"./dist/testing/index.js"}},"gitHead":"9bf08e2ee77392a5871c0637ef38437fa53b3722","license":"Apache-2.0","scripts":{"lint":"eslint \"src/**/*.ts\" \"tests/**/*.ts\"","test":"vitest run","build":"tsup && npm run copy:assets","clean":"rimraf dist","start":"node dist/bin.js","watch":"tsup --watch","format":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","gen-cert":"node scripts/gen-cert.mjs","lint:fix":"eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix","pack:mcpb":"npm run build && node scripts/pack-mcpb.mjs","typecheck":"tsc -p tsconfig.json --noEmit","demo:oauth":"npm run build && node web/demos/oauth-lab/server/start.mjs","format:fix":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","leak-probe":"node --expose-gc scripts/leak-probe.mjs","test:watch":"vitest","copy:assets":"node scripts/copy-assets.mjs","prepublishOnly":"npm run lint && npm run build && npm test","demo:oauth:smoke":"node web/demos/oauth-lab/server/smoke-test.mjs"},"version":"1.6.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"15b2ff05-1704-4ad4-a865-b995d7f96b49"}},"homepage":"https://github.com/pandaGaume/mcp-broker#readme","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"_npmVersion":"11.21.0","description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","directories":{},"maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.0","jose":"^6.2.3","open":"^11.0.0","@cyanmycelium/mcp-core":"^1.4.1"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","tslib":"^2.8.1","eslint":"^8.57.0","rimraf":"~6.0.1","vitest":"^4.1.9","prettier":"^3.2.0","@types/ws":"^8.5.0","selfsigned":"^2.4.1","typescript":"^5.4.0","@types/node":"^20.11.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@cyanmycelium/mcp-broker-provider":"^0.4.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-broker_1.6.1_1791041235527_0.8476360268909271"}}},"time":{"created":"2026-05-19T17:28:08.205Z","modified":"2026-10-03T15:27:16.012Z","0.1.0":"2026-05-19T17:28:08.534Z","0.2.0":"2026-05-19T17:49:10.316Z","0.3.0":"2026-05-22T15:49:46.383Z","0.4.0":"2026-05-28T06:23:33.565Z","1.0.1":"2026-07-27T14:20:07.745Z","1.2.0":"2026-07-28T16:23:31.237Z","1.2.1":"2026-09-01T17:51:18.040Z","1.3.0":"2026-09-12T16:49:28.260Z","1.3.1":"2026-09-13T12:00:55.332Z","1.3.2":"2026-09-14T09:37:42.351Z","1.3.3":"2026-09-21T09:18:10.030Z","1.3.4":"2026-09-21T12:16:16.862Z","1.4.0":"2026-09-30T11:20:14.563Z","1.5.0":"2026-10-01T17:24:27.763Z","1.6.0":"2026-10-02T12:06:22.559Z","1.6.1":"2026-10-03T15:27:15.659Z"},"bugs":{"url":"https://github.com/pandaGaume/mcp-broker/issues"},"author":{"url":"CyanMycelium","name":"Guillaume Pelletier"},"license":"Apache-2.0","homepage":"https://github.com/pandaGaume/mcp-broker#readme","keywords":["mcp","model-context-protocol","broker","tunnel","websocket","jsonrpc","cyanmycelium"],"repository":{"url":"git+https://github.com/pandaGaume/mcp-broker.git","type":"git","directory":"node/packages/broker"},"description":"WebSocket-based Model Context Protocol broker. Aggregates multiple MCP providers behind a single endpoint with stdio, SSE, and Streamable HTTP client transports.","maintainers":[{"name":"gaume","email":"gaume.pelletier@gmail.com"}],"readme":"<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/pandaGaume/mcp-broker/main/docs/assets/logo.png\" alt=\"mcp-broker\" width=\"160\" />\n</p>\n\n[![npm](https://img.shields.io/npm/v/@cyanmycelium/mcp-broker)](https://www.npmjs.com/package/@cyanmycelium/mcp-broker)\n[![CI](https://github.com/pandaGaume/mcp-broker/actions/workflows/ci-node.yml/badge.svg)](https://github.com/pandaGaume/mcp-broker/actions/workflows/ci-node.yml)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n\n# @cyanmycelium/mcp-broker\n\nWebSocket-based [Model Context Protocol](https://modelcontextprotocol.io/) broker. Aggregates multiple MCP providers behind a single endpoint, with WebSocket, Streamable HTTP, SSE, and stdio client transports.\n\n> This is the Node/TypeScript implementation of the broker. Architecture, wire protocol, and endpoints are documented language-neutrally in the [repository `docs/` folder](https://github.com/pandaGaume/mcp-broker/tree/main/docs), which is not shipped in the npm package. Every link out of this file is therefore absolute.\n\n| I want to | go to |\n|---|---|\n| publish my MCP server into a slot | [the pairing rule](#the-one-rule-that-costs-the-most-time) |\n| wire Claude Desktop or another stdio host | [Claude Desktop integration](#claude-desktop-integration) |\n| reach a slot as a client | [Install and run](#install-and-run), [Browser origins](#browser-origins) |\n| know what `_broker` and `_all` are | [Reserved slots](#reserved-slots-_broker-and-_all) |\n| configure the process | [Configuration](#configuration) |\n| embed the broker in my own process | [Programmatic API](#programmatic-api) |\n| fix something that is already broken | [Troubleshooting](#troubleshooting), or call `broker_diagnose` |\n\n## Install and run\n\n```sh\n# Run the broker without installing\nnpx @cyanmycelium/mcp-broker\n\n# Or install globally\nnpm install -g @cyanmycelium/mcp-broker\nmcp-broker\n```\n\nThe broker starts on `http://localhost:3000` by default.\n\n- Connect your MCP provider to: `ws://localhost:3000/provider/<name>`\n- Point an MCP client at: `http://localhost:3000/<name>/mcp` (Streamable HTTP) or `http://localhost:3000/<name>/sse` (legacy SSE) or `ws://localhost:3000/<name>` (raw WS)\n\n### The broker documents itself\n\nOnce it is running you do not need this README. The reserved `_broker` slot\nserves the integration guide over MCP, and diagnoses the deployment:\n\n| call it with | and you get |\n|---|---|\n| `broker_guide({ topic? })`, or read `broker://guide/{topic}` | six Markdown pages (`index`, `publish-provider`, `connect-client`, `host-config`, `deploy`, `troubleshooting`) with **this** broker's effective configuration injected into each |\n| `broker_diagnose({ slot? })` | live state plus the problems the broker can prove, each with `symptom`, `evidence` and a `fix` |\n\nPoint any MCP client at `http://localhost:3000/_broker/mcp` and call them. From\na stdio host bridged to `_all` they are named `_broker-broker_guide` and\n`_broker-broker_diagnose`. When something does not work, call `broker_diagnose`\nbefore reading anything: it does the correlation for you and names the fix.\n\n### The one rule that costs the most time\n\nA provider's transport and its URL path are a matched pair:\n\n```\n  DirectTransport      <->  ws://<host>/provider/<name>   plain JSON-RPC frames\n  MultiplexTransport   <->  ws://<host>/providers         envelopes { provider, payload }\n```\n\n`ws://<host>/providers/<name>` is **neither**. The router matches `/providers`\nexactly and `/provider/` as a prefix, so a URL starting with `/providers/` falls\nthrough to the client branch and is accepted as an MCP *client* on a slot named\n`providers/<name>`. Nothing errors; your slot stays empty.\n\nBoth mismatches are detected on the first frame and refused with WebSocket close\ncode `1008` and a reason naming the correction. Older brokers stay silent, so\nthe observable signatures are worth knowing:\n\n- **MultiplexTransport on `/provider/<name>`**: `provider_status` reports\n  `connected: true`, `transport: \"ws\"`, `pendingCount` climbing and never\n  falling, while the client's `initialize` never resolves.\n- **DirectTransport on `/providers`**: your socket is open and the slot never\n  appears in `providers_list` at all.\n\n`broker_diagnose` reports the first as `transport-path-mismatch`.\n\n> **Testing?** `startTestBroker()` from `@cyanmycelium/mcp-broker/testing` runs a\n> real broker in one call, with callers that need no authorization server. See\n> [docs/testing.md](docs/testing.md).\n\n## Configuration\n\nTwo sources, env vars **always win** over the file. The file is the static baseline you ship with the broker; env vars are deploy-specific overrides.\n\n### Option A: `.mcp-broker/` folder (recommended)\n\nDrop a `.mcp-broker/` folder next to where you launch the broker. Paths\ninside `config.json` are resolved against this folder, so it stays\nself-contained (certs, www, grammar overrides all next to the config).\n\n```\nyour-project/\n└── .mcp-broker/\n    ├── config.json       ← broker configuration\n    ├── certs/            ← TLS material (optional)\n    ├── grammars/         ← local grammar overrides (optional)\n    └── www/              ← static dev harness (optional)\n```\n\nMinimal `config.json`:\n\n```json\n{\n    \"port\": 3001,\n    \"locale\": \"fr\",\n    \"allowedOrigins\": [\"http://localhost:3001\"],\n    \"www\": {\n        \"open\":   false,\n        \"mounts\": [{ \"urlPrefix\": \"/\", \"dir\": \"www\" }]\n    },\n    \"stdioUpstreams\": [\n        {\n            \"name\": \"fs\",\n            \"command\": \"npx\",\n            \"args\":   [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/data\"],\n            \"aggregate\": true\n        }\n    ],\n    \"mcpServers\": [\n        { \"name\": \"geo\", \"url\": \"https://geo.example.com/mcp\" }\n    ]\n}\n```\n\nThree ways to give the broker a provider without writing any code:\n`stdioUpstreams[]` spawns a child process, `mcpServers[]` dials out to a remote\nMCP server by URL, and `mcpbBundles[]` verifies and runs a signed `.mcpb`\nbundle. Note that `stdioUpstreams` entries are **not** in `_all` unless you\nwrite `\"aggregate\": true`, while the other two are in unless you write\n`\"aggregate\": false`.\n\nStart from the [`.mcp-broker.example/`](.mcp-broker.example/) template, which\nships with authorization off and every key annotated:\n\n```sh\ncp -r node_modules/@cyanmycelium/mcp-broker/.mcp-broker.example .mcp-broker\n```\n\nFull reference (every field, defaults, recipes, grammar overrides): **[docs/config.md](https://github.com/pandaGaume/mcp-broker/blob/main/node/packages/broker/docs/config.md)**.\n\n### Option B: Environment variables\n\nThis table is complete: it lists every `MCP_BROKER_*` variable the CLI reads.\n\n| Variable | Default | Notes |\n|---|---|---|\n| `MCP_BROKER_CONFIG` | `./.mcp-broker/config.json` | Path to a JSON config file (see above) |\n| `MCP_BROKER_PORT` | `3000` | TCP port to listen on |\n| `MCP_BROKER_HOST` | `0.0.0.0` | Interface to bind |\n| `MCP_BROKER_LOCALE` | `en` | BCP-47 tag driving the `_broker` tool descriptions |\n| `MCP_BROKER_ALLOWED_ORIGINS` | (unset) | Comma-separated browser origins allowed on the client endpoints. **Unset means no browser origin passes.** See below |\n| `MCP_BROKER_PROVIDER_PATH` | `/provider` | Prefix for dedicated provider WS connections (`DirectTransport`, plain frames) |\n| `MCP_BROKER_PROVIDERS_PATH` | `/providers` | Exact path for multiplexed provider WS connections (`MultiplexTransport`, envelopes) |\n| `MCP_BROKER_CLIENT_PATH` | `/` | Prefix for raw WS clients |\n| `MCP_BROKER_MCP_PATH` | `/mcp` | Per-slot suffix for Streamable HTTP |\n| `MCP_BROKER_SSE_PATH` | `/sse` | Per-slot suffix for the legacy SSE stream |\n| `MCP_BROKER_MESSAGES_PATH` | `/messages` | Per-slot suffix for legacy SSE posts |\n| `MCP_BROKER_PROVIDER_HEARTBEAT_MS` | `30000` | ws-level ping interval on provider sockets. `0` disables |\n| `MCP_BROKER_PROVIDER_REQUEST_TIMEOUT_MS` | `60000` | How long a provider has to answer one request before it is failed. `0` disables |\n| `MCP_BROKER_PROVIDER_TAKEOVER` | `liveness` | `reject`, `liveness` or `always` when a second provider claims an occupied slot |\n| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | (unset) | Standard OpenTelemetry full traces endpoint. Enables provider telemetry export |\n| `OTEL_EXPORTER_OTLP_HEADERS` | (unset) | Standard comma-separated, percent-encoded OTLP headers |\n| `MCP_BROKER_WWW_DIR` | (unset) | If set, serve this directory at `/` |\n| `MCP_BROKER_BUNDLE_DIR` | (unset) | If set, serve this directory at `/bundle` |\n| `MCP_BROKER_OPEN` | (unset) | `1` opens the broker root on startup; a `/path` or a same-origin absolute URL opens that page. Opens only when a static mount actually covers the resolved path |\n| `MCP_BROKER_TLS_CERT` | (unset) | Path to a PEM certificate. Enables HTTPS/WSS |\n| `MCP_BROKER_TLS_KEY` | (unset) | Path to a PEM private key. Enables HTTPS/WSS |\n| `MCP_BROKER_PROTOCOL` | auto | `http` forces plain, `https` forces TLS, unset auto-detects from cert+key |\n| `MCP_BROKER_STDIO_PROVIDER` | (unset) | When set, bridge stdin/stdout JSON-RPC to this slot. **Use `_all`**, see [Claude Desktop integration](#claude-desktop-integration) |\n| `MCP_BROKER_AUTH_ENABLED` | (unset) | `1` to turn on the OAuth 2.1 resource server (requires the three below) |\n| `MCP_BROKER_PUBLIC_BASE_URL` | (unset) | Public origin used to build canonical resource URIs, e.g. `https://mcp.example.com` |\n| `MCP_BROKER_JWKS` | (unset) | Authorization server's JWKS URL, used to verify token signatures |\n| `MCP_BROKER_ISSUER` | (unset) | Expected token issuer (defaults to the sole authorization server) |\n| `MCP_BROKER_PROVIDER_SECRET` | (unset) | Shared secret every provider must present to occupy a slot. **Not gated by `auth.enabled`**: setting it alone turns provider authentication on |\n\n`mcp-broker --help` prints the same list against the running build.\n\n### Browser origins\n\nClient endpoints (`/<slot>/mcp`, `/<slot>/sse`, `/<slot>/messages`) refuse any\nrequest carrying an `Origin` header that is not allowed, with `403` and an\n`invalid_origin` body. **The allow list is empty by default**, so out of the box\nno browser origin passes while every non-browser client, which sends no\n`Origin`, passes unchanged. This is the DNS-rebinding protection the MCP\nspecification asks for.\n\n**A static mount does not exempt the origin it serves.** A page the broker\nitself serves at `http://localhost:3000/` is still a browser origin and must be\nlisted:\n\n```sh\nMCP_BROKER_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173\n```\n\nMatch the scheme, host and port exactly as the browser sends them. If the broker\nruns with TLS, the origin is `https://`, not `http://`.\n\nScope, precisely: the check covers the three **HTTP** client endpoints. A raw\nWebSocket upgrade (`ws://<host>/<slot>`) and both provider endpoints are not\norigin-checked, so `allowedOrigins` is not a substitute for authentication.\n\nFull reference, including the regular-expression form and the\n`withAllowedOrigins` predicate, in [docs/config.md](https://github.com/pandaGaume/mcp-broker/blob/main/node/packages/broker/docs/config.md#allowedorigins).\n\n## Reserved slots: `_broker` and `_all`\n\nTwo slot names are reserved. A provider that tries to claim either is refused\nwith `Provider \"<name>\" is reserved by the broker`.\n\n### `_broker`, introspection\n\nThe broker registers **itself** as a provider under `_broker`, over an\nin-process loopback transport. Reach it through any client transport, e.g.\n`http://localhost:3000/_broker/mcp`. It proxies nothing: it is not a route to\nother slots.\n\n| tool | arguments | returns |\n|---|---|---|\n| `broker_info` | none | `{ name, version, uptimeSeconds, host, port, tls, paths }` |\n| `providers_list` | none | every slot known to the broker, connected or not |\n| `provider_status` | `{ name }` | one slot in detail |\n| `broker_guide` | `{ topic? }` | one of the six guide pages; no argument returns the index |\n| `broker_diagnose` | `{ slot? }` | live state plus proven problems, each with `symptom`, `evidence`, `fix` |\n\nMatching resources for clients that prefer `resources/read`: `broker://info`,\n`broker://providers`, the template `broker://providers/{name}`, the six\n`broker://guide/<topic>` pages and the template `broker://guide/{topic}`.\n\n**Watch slots instead of polling.** `broker://providers` and\n`broker://providers/<name>` accept `resources/subscribe`. A slot appearing, a\nprovider attaching or detaching, a slot joining or leaving `_all` each send\n`notifications/resources/updated`; the counters never do, since reading moves\nthem. Reads are always live.\n\n```jsonc\n// -> {\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"resources/subscribe\",\"params\":{\"uri\":\"broker://providers\"}}\n// <- {\"jsonrpc\":\"2.0\",\"id\":2,\"result\":{}}\n// ...a provider connects:\n// <- {\"jsonrpc\":\"2.0\",\"method\":\"notifications/resources/updated\",\"params\":{\"uri\":\"broker://providers\"}}\n```\n\nEach provider entry from `providers_list` / `provider_status`:\n\n```json\n{\n    \"name\": \"weather\",\n    \"transport\": \"ws\",\n    \"connected\": true,\n    \"aggregate\": true,\n    \"connectedSince\": \"2026-09-14T08:12:03.417Z\",\n    \"connectedForMs\": 184211,\n    \"clientCount\": 0,\n    \"sessionCount\": 1,\n    \"pendingCount\": 0,\n    \"resourceSubscriptionCount\": 0\n}\n```\n\n- The first six fields are about the **provider**: whether something serves\n  the slot, over what, whether it is in `_all`, and since when. A\n  `connectedSince` that is always a few seconds old is a provider that keeps\n  reconnecting.\n- The three counts are about the slot's **callers**. A connected provider that\n  nobody is calling right now reads `clientCount: 0, sessionCount: 0,\n  pendingCount: 0`; that is not a fault.\n- `transport` is `ws` (dedicated socket), `ws-multiplex` (shared socket),\n  `stdio` (**any** configured upstream: a child process from `stdioUpstreams`,\n  a `.mcpb` bundle, *or* a remote URL from `mcpServers`), `loopback`\n  (in-process), or `none` (the slot exists but nothing is serving it).\n- `clientCount` counts **raw WebSocket clients only**. A perfectly healthy\n  Streamable HTTP client reads as `clientCount: 0, sessionCount: 1`.\n- `pendingCount` is the number of in-flight requests. One that only grows is the\n  signature of a provider that is connected and not answering.\n- `resourceSubscriptionCount` is the client/URI pairs held by\n  `resources/subscribe`. One that only grows is HTTP clients leaving without\n  `DELETE`.\n\n### `_all`, the aggregate\n\n`_all` presents the union of the tools and prompts of every **opted-in**\nprovider as one MCP server. It is not a proxy and not automatic.\n\nMembership, per provider kind:\n\n| provider kind | joins `_all` when |\n|---|---|\n| WebSocket, `DirectTransport` | `new DirectTransport(url, { aggregate: true })` |\n| WebSocket, `MultiplexTransport` | `MultiplexTransport.create(name, url, { aggregate: true })` |\n| `stdioUpstreams[]` | `\"aggregate\": true` (**omitted means NOT aggregated**) |\n| `mcpServers[]` | by default; `\"aggregate\": false` opts out |\n| `mcpbBundles[]` | by default; `\"aggregate\": false` opts out |\n| `_broker` | always, automatically |\n\nThat default asymmetry between `stdioUpstreams` and the other two is real and it\nis worth re-reading before assuming a slot is in.\n\nNames are prefixed with the origin slot, `<slot>-<original>`, and descriptions\nare tagged `[<slot>] <original description>`.\n\n> **Never reconstruct a prefixed name.** It is capped at 64 characters, an\n> overlong one is truncated and given a hash suffix, and a collision between two\n> providers is broken with a `-2`, `-3` suffix. The mapping back to\n> `(provider, original)` is a lookup table, not a parse. Call `tools/list` on\n> `_all` and pass the returned string back verbatim in `tools/call`.\n\n`_all` implements `initialize`, `ping`, `tools/list`, `tools/call`,\n`prompts/list` and `prompts/get`. **Everything else returns `-32601 Method not\nfound`, including `resources/list` and `resources/read`.** For a provider's\nresources, connect to that provider's own slot.\n\nIt emits `notifications/tools/list_changed` and\n`notifications/prompts/list_changed` when a provider joins, leaves or changes\nits catalog, so a subscribing client sees a provider that arrives mid-session\nwithout reconnecting. That is what makes `_all` the correct stdio-bridge target.\n\nRegistration snippets must **install the MCP message handler before announcing\nthe slot**. The broker sends `initialize` the moment it accepts an aggregate\nregistration; a provider not listening yet fails that handshake, is dropped from\n`_all` and logged, with no retry. The SDK's `aggregate` option already does this\nin the right order.\n\nWhen authorization is enabled, `_all` **filters the catalog** rather than\nrejecting the call: a caller sees only the providers it is scoped for, and a\ntool it may not see answers `-32602 Unknown aggregated tool`, deliberately\nindistinguishable from a name that does not exist.\n\n## Resource subscriptions\n\n`resources/subscribe` works on every slot except `_all`, over every client\ntransport. The broker owns the reference count between clients and provider:\n\n- N clients on one URI cost the provider **one** `resources/subscribe`; the last\n  one leaving sends **one** `resources/unsubscribe`. Concurrent requests are\n  serialized per URI.\n- `notifications/resources/updated` reaches only the sessions subscribed to that\n  exact `params.uri`. One without a usable `uri` is dropped and logged, never\n  broadcast. Every other notification is still broadcast to the slot.\n- Closing a WebSocket or an SSE stream, `DELETE /<slot>/mcp`, closing stdio,\n  closing an in-process client from `openInternalClient()`, and stopping the\n  broker all release what the client held.\n- When a provider reconnects, the broker replays the last client `initialize`,\n  then one subscribe per URI still held, then sends each subscriber one\n  `updated` so it re-reads. Install the provider's message handler before its\n  socket opens.\n- `resources/subscribe` needs `mcp.resources.read` on the slot\n  (`broker.providers.read` on `_broker`); each update is re-checked per\n  recipient, and one that lost the grant is unsubscribed. `resources/unsubscribe`\n  is never refused.\n- Limits: `resourceSubscriptions` in `config.json` (see\n  [config.md](docs/config.md#resourcesubscriptions)), or\n  `withResourceSubscriptionLimits()` on the builder.\n\nA provider built on `@cyanmycelium/mcp-core` 1.3.0 or later answers\n`resources/subscribe` itself; its behaviors only report changes:\n\n```ts\nclass GaugeAdapter extends McpAdapterBase {\n    set(value: number): void {\n        this._value = value;\n        this._forwardResourceContentChanged(\"plant://gauge\"); // -> notifications/resources/updated, subscribers only\n    }\n}\n```\n\n## Provider telemetry and OTLP\n\nThe complete protocol and deployment contract is in\n[docs/telemetry.md](https://github.com/pandaGaume/mcp-broker/blob/main/docs/telemetry.md).\n\nThe optional telemetry extension accepts `broker/telemetry` from any\nprovider slot. The broker consumes these notifications itself. It never sends\nthem to MCP clients, and it never waits for the exporter while routing requests\nor responses.\n\nThe pipeline has explicit bounds. By default it accepts frames up to 64 KiB,\nqueues at most 256 spans, exports batches of up to 32, and drops new telemetry\nwhen the queue is full. `getTelemetryStats()` reports every accepted, exported,\nand dropped span. A trace failure therefore cannot block MCP control traffic.\n\nFor the CLI, set the standard OpenTelemetry environment variable:\n\n```sh\nOTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://otel-collector:4318/v1/traces mcp-broker\n```\n\n`OTEL_EXPORTER_OTLP_HEADERS` carries optional comma-separated, percent-encoded\nheaders. The same settings can be kept in `config.json` under `telemetry`:\n\n```json\n{\n    \"telemetry\": {\n        \"otlpHttpEndpoint\": \"http://otel-collector:4318/v1/traces\",\n        \"timeoutMs\": 5000,\n        \"queueCapacity\": 256,\n        \"batchSize\": 32\n    }\n}\n```\n\nConfigure the built-in dependency-free OTLP/HTTP JSON exporter:\n\n```ts\nimport { WsTunnelBuilder } from \"@cyanmycelium/mcp-broker\";\n\nconst broker = new WsTunnelBuilder()\n    .withPort(3000)\n    .withOtlpHttpTelemetry(\n        {\n            endpoint: \"http://otel-collector:4318/v1/traces\",\n            headers: { Authorization: `Bearer ${process.env.OTLP_TOKEN}` },\n        },\n        {\n            queueCapacity: 512,\n            batchSize: 32,\n            onExportError: (error) => console.error(\"telemetry export failed\", error),\n        }\n    )\n    .build();\n```\n\nOr pass any sink with `withTelemetry({ exporter })`. This is useful for a file,\nKafka, an existing OpenTelemetry SDK, or a deterministic test collector.\n\nProvider wire format:\n\n```json\n{\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"broker/telemetry\",\n    \"params\": {\n        \"version\": 1,\n        \"signal\": \"traces\",\n        \"span\": {\n            \"traceId\": \"0123456789abcdef0123456789abcdef\",\n            \"spanId\": \"0123456789abcdef\",\n            \"parentSpanId\": \"fedcba9876543210\",\n            \"name\": \"modbus.read\",\n            \"kind\": 3,\n            \"startTimeUnixNano\": \"1720000000000000000\",\n            \"endTimeUnixNano\": \"1720000000001000000\",\n            \"attributes\": {\n                \"modbus.function_code\": 3,\n                \"network.transport\": \"tcp\"\n            },\n            \"events\": [\n                {\n                    \"name\": \"pdu.rx\",\n                    \"timeUnixNano\": \"1720000000000900000\",\n                    \"attributes\": { \"bytes\": 9 }\n                }\n            ],\n            \"status\": { \"code\": 1 }\n        }\n    }\n}\n```\n\nTrace IDs and parent relationships follow W3C Trace Context representation.\nEvery routed request carries the context in `params._meta.traceparent`.\nTypeScript providers can continue it with `traceparentOf()`,\n`childTraceparent()` and `withTraceparent()`, then emit with\n`transport.broker.span(span)`. The exporter produces an OTLP\n`ExportTraceServiceRequest`. `service.name` is the authenticated provider\nprincipal when available, otherwise the slot. `mcp.provider.slot` always keeps\nthe slot, and `mcp.provider.principal` records the authenticated identity. Raw\nprotocol payloads are not required by the schema. A provider should emit them\nonly when its own runtime trace policy explicitly enables that level of detail.\n\n## Authorization (OAuth 2.1)\n\nBy default the broker performs **no** authentication. That is fine behind a\ntrusted network boundary, but do not expose it publicly as-is. Turn on the OAuth 2.1\nresource server to require a bearer token on every client request, authenticate\nproviders, and filter the `_all` aggregate per caller.\n\nEnabled via the `auth` config block (or env vars). Minimal `.mcp-broker/config.json`:\n\nThe resource paths below use a compact ISA-95 / IEC 62264-aligned industrial\nprofile. The engine remains domain-neutral, does not claim full ISA-95\ncompliance, and can map UMD-style namespaces through `slotResources`.\n\n```json\n{\n    \"auth\": {\n        \"enabled\": true,\n        \"publicBaseUrl\": \"https://mcp.example.com\",\n        \"authorizationServers\": [\"https://auth.example.com\"],\n        \"jwks\": \"https://auth.example.com/.well-known/jwks.json\",\n        \"requiredScopes\": [\"mcp:call\"],\n        \"perSlotScopes\": { \"_broker\": [\"broker:admin\"] },\n        \"subjectMapping\": {\n            \"userClaim\": \"sub\",\n            \"groupClaims\": [\"groups\"],\n            \"clientClaim\": \"client_id\"\n        },\n        \"roles\": {\n            \"viewer\": {\n                \"capabilities\": [\"mcp.tools.list\", \"mcp.resources.read\"]\n            },\n            \"maintenance\": {\n                \"inherits\": [\"viewer\"],\n                \"capabilities\": [\"mcp.tools.diagnose\"]\n            }\n        },\n        \"assignments\": [\n            {\n                \"subject\": \"group:maintenance-site-a\",\n                \"role\": \"maintenance\",\n                \"resource\": \"/enterprise/site-a/**\"\n            }\n        ],\n        \"slotResources\": {\n            \"motor-7\": \"/enterprise/site-a/area-a/line-3/cell-2/motor-7\"\n        },\n        \"toolCapabilities\": {\n            \"diagnose_motor\": \"mcp.tools.diagnose\"\n        },\n        \"providerSecret\": \"change-me\"\n    }\n}\n```\n\nWith this on:\n\n- `POST /<slot>/mcp` (and `/sse`, `/messages`, `ws://…/<slot>`) require\n  `Authorization: Bearer <token>`; the token's audience must be\n  `https://mcp.example.com/<slot>/mcp`.\n- Clients discover the authorization server via\n  `GET /.well-known/oauth-protected-resource/<slot>/mcp` (RFC 9728), advertised\n  in the `401` challenge.\n- Providers must present `providerSecret` (via `X-Provider-Token` or\n  `Authorization: Bearer`) to connect to `/provider/<slot>` or `/providers`.\n- `_all` only shows providers allowed by the caller's hierarchical policy.\n- Explicit denies override inherited role grants.\n- Structured provider principals can publish only inside their allowed resource\n  namespace.\n\nTwo things this does **not** do. It does not authenticate the stdio bridge:\n`MCP_BROKER_STDIO_PROVIDER` reaches `_all` with no principal attached, so\nenabling per-provider scopes silently empties an MCP host's tool list. And it\ncannot authenticate a browser-hosted provider: the secret is read from the\n`X-Provider-Token` header or from `Authorization: Bearer`, and the browser\n`WebSocket` constructor cannot set headers, so setting `providerSecret` locks\nevery browser provider out permanently with an HTTP 401 that reaches the page as\na bare `error` event. Run without a provider secret, or terminate provider auth\nin a reverse proxy that injects the header.\n\nFull model, flows, scopes, and endpoints:\n**[docs/authorization.md](https://github.com/pandaGaume/mcp-broker/blob/main/docs/authorization.md)**.\nRoles, resource paths, denies, and migration:\n**[docs/hierarchical-authorization.md](https://github.com/pandaGaume/mcp-broker/blob/main/docs/hierarchical-authorization.md)**.\nConfig field reference: **[docs/config.md](https://github.com/pandaGaume/mcp-broker/blob/main/node/packages/broker/docs/config.md#auth-oauth-21-authorization)**.\n(The first two live in the repository and are not shipped in the npm package.)\n\n## Programmatic API\n\n```ts\nimport { WsTunnelBuilder } from \"@cyanmycelium/mcp-broker\";\n\nconst broker = new WsTunnelBuilder()\n    .withPort(3000)\n    .withHost(\"0.0.0.0\")\n    .withProviderPath(\"/provider\")\n    .withMcpPath(\"/mcp\")\n    // Required before any browser page can reach a client endpoint.\n    .withAllowedOrigins([\"http://localhost:5173\"])\n    // Optional: bridge a local stdio MCP server as a provider. One object, not positional args.\n    .withStdioUpstream({ name: \"my-server\", command: \"node\", args: [\"./my-server.js\"], aggregate: true })\n    // Optional: front a remote MCP server reached by URL.\n    .withRemoteUpstream({ name: \"geo\", url: \"https://geo.example.com/mcp\" })\n    // Optional: serve a dev harness at /\n    .withStaticMount(\"/\", \"/abs/path/to/www\")\n    // Optional: enable the OAuth 2.1 resource server + provider auth\n    .withJwtAuth({\n        publicBaseUrl: \"https://mcp.example.com\",\n        authorizationServers: [\"https://auth.example.com\"],\n        jwksUri: \"https://auth.example.com/.well-known/jwks.json\",\n        requiredScopes: [\"mcp:call\"],\n        roles: {\n            viewer: { capabilities: [\"mcp.tools.list\"] },\n        },\n        assignments: [\n            {\n                subject: \"group:operators\",\n                role: \"viewer\",\n                resource: \"/enterprise/site-a/**\",\n            },\n        ],\n        subjectMapping: { groupClaims: [\"groups\"] },\n    })\n    .withProviderSecret(process.env.PROVIDER_SECRET!)\n    .build();\n\nawait broker.start();\n```\n\n`start()` **rejects** on a listen failure, with a message naming the port and\nwhat to do about it. Await it, or handle the rejection: `void broker.start()`\nproduces an unhandled rejection.\n\nAn MCP server living in the same process needs no WebSocket at all:\n\n```ts\nimport { LoopbackTransport, McpServerBuilder } from \"@cyanmycelium/mcp-core\";\n\nconst [serverEnd, clientEnd] = LoopbackTransport.createPair();\nconst server = new McpServerBuilder().withTransport(serverEnd).register(/* behaviors */).build();\nawait server.start();\nbroker.registerLoopbackProvider(\"in-process\", clientEnd);\n```\n\nA loopback slot outranks a WebSocket provider of the same name: the WebSocket\none is refused with `Provider \"<name>\" is reserved by the broker`.\n\nProvider liveness has three knobs, all also settable from the config file and\nfrom `MCP_BROKER_*`:\n\n| method | default | what it addresses |\n|---|---|---|\n| `withProviderHeartbeat(ms)` | `30000` | a half-open socket holding a slot until TCP keepalive expires, hours later. `0` disables |\n| `withProviderTakeover(mode)` | `\"liveness\"` | `\"reject\"` keeps the incumbent always; `\"always\"` needs provider auth and a matching principal, and degrades to `\"liveness\"` with a log otherwise |\n| `withProviderRequestTimeout(ms)` | `60000` | a provider that stays connected and never answers, the ordinary state of a throttled background browser tab. `0` disables |\n\nA pong is answered by the peer's network stack, so the heartbeat proves the\n*process* is alive, not that it is serving. `withProviderRequestTimeout` is what\ncovers the second case.\n\nAll builder methods are documented inline. The full options interface is\n`IWsTunnelOptions`, also exported. Use `withAuthorizationPolicy` for a\nstandalone policy configuration, `withPolicyEngine` for a custom engine, and\n`withSlotResourceResolver` for a custom namespace mapping. For a custom token\nvalidator (for example RFC 7662 introspection) or provider authenticator, use\n`withAuth(resolvedAuth)` or `withProviderAuth(authenticator)` with your own\n`ITokenValidator` or `IProviderAuthenticator`.\n\n`brokerName` is honored by `IWsTunnelOptions` but there is no\n`withBrokerName()`, so the CLI cannot forward the config-file key. Set it\nthrough `IWsTunnelOptions` directly if you need it.\n\n## Runnable samples\n\nFive self-contained integration samples live in the repository, outside this\npackage: [samples/](https://github.com/pandaGaume/mcp-broker/tree/main/samples).\nEach starts what it needs and proves itself end to end, and\n[samples/index.json](https://github.com/pandaGaume/mcp-broker/blob/main/samples/index.json)\nindexes them for an agent. They are not in this package's `files`, so they are\non GitHub rather than in `node_modules`.\n\nEverything below *does* ship inside the npm package under `web/`, so it is\navailable from `node_modules/@cyanmycelium/mcp-broker/web`.\n\n| path | what it shows |\n|---|---|\n| [`web/demos/provider-tunnel/`](web/demos/provider-tunnel/) | a browser page hosting an MCP server and tunnelling it into a slot |\n| [`web/demos/broker-explorer/`](web/demos/broker-explorer/) | a browser MCP **client** driving `_broker`, `_all` or any slot |\n| [`web/demos/oauth-lab/`](web/demos/oauth-lab/) | a complete local OAuth 2.1 and policy environment |\n| [`.mcp-broker.example/`](.mcp-broker.example/) | a config template with per-key guides in [English](.mcp-broker.example/CONFIGURATION-EN.md) and [French](.mcp-broker.example/CONFIGURATION-FR.md), plus `config.stdio-bridge.json` |\n\nServe the whole `web/` folder from an installed package in one command:\n\n```sh\nMCP_BROKER_WWW_DIR=node_modules/@cyanmycelium/mcp-broker/web \\\nMCP_BROKER_ALLOWED_ORIGINS=http://localhost:3000 \\\nMCP_BROKER_OPEN=1 \\\nnpx @cyanmycelium/mcp-broker\n```\n\n`MCP_BROKER_ALLOWED_ORIGINS` is there because a page that reaches a slot over\n**HTTP** (`/<slot>/mcp`, `/<slot>/sse`, `/<slot>/messages`) is origin-checked,\nand the broker serving the page does not exempt it. A page that uses only\nWebSocket transports does not need it: WebSocket upgrades carry no origin check\nat all, which is worth knowing in both directions.\n\n## Interactive OAuth demo\n\nThe bundled [OAuth Policy Lab](web/demos/oauth-lab/) runs a complete local\nAuthorization Code and PKCE flow with signed JWTs, JWKS validation,\naudience-bound tokens, hierarchical policies, explicit denies, and a live\naudit:\n\n```sh\nnpm run demo:oauth\n```\n\nThe page opens at `http://127.0.0.1:3001/demos/oauth-lab/`. See the\n[demo README](web/demos/oauth-lab/README.md) for its identities, policy matrix,\nand automated smoke test.\n\n## TLS for local development\n\n`gen-cert` is a repository script, not part of the published package: it needs\n`selfsigned`, which is a devDependency. From a checkout of this repo, in\n`node/packages/broker`:\n\n```sh\nnpm run gen-cert -- --out .mcp-broker/certs\n# Writes .mcp-broker/certs/cert.pem and .mcp-broker/certs/key.pem\n\nMCP_BROKER_TLS_CERT=.mcp-broker/certs/cert.pem \\\nMCP_BROKER_TLS_KEY=.mcp-broker/certs/key.pem \\\nnpm start\n```\n\nWithout `--out` the script writes to `../certs` resolved against the working\ndirectory, which for an npm script is the package directory. Pass `--out`\nwhenever you care where the files land.\n\nOutside this repository, `openssl` does the same job:\n\n```sh\nmkdir -p .mcp-broker/certs && openssl req -x509 -newkey rsa:2048 -nodes -days 365 \\\n  -keyout .mcp-broker/certs/key.pem -out .mcp-broker/certs/cert.pem \\\n  -subj \"/CN=localhost\" -addext \"subjectAltName=DNS:localhost,IP:127.0.0.1\"\n```\n\nSetting both a certificate and a key switches the **whole** server to HTTPS and\nWSS at once. There is no mixed mode: providers then connect with `wss://`,\nclients with `https://`, and every entry in `allowedOrigins` must be spelled\n`https://` or it will match nothing. The files are read synchronously when the\ntunnel is built, so a wrong path fails before the port is bound.\n\nThe generated certificate covers `localhost`, `127.0.0.1`, `::1` for 365 days. Browsers will warn about an untrusted issuer on first visit. Click \"Advanced → Proceed\". MCP clients (Claude, Inspector) ignore certificate validation by default.\n\n## Docker\n\nA multi-stage `Dockerfile` ships with the package: build stage compiles TypeScript and copies grammar JSON, runtime stage carries only the compiled `dist/`, production `node_modules`, and runs as a non-root user.\n\n```sh\n# From the node/ directory\ndocker build -t cyanmycelium/mcp-broker:0.1.0 .\n\n# Run on host port 3000\ndocker run --rm -p 3000:3000 cyanmycelium/mcp-broker:0.1.0\n\n# With a custom locale and host port\ndocker run --rm -p 4000:4000 \\\n    -e MCP_BROKER_PORT=4000 \\\n    -e MCP_BROKER_LOCALE=fr-CA \\\n    cyanmycelium/mcp-broker:0.1.0\n```\n\n### Mounting TLS material\n\n```sh\n# Generate localhost certs on the host first\nnpm run gen-cert  # writes ../certs/cert.pem and ../certs/key.pem\n\ndocker run --rm -p 3000:3000 \\\n    -v \"$(pwd)/../certs:/certs:ro\" \\\n    -e MCP_BROKER_TLS_CERT=/certs/cert.pem \\\n    -e MCP_BROKER_TLS_KEY=/certs/key.pem \\\n    cyanmycelium/mcp-broker:0.1.0\n```\n\n### Mounting a static dev harness\n\n```sh\ndocker run --rm -p 3000:3000 \\\n    -v \"$(pwd)/public:/www:ro\" \\\n    -e MCP_BROKER_WWW_DIR=/www \\\n    cyanmycelium/mcp-broker:0.1.0\n```\n\n### Health check\n\nThe image declares a `HEALTHCHECK` that opens a TCP socket on `MCP_BROKER_PORT`. Orchestrators (Docker Compose, Kubernetes liveness probe) pick it up automatically.\n\n### docker-compose snippet\n\n```yaml\nservices:\n  broker:\n    build: .\n    # Or pull a published image once available:\n    # image: ghcr.io/pandagaume/mcp-broker:0.1.0\n    ports:\n      - \"3000:3000\"\n    environment:\n      MCP_BROKER_PORT: \"3000\"\n      MCP_BROKER_LOCALE: \"en\"\n    restart: unless-stopped\n```\n\n## Claude Desktop integration\n\nThe broker can act as a stdio MCP server for Claude Desktop and any other stdio\nMCP host. **Point the bridge at `_all`, not at one of your slots:**\n\n```json\n{\n  \"mcpServers\": {\n    \"mcp-broker\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@cyanmycelium/mcp-broker\"],\n      \"env\": {\n        \"MCP_BROKER_STDIO_PROVIDER\": \"_all\",\n        \"MCP_BROKER_PORT\": \"3000\",\n        \"MCP_BROKER_HOST\": \"127.0.0.1\"\n      }\n    }\n  }\n}\n```\n\n### Why `_all` and not your slot\n\nThis is an ordering problem, and pinning a real slot fails every single time.\n\nAn MCP host starts its servers when the host application launches. It sends\n`initialize` immediately and treats a failure as a dead server: no retry, no\nbackoff, the entry is disabled for the session. Your provider does not exist\nyet. A browser provider needs a human to open a page; a provider in another\nprocess needs that process to start. So the bridge answers the host's very first\n`initialize` with `-32000 Provider \"<slot>\" not connected`, and the host gives\nup. **Pinning a real slot never works for a browser-hosted provider at all.**\n\n`_all` is registered before the broker resumes stdin, so the slot exists before\nthe host's first byte arrives. It answers `initialize` itself. It already\naggregates `_broker`, so the host always has at least the five introspection\ntools. And it pushes `notifications/tools/list_changed` when a provider joins,\nso a page opened ten minutes into the session appears in the host's tool list\nlive, with no reconnect.\n\n`_broker` is the fallback if you want introspection only. It is also always up,\nbut it will never show anything except the broker's own five tools.\n\nProviders still have to **opt in** to `_all` (see\n[Reserved slots](#reserved-slots-_broker-and-_all)). If the host shows only\n`_broker-*` tools, nothing opted in; call `_broker-broker_diagnose` and it will\nsay so.\n\n### One broker per port\n\nDo not add a second host entry that spawns another broker. The second process\ncannot bind the port and dies; the host reports `Connection closed` with no\ncause, and the real `EADDRINUSE` diagnosis is only in the host's\n`mcp-server-<name>.log`. If you want two logical servers visible to the host,\npublish both into the one broker and let `_all` union them.\n\n### The bridge is anonymous\n\nThe stdio bridge forwards frames to `_all` with **no principal attached**. While\nno authorization is configured that is invisible. The moment you enable\nper-provider scopes, or any policy that denies an anonymous subject, the host's\ntool list silently empties: `tools/list` still succeeds and returns\n`tools: []`, and nothing anywhere says why.\n\nIn this mode all broker logging goes to stderr; stdout is reserved for the JSON-RPC stream the host expects.\n\n## Troubleshooting\n\nCall `broker_diagnose()` on the `_broker` slot first. It reads the live state\nand names the problems it can prove. This table is the reference behind it, and\ncovers the failures the broker cannot see from the inside.\n\n| symptom | cause | fix |\n|---|---|---|\n| Client hangs forever on `initialize`, provider shows `connected: true` | `MultiplexTransport` on `/provider/<name>` | move it to `ws://<host>/providers`, or switch it to `DirectTransport` |\n| Provider socket open, slot never appears in `providers_list` | `DirectTransport` on `/providers` | move it to `ws://<host>/provider/<name>`, or switch it to `MultiplexTransport` |\n| Provider on `/providers/<name>`, nothing works | that path is neither endpoint: it is accepted as a **client** on a slot named `providers/<name>` | drop the name for multiplex, or add `/provider/` for a dedicated socket |\n| WebSocket closes `1008 already connected` after a reload | a stale socket still holds the slot | release on `pagehide`; the heartbeat frees a genuinely dead one within one interval |\n| Host reports `Connection closed` with no cause | a second broker could not bind the port | one broker per port; `EADDRINUSE` is in `mcp-server-<name>.log` |\n| `403 invalid_origin` from a page this broker serves | a static mount does not exempt the origin it serves | list that exact origin, scheme and port included |\n| `Provider \"<slot>\" not connected` at host start | ordering: the host starts before any provider exists | point `MCP_BROKER_STDIO_PROVIDER` at `_all` |\n| `_all` shows only `_broker-*` tools | nothing opted into the aggregate | see [Reserved slots](#reserved-slots-_broker-and-_all); verify with `tools/list` on `_all` |\n| Host's tool list empties after enabling authorization | the stdio bridge is anonymous | grant the anonymous subject, or stop bridging in authorized deployments |\n| Browser provider gets a bare `error` event | provider auth is on; a browser cannot send the header | run without a provider secret, or authenticate in a proxy |\n| `-32601 Method not found` on `_all` | `_all` covers tools and prompts only | use the provider's own slot for resources |\n| `-32602 Unknown aggregated tool` | the prefixed name was reconstructed rather than echoed | re-run `tools/list`, pass the name back verbatim |\n| `did not respond within 60000ms` | the provider stayed connected and never answered | raise `providerRequestTimeoutMs`, or fix the provider |\n| `sessionCount` grows and never falls | Streamable HTTP and SSE sessions do not expire | send `DELETE /<slot>/mcp` when a client is done; restart if it is already large |\n| Subscribed, `notifications/resources/updated` never arrives | the update names another URI (exact match), carries no `params.uri` (dropped, logged once), or the read grant was revoked | compare URIs byte for byte; read the broker log |\n| `resources/subscribe` answers `-32601` on a provider slot | the provider does not implement it (mcp-core before 1.3.0 did not) | upgrade the provider |\n| `-32000 Subscription limit reached` | `maxSubscriptionsPerClient` or `maxSubscriptionsPerSlot` | unsubscribe what you no longer watch, or raise `resourceSubscriptions` |\n\nReading the console: the broker prints one line per accepted WebSocket upgrade\nnaming the path, the role the router assigned (`dedicated-provider`,\n`multiplex-provider` or `client`) and the slot. **A provider URL that came out\nas `role=client` is the mismatch, caught for free.** In stdio mode every log\ngoes to stderr, so look in the host's `mcp-server-<name>.log`, never on stdout.\nDo not read silence as success: routed frames and provider replies are not\nlogged at all, and `providers_list` plus `broker_diagnose` are the ground truth.\n\n## Development\n\n```sh\nnpm install\nnpm run build      # tsc -b\nnpm test           # vitest run\nnpm run lint\nnpm start          # node dist/bin.js\n```\n\nRequires Node 20.11+.\n\n### Running the broker of this checkout\n\n`npm start` runs `dist/bin.js`, the code of the working tree once `npm run\nbuild` has been run (from `node/`, which builds the provider package first).\nIt reads `.mcp-broker/config.json` next to `package.json` when there is one;\nthat folder is gitignored, so each checkout keeps its own. A config that makes\nthe broker reachable from a device on the LAN and serves this package's `web/`\n(the broker explorer at `/demos/broker-explorer/`) from the same port:\n\n```json\n{\n    \"port\": 3000,\n    \"host\": \"0.0.0.0\",\n    \"www\": { \"open\": false, \"mounts\": [{ \"urlPrefix\": \"/\", \"dir\": \"../web\" }] },\n    \"allowedOrigins\": [\"http://localhost:3000\", \"http://127.0.0.1:3000\"]\n}\n```\n\nPaths in the file resolve against the file's own directory, hence `../web`.\nKeep the terminal open: the process lives as long as it does. Without the\nfile the defaults apply, `0.0.0.0:3000` and no static mount. Every C sample,\nthe roundtrip and the soak in [`c/`](https://github.com/pandaGaume/mcp-broker/tree/main/c)\ntarget this broker, not an installed one.\n\n## Releasing\n\nThe package is published to npm by [`.github/workflows/release-node.yml`](https://github.com/pandaGaume/mcp-broker/blob/main/.github/workflows/release-node.yml), triggered by tags of the form `node-v*`.\n\n```sh\n# from the node/ directory:\nnpm run bump:minor           # updates the broker, commits, and creates node-v<version>\ngit push                     # pushes the release commit\ngit push origin node-v1.6.0  # pushes the tag explicitly and starts the workflow\n```\n\nThe workflow runs lint, build, test, then `npm publish --access public --provenance` and creates a GitHub Release with auto-generated notes.\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE).\n\n## Execution limits\n\nOperator-owned call quotas and provider operation budgets: [configuration, SDK and recovery](docs/execution-limits.md).\n","readmeFilename":"README.md"}