{"_id":"@antidrift/zeromcp","_rev":"6-62563e8240c1d24ed81d89f6e998abb1","name":"@antidrift/zeromcp","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@antidrift/zeromcp","version":"0.1.0","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","_id":"@antidrift/zeromcp@0.1.0","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"bin":{"mcp":"bin/mcp.js"},"dist":{"shasum":"36a7521d0734680d85e8721be0319873d6da6e0e","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.1.0.tgz","fileCount":35,"integrity":"sha512-8JaXBXw3bdSqQ2UhaQtFnQ4C8YGBQtN0ZSINP1pqUC+1vkZn01AjguRqsCzqM3+uA+0QbByKfeEmcY4RuGR75A==","signatures":[{"sig":"MEYCIQCCx40jNFcB20o38yDUeotfvXFu0wSyO9Y7DEGKMPM5owIhAPaOoAKbScb0HFI7uzpRgMd7DT9hT4ZgGnLTiStGFByp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89394},"main":"dist/server.js","type":"module","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"}},"gitHead":"d9022ef15c11fb99f3ef802f9a772f643b4cddae","scripts":{"test":"node --test test/*.test.js","build":"tsc"},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"repository":{"url":"git+https://github.com/antidrift-dev/zeromcp.git","type":"git","directory":"nodejs"},"_npmVersion":"11.12.0","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","directories":{},"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/zeromcp_0.1.0_1775513894779_0.6366273013407893","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@antidrift/zeromcp","version":"0.1.1","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","_id":"@antidrift/zeromcp@0.1.1","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"bin":{"mcp":"bin/mcp.js"},"dist":{"shasum":"d3065192191c263df264a1bec14dbcb611f788bd","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.1.1.tgz","fileCount":35,"integrity":"sha512-rbyc/NcwGloV5WwpNGkIekPsHz6sdgV+6TJtBJgXVMhAUbF0whqzH1u+vK0d8hQ+9iZyqKbnkLAQDwDehK/Udg==","signatures":[{"sig":"MEYCIQCCcudK1q03ABm09uG9vjmY+xRV8Hnu8NO8G8sGWsRMbgIhAIRcKRJpdfW5vwey072vChc4CM6smloIGwVcEC2A505+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89798},"main":"dist/server.js","type":"module","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"}},"gitHead":"372e732b67c8e921b1e90094b610b08ab2e22b61","scripts":{"test":"node --test test/*.test.js","build":"tsc"},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"repository":{"url":"git+https://github.com/antidrift-dev/zeromcp.git","type":"git","directory":"nodejs"},"_npmVersion":"11.12.0","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","directories":{},"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/zeromcp_0.1.1_1775580353128_0.7200610265705485","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@antidrift/zeromcp","version":"0.2.0","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","_id":"@antidrift/zeromcp@0.2.0","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"bin":{"mcp":"bin/mcp.js"},"dist":{"shasum":"76b7fc23a15555403504e44c52eaed6e3a2b2194","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.2.0.tgz","fileCount":51,"integrity":"sha512-hl9A+WgiRPI6anZbNbr1dAvf/dWzX1wigZXAQkcJmsR2qKTeD6wzHFW295JldNxtfmD8kKvTbV7J0DFTh6KzVA==","signatures":[{"sig":"MEUCIQCoKr/JRgiuEpVuAGgCZULA1JRkZMNNzQJufFeRAYm0mwIgO+NNoQZS5dh9Yt0iJgEXnEiwLTYrN606Q/3m8YFpWOM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@antidrift%2fzeromcp@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":128284},"main":"dist/server.js","type":"module","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"}},"gitHead":"0732626504d4e42115bce8df5aecf23800c08e63","scripts":{"test":"node --test test/*.test.js","build":"tsc"},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"repository":{"url":"git+https://github.com/antidrift-dev/zeromcp.git","type":"git","directory":"nodejs"},"_npmVersion":"10.9.7","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","directories":{},"_nodeVersion":"22.22.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/zeromcp_0.2.0_1775671573723_0.9331483915454386","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@antidrift/zeromcp","version":"0.2.1","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","_id":"@antidrift/zeromcp@0.2.1","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"bin":{"mcp":"bin/mcp.js"},"dist":{"shasum":"eb347ac9e0da4437c154c258859d68dba3cad4d7","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.2.1.tgz","fileCount":51,"integrity":"sha512-xM6/87aApdbDdnIKf17W4ot8GkK1b8JRsVOfJ08Q7c+TOC0EjYXgx8RWGOPYOqiofnz/gonKUn77/zc7Wypu/A==","signatures":[{"sig":"MEQCIDQfxR3EEhJiSusC5+Ny1muXgKjqB6BglNbHMbUyZx8eAiAeiYhdDJZIuCPvEmK8z1UKSwRDsbdZP8JCanKSg1drWQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@antidrift%2fzeromcp@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":128413},"main":"dist/server.js","type":"module","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"}},"gitHead":"b8b77a2226686100bbc0132a528379fe4f234e93","scripts":{"test":"node --test test/*.test.js","build":"tsc"},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"repository":{"url":"git+https://github.com/antidrift-dev/zeromcp.git","type":"git","directory":"nodejs"},"_npmVersion":"10.9.7","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","directories":{},"_nodeVersion":"22.22.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/zeromcp_0.2.1_1776694869134_0.06662875851816996","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@antidrift/zeromcp","version":"0.2.2","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","_id":"@antidrift/zeromcp@0.2.2","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"bin":{"mcp":"bin/mcp.js"},"dist":{"shasum":"f67ecf0040de511960ac69981622cef35ed1aad1","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.2.2.tgz","fileCount":51,"integrity":"sha512-gaP8+j9bP1jU6lgoNEJ/WcCWvlSRjFgMmwzPO3d5OlfI1owiZm0DfNW3gNLOkGcBh2EMB/RZpDLbvnR8q14JMQ==","signatures":[{"sig":"MEQCIAI2K5SvGd/TGFlONDBxX6/tg3tVKE/Zc/77jydGxiXkAiAkyRpCA+JiPy8Txcm/XYmpvDblqbnfEdIqBqsp1zi3IQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@antidrift%2fzeromcp@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":129440},"main":"dist/server.js","type":"module","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"}},"gitHead":"cda956abfd179697ed35102156f1ac4d4fd13ca2","scripts":{"test":"node --test test/*.test.js","build":"tsc"},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"repository":{"url":"git+https://github.com/antidrift-dev/zeromcp.git","type":"git","directory":"nodejs"},"_npmVersion":"10.9.7","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","directories":{},"_nodeVersion":"22.22.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/zeromcp_0.2.2_1777145358626_0.05631566072848626","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@antidrift/zeromcp","version":"0.3.0","description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","type":"module","main":"dist/server.js","types":"dist/server.d.ts","bin":{"mcp":"bin/mcp.js"},"exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js"},"./schema":{"types":"./dist/schema.d.ts","import":"./dist/schema.js"},"./scanner":{"types":"./dist/scanner.d.ts","import":"./dist/scanner.js"},"./handler":{"types":"./dist/handler.d.ts","import":"./dist/handler.js"},"./dispatch":{"types":"./dist/dispatch.d.ts","import":"./dist/dispatch.js"},"./registry":{"types":"./dist/registry.d.ts","import":"./dist/registry.js"}},"scripts":{"build":"tsc","test":"node --test test/*.test.js"},"devDependencies":{"@types/node":"^25.5.0","typescript":"^5.4.0"},"keywords":["mcp","zero-config","serverless","tools","ai-agents"],"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/antidrift-dev/zeromcp.git","directory":"nodejs"},"homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"_id":"@antidrift/zeromcp@0.3.0","gitHead":"af1d6b4b900dd8b1ffea0de2c37b7427d512e8eb","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-okY5z/SAyYilGBJ7Y4ZCQA7kIKVId5lfrucp4Toj5EF8hXOohnQT+gTb3d1OqDapbdFYoI+gbuf0IpJEXwsIJw==","shasum":"b1e15547e6ac914b175c465c59ea3751a2963bb2","tarball":"https://registry.npmjs.org/@antidrift/zeromcp/-/zeromcp-0.3.0.tgz","fileCount":59,"unpackedSize":152781,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@antidrift%2fzeromcp@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICRBctkodehpiSirD3ZcDw/pSIH2ZC+OnCc61/+6vIAAAiEAtf8yo246EpDduNlaQqqxskyYLo7PX2R1S2ar5an0X5s="}]},"_npmUser":{"name":"chriswelker","email":"chris@probeo.io"},"directories":{},"maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zeromcp_0.3.0_1786054323335_0.5019440912983135"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-06T22:18:14.687Z","modified":"2026-08-06T22:12:03.833Z","0.1.0":"2026-04-06T22:18:14.931Z","0.1.1":"2026-04-07T16:45:53.323Z","0.2.0":"2026-04-08T18:06:13.875Z","0.2.1":"2026-04-20T14:21:09.285Z","0.2.2":"2026-04-25T19:29:18.765Z","0.3.0":"2026-08-06T22:12:03.492Z"},"bugs":{"url":"https://github.com/antidrift-dev/zeromcp/issues"},"author":{"name":"Antidrift","email":"hello@probeo.io"},"license":"MIT","homepage":"https://github.com/antidrift-dev/zeromcp/tree/main/nodejs","keywords":["mcp","zero-config","serverless","tools","ai-agents"],"repository":{"type":"git","url":"git+https://github.com/antidrift-dev/zeromcp.git","directory":"nodejs"},"description":"Zero-config MCP server. Drop a JS file in a folder, it's a tool.","maintainers":[{"name":"chriswelker","email":"chris@probeo.io"}],"readme":"# ZeroMCP &mdash; Node.js\n\nDrop a `.js` file in a folder, get a sandboxed MCP server. Stdio out of the box.\n\n## Getting started\n\n```js\n// tools/hello.js — this is a complete MCP server\nexport default {\n  description: \"Say hello to someone\",\n  input: { name: 'string' },\n  execute: async ({ name }) => `Hello, ${name}!`,\n};\n```\n\n```sh\nnpm run build\nnode bin/mcp.js serve ./tools\n```\n\nThat's it. Stdio transport works immediately. No server class, no transport config, no schema library. Drop another `.js` file to add another tool. Delete a file to remove one. Hot reload picks up changes automatically.\n\n## vs. the official SDK\n\nThe official `@modelcontextprotocol/sdk` requires you to instantiate a server, configure a transport, wire them together, define zod schemas, and wrap every return in `{ content: [{ type: \"text\", text }] }`. ZeroMCP handles all of that &mdash; you just write the tool.\n\nIn benchmarks, ZeroMCP Node.js handles 14,173 requests/second over stdio versus the official SDK's 8,832 — 1.6x faster with 23% less memory. Over HTTP, ZeroMCP serves 4,539 rps at 22-26 MB versus the official SDK's 2,610 rps at 154-174 MB. The official SDK routes HTTP through a stdio proxy; ZeroMCP runs native inside your framework.\n\nThe official SDK also has **no sandbox**. ZeroMCP enforces per-tool network allowlists, credential isolation, filesystem controls, and exec prevention at runtime.\n\n## HTTP / Streamable HTTP\n\nZeroMCP exposes a `createHandler` function that works with any HTTP framework. You handle the transport, ZeroMCP handles the MCP protocol.\n\n```js\nimport { createHandler } from 'zeromcp/handler';\n\nconst handler = await createHandler('./tools');\n```\n\n**Express:**\n\n```js\nimport express from 'express';\nconst app = express();\napp.use(express.json());\napp.post('/mcp', async (req, res) => res.json(await handler(req.body)));\napp.listen(3000);\n```\n\n**Fastify:**\n\n```js\nimport Fastify from 'fastify';\nconst app = Fastify();\napp.post('/mcp', async (req) => handler(req.body));\napp.listen({ port: 3000 });\n```\n\n**Hono:**\n\n```js\nimport { Hono } from 'hono';\nimport { serve } from '@hono/node-server';\nconst app = new Hono();\napp.post('/mcp', async (c) => c.json(await handler(await c.req.json())));\nserve({ fetch: app.fetch, port: 3000 });\n```\n\n**Cloudflare Workers:**\n\n```js\nexport default {\n  async fetch(request) {\n    return Response.json(await handler(await request.json()));\n  }\n};\n```\n\n**AWS Lambda:**\n\n```js\nexport const handle = async (event) => handler(JSON.parse(event.body));\n```\n\nThe handler takes a JSON-RPC object and returns a JSON-RPC response. No opinions about HTTP framework, headers, or routing.\n\n## Requirements\n\n- Node.js 18+\n\n## Defining tools\n\nCreate a `.js` or `.mjs` file that default-exports a tool object:\n\n```js\n// tools/add.js\nexport default {\n  description: \"Add two numbers together\",\n  input: { a: 'number', b: 'number' },\n  execute: async ({ a, b }) => ({ sum: a + b }),\n};\n```\n\n### Input types\n\nShorthand strings: `'string'`, `'number'`, `'boolean'`, `'object'`, `'array'`. Expanded to JSON Schema automatically.\n\n### Returning values\n\nReturn a string or an object. ZeroMCP wraps it in the MCP content envelope for you.\n\n## Sandbox\n\nThe Node.js implementation has full runtime sandboxing.\n\n### Network allowlists\n\n```js\nexport default {\n  description: \"Fetch from our API\",\n  input: { endpoint: 'string' },\n  permissions: {\n    network: ['api.example.com', '*.internal.dev'],\n  },\n  execute: async ({ endpoint }, ctx) => {\n    const res = await ctx.fetch(`https://api.example.com/${endpoint}`);\n    return res.body;\n  },\n};\n```\n\nRequests to unlisted domains are blocked and logged.\n\n### Credential injection\n\nTools receive secrets via `ctx.credentials`, configured per namespace in `zeromcp.config.json`. Tools never read `process.env` directly.\n\n### Filesystem and exec control\n\n- `fs: 'read'` or `fs: 'write'` &mdash; unauthorized access blocked via proxy objects and static source auditing\n- `exec: true` required to spawn subprocesses &mdash; denied by default\n\n### Permission logging\n\n```\n[zeromcp] fetch_data → GET api.example.com\n[zeromcp] fetch_data ✗ GET evil.com (not in allowlist)\n```\n\n## Directory structure\n\nTools are discovered recursively. Subdirectory names become namespace prefixes. `node_modules` directories are skipped automatically.\n\n```\ntools/\n  hello.js          -> tool \"hello\"\n  math/\n    add.js          -> tool \"math_add\"\n    multiply.js     -> tool \"math_multiply\"\n```\n\n## Programmatic API\n\n```js\nimport { createHandler } from 'zeromcp/handler';   // HTTP handler\nimport { ToolScanner } from 'zeromcp/scanner';      // Tool discovery\nimport { toJsonSchema, validate } from 'zeromcp/schema'; // Schema utils\nimport { createRegistry } from 'zeromcp/registry';  // Framework-neutral tool registry (MCP + REST + OpenAPI)\n```\n\n`createRegistry` is async and takes a plain object of tools you provide (rather than scanning a directory) — `const registry = await createRegistry(tools, options)` — returning `{ routes, openapi, mcp }`: a route table for wiring into any router, a ready-to-serve OpenAPI document, and an `mcp` handler with the same signature as `createHandler`. Like `createHandler`, it accepts an `options.remote` list of remote MCP servers to federate; their tools are merged in namespaced as `servername.toolname`, with any local tool of the same name overriding the remote one.\n\n## Configuration\n\nOptional `zeromcp.config.json`:\n\n```json\n{\n  \"tools\": [\"./tools\"],\n  \"transport\": [\n    { \"type\": \"stdio\" },\n    { \"type\": \"http\", \"port\": 4242, \"auth\": \"env:TOKEN\" }\n  ],\n  \"autoload_tools\": true,\n  \"logging\": true,\n  \"bypass_permissions\": false,\n  \"credentials\": {\n    \"api\": { \"env\": \"API_KEY\" }\n  }\n}\n```\n\n## Testing\n\n```sh\nnpm test\n```\n\nNode.js passes all 10 conformance suites and survives 21/22 chaos monkey attacks.\n","readmeFilename":"README.md"}