{"_id":"@actionproxy/mcp-wrapper","name":"@actionproxy/mcp-wrapper","dist-tags":{"next":"0.1.1","latest":"0.1.1"},"versions":{"0.1.1":{"name":"@actionproxy/mcp-wrapper","version":"0.1.1","description":"MCP stdio proxy for governing tool calls with ActionProxy policy, human approval, one-time grants, and audit","keywords":["actionproxy","ai-agents","agent-security","ai-governance","approval-gateway","audit","human-in-the-loop","mcp","mcp-proxy","mcp-server","model-context-protocol","tool-calling","tool-governance"],"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/ActionProxy/actionproxy.git","directory":"packages/mcp-wrapper"},"homepage":"https://actionproxy.com/quickstart/","bugs":{"url":"https://github.com/ActionProxy/actionproxy/issues"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"engines":{"node":">=22 <25"},"type":"module","bin":{"actionproxy-mcp":"dist/index.js"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"yaml":"^2.5.1"},"devDependencies":{"@types/node":"^22.7.4","tsup":"^8.3.0","typescript":"^5.6.3","vitest":"^3.2.6"},"scripts":{"build":"tsup src/index.ts --format esm --dts --out-dir dist","test":"vitest run","lint":"tsc --noEmit"},"_id":"@actionproxy/mcp-wrapper@0.1.1","_integrity":"sha512-kainzcr4BYFWBXeBRibiq9w+4HOKTkxwEkbISs2JMXdx9wvWkudXNw2/a4k0bJp2Ce1VJZsDychY3rh/XTK9WQ==","_resolved":"/home/runner/work/actionproxy/actionproxy/npm-release-bundle/actionproxy-mcp-wrapper-0.1.1.tgz","_from":"file:/home/runner/work/actionproxy/actionproxy/npm-release-bundle/actionproxy-mcp-wrapper-0.1.1.tgz","_nodeVersion":"24.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-kainzcr4BYFWBXeBRibiq9w+4HOKTkxwEkbISs2JMXdx9wvWkudXNw2/a4k0bJp2Ce1VJZsDychY3rh/XTK9WQ==","shasum":"7211c0d44ffacb117f70ddde8547231efa1c3704","tarball":"https://registry.npmjs.org/@actionproxy/mcp-wrapper/-/mcp-wrapper-0.1.1.tgz","fileCount":5,"unpackedSize":92429,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@actionproxy%2fmcp-wrapper@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIA1itY+ucN8m7kjas0eU8yc6JbdymKUuUpwX1LzNpGYCAiAmgkruOD8F39uWRVySLEyuBImVuTlB5KTTV9RVPxAqvA=="}]},"_npmUser":{"name":"idan-actionproxy","email":"npm@actionproxy.com"},"directories":{},"maintainers":[{"name":"idan-actionproxy","email":"npm@actionproxy.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-wrapper_0.1.1_1787043749494_0.17781373766999464"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T09:02:29.332Z","0.1.1":"2026-08-18T09:02:29.643Z","modified":"2026-08-18T09:02:30.047Z"},"maintainers":[{"name":"idan-actionproxy","email":"npm@actionproxy.com"}],"description":"MCP stdio proxy for governing tool calls with ActionProxy policy, human approval, one-time grants, and audit","homepage":"https://actionproxy.com/quickstart/","keywords":["actionproxy","ai-agents","agent-security","ai-governance","approval-gateway","audit","human-in-the-loop","mcp","mcp-proxy","mcp-server","model-context-protocol","tool-calling","tool-governance"],"repository":{"type":"git","url":"git+https://github.com/ActionProxy/actionproxy.git","directory":"packages/mcp-wrapper"},"bugs":{"url":"https://github.com/ActionProxy/actionproxy/issues"},"license":"Apache-2.0","readme":"# ActionProxy MCP Wrapper\n\nWrap downstream MCP servers with ActionProxy approval, one-time execution grants, and audit.\n\nThis package is the local stdio proxy; it does not install or start the\nActionProxy gateway. Complete the local gateway proof first, then verify and\ninstall the exact wrapper version:\n\n```bash\nnpm view @actionproxy/mcp-wrapper@0.1.1 version dist.integrity repository.url dist.attestations\nnpm install --save-exact @actionproxy/mcp-wrapper@0.1.1\n```\n\nIf the exact registry lookup does not succeed, the release is not available\nyet. Do not substitute an unscoped or similarly named package. Use the reviewed\nsource-tarball fallback below.\n\nRegister only `actionproxy-mcp` in the MCP host. Do not also register the\ndownstream server directly; that would create an ungoverned bypass around\nActionProxy policy, approval, grants, and audit.\n\nStart the separate ActionProxy gateway, create `actionproxy.mcp.yaml`, and run\na static configuration check:\n\n```bash\nnpm exec -- actionproxy-mcp doctor --config actionproxy.mcp.yaml\nnpm exec -- actionproxy-mcp doctor --config actionproxy.mcp.yaml --json\n```\n\nStatic doctor starts no downstream process and does not prove policy or\nexecution. After reviewing every configured child command, add `--discover` to\nperform bounded MCP initialization and `tools/list`.\n\n## Register an npm-installed wrapper\n\nInstall the exact version in a stable project directory, then point the MCP\nhost at the installed executable. Do not register the downstream MCP server\nseparately.\n\n```bash\nnpm install --save-exact @actionproxy/mcp-wrapper@0.1.1\nnode /absolute/path/to/project/node_modules/@actionproxy/mcp-wrapper/dist/index.js doctor --config /absolute/path/to/project/actionproxy.mcp.yaml\n```\n\nUse absolute paths because MCP hosts may start outside the project directory.\nUse forward-slash absolute paths on Windows as well.\n\nCodex CLI:\n\n```bash\ncodex mcp add actionproxy -- node /absolute/path/to/project/node_modules/@actionproxy/mcp-wrapper/dist/index.js wrap --config /absolute/path/to/project/actionproxy.mcp.yaml\n```\n\nClaude Code CLI:\n\n```bash\nclaude mcp add --transport stdio actionproxy -- node /absolute/path/to/project/node_modules/@actionproxy/mcp-wrapper/dist/index.js wrap --config /absolute/path/to/project/actionproxy.mcp.yaml\n```\n\nGeneric stdio configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"actionproxy\": {\n      \"command\": \"node\",\n      \"args\": [\n        \"/absolute/path/to/project/node_modules/@actionproxy/mcp-wrapper/dist/index.js\",\n        \"wrap\",\n        \"--config\",\n        \"/absolute/path/to/project/actionproxy.mcp.yaml\"\n      ]\n    }\n  }\n}\n```\n\nSee the [adoption guide](https://github.com/ActionProxy/actionproxy/blob/v0.1.1/docs/ADOPTING.md),\n[wrapper schema](https://actionproxy.com/schemas/actionproxy.mcp-wrapper.v1.schema.json),\nand [host configurations](https://github.com/ActionProxy/actionproxy/tree/v0.1.1/examples/mcp-hosts).\n\n## Source-tarball fallback\n\nTo evaluate from a reviewed ActionProxy checkout or pin its exact local\nartifact, create and install a tarball:\n\n```bash\ncorepack pnpm install --frozen-lockfile\nmkdir -p /absolute/path/to/your-app/vendor\ncorepack pnpm --filter @actionproxy/mcp-wrapper pack \\\n  --out /absolute/path/to/your-app/vendor/actionproxy-mcp-wrapper-0.1.1.tgz\ncd /absolute/path/to/your-app\ncorepack pnpm add ./vendor/actionproxy-mcp-wrapper-0.1.1.tgz\ncorepack pnpm exec actionproxy-mcp wrap --config actionproxy.mcp.yaml\n```\n\nThe wrapper is a local stdio MCP server. A host connects to `actionproxy-mcp`, the wrapper reads tools from configured downstream MCP servers, and each `tools/call` is first submitted to ActionProxy. ActionProxy authorizes the call; the downstream MCP server still owns the real tool implementation and credentials.\n\n## CLI from the source checkout\n\nAfter building the wrapper in the ActionProxy checkout, invoke its generated\nentry point directly:\n\n```bash\n./packages/mcp-wrapper/dist/index.js wrap --config actionproxy.mcp.yaml\n```\n\nInspect the configured tool plane without starting a downstream process or\ncontacting ActionProxy:\n\n```bash\n./packages/mcp-wrapper/dist/index.js doctor --config actionproxy.mcp.yaml\n./packages/mcp-wrapper/dist/index.js doctor --config actionproxy.mcp.yaml --json\n```\n\nOpt in to bounded downstream discovery when you are ready to run the configured\ncommands. Discovery performs MCP `initialize` and one `tools/list`, then closes\neach process. It never calls a tool and still does not contact ActionProxy:\n\n```bash\n./packages/mcp-wrapper/dist/index.js doctor --config actionproxy.mcp.yaml --discover\n```\n\n`--discover` is protocol-read-only, not process-safe: it executes each\nconfigured child command with its configured OS privileges. Child startup is\nnot sandboxed, and a malicious process can act during initialization without a\n`tools/call`. Run discovery only for reviewed configurations in an isolated\nenvironment appropriate to those commands.\n\nDoctor output uses `actionproxy.tool-plane-report.v1` with\n`coverage: configured_mcp_wrapper`. Its explicit `unverified` list distinguishes\nconfiguration inspection from endpoint, host-registration, policy, approval,\nexecution, and audit verification.\n\nThe report does not verify agent-host configuration, host-native or provider-\nhosted tools, direct network or shell access, unmediated credentials,\nconversation identity, ActionProxy server policy, or prompt-injection\nresistance. Registering only this wrapper in the MCP host is an operator\nresponsibility; doctor cannot inspect or disable alternate host capabilities.\n\n## Config\n\n```yaml\nactionproxy:\n  baseUrl: http://localhost:8787\n  bearerTokenEnv: ACTIONPROXY_MCP_BEARER_TOKEN\n  requestedBy: mcp-host@example.com\n  agentId: actionproxy-mcp-wrapper\n  approvalPollIntervalMs: 1000\n  approvalTimeoutMs: 120000\n  cancelPendingOnAbort: false\n  requestTimeoutMs: 30000\n\nservers:\n  demo:\n    command: node\n    args: [\"./examples/mcp-demo/server.mjs\"]\n    envPassthrough: [DOWNSTREAM_CREDENTIAL_REFERENCE]\n    requestTimeoutMs: 30000\n\npolicies:\n  gmail.send_email:\n    approval: required\n```\n\n`policies` is documented intent for the wrapper config. Policy enforcement still happens in the ActionProxy server YAML policy.\n\n`bearerTokenEnv` is an environment-variable name, never a token value. For an\nauthenticated deployment, create a wrapper service account with only\n`tool_call:submit`, `tool_call:read`, and `execution_grant:consume`, then start\nthe wrapper with that variable set. Inline `token`, `bearerToken`, and `apiKey`\nconfig values are rejected.\n\n`cancelPendingOnAbort` defaults to `false` for compatibility. When enabled for\nan interactive adapter such as the bundled ChatGPT demo, an expired approval\nwait or an upstream MCP cancellation asks ActionProxy to cancel the proposal\nwhile it is still pending. The wrapper never resumes downstream dispatch after\nthat upstream request has ended; if a human decision wins the race, the\nrecorded server decision remains authoritative.\n\nThe wrapper passes only a small operating-system environment allowlist and\nexplicit `servers.<name>.env` entries to a downstream process. Existing parent\nvariables must be named individually under `envPassthrough`; only their names,\nnot values, enter YAML, and startup fails when a named variable is absent. The\nActionProxy bearer variable is always removed and cannot be passed through,\neven with different casing. Raw child stderr is drained rather than copied into\nordinary wrapper logs.\n\n## Behavior\n\n- `tools/list` returns the downstream tools.\n- `tools/call` submits the tool name and arguments to the trusted\n  `POST /v1/mcp/tool-calls` adapter boundary.\n- Allowed calls receive an execution grant, the wrapper consumes it, then forwards to the downstream MCP server.\n- Approval-required calls wait until ActionProxy approval completes, consume the final execution grant, then forward downstream.\n- Blocked or rejected calls return an MCP error result and do not call downstream.\n\nEvery submission carries a stable, random wrapper-session UUID in\n`X-ActionProxy-MCP-Session-Id`. Valid downstream results that will be returned\nto the model are reported before release with bounded\n`actionproxy.result-delivery.v1` evidence: a model-visible flag, canonical JSON\nSHA-256 hash, and canonical byte count. This also applies to valid MCP\n`isError: true` results. If outcome reporting fails, the result is withheld.\nTransport exceptions have no trusted model-visible result and return only a\nstatic wrapper message; child-provided exception text is not copied into the\nhost response.\n\nThe server derives an opaque influence scope from the UUID plus authenticated\nworkspace, principal, adapter, protocol, and transport state. The raw UUID is\nnot persisted or returned. Administrator-reviewed `resultSource` policy labels\nclassify model-visible output before release; later `influence` rules can only\npreserve, require approval, or deny relative to base policy. Integrity is\nadapter provenance, not content safety or instruction authority. A generic web\ntool is `public_untrusted`, and no hostname or vendor is automatically trusted.\n`instructionAuthority: none` is ActionProxy policy/exposure/audit evidence, not\na mutation of the child result. The valid child payload, including `_meta`, is\nopaque and unchanged; child assertions cannot grant authority or authorize a\nlater action.\nOne wrapper process may span conversations, and restarting it does not prove\nthe model cleared persistent memory.\n\nWhen enabling influence on an existing installation, start a fresh wrapper\nprocess and clear prior agent context where the host permits it. Reads released\nbefore opt-in were not classified or recorded, so the new scope can isolate\nfuture enforcement but cannot retroactively account for earlier content.\n\nThe wrapper sets `metadata.actionproxyExecution = \"external\"` so ActionProxy authorizes the call but does not require a gateway-side tool implementation for arbitrary downstream MCP tools.\nIf ActionProxy does not return a valid grant, or if grant consumption fails, the wrapper fails closed and does not call the downstream tool.\n\nEach stdio process creates a random transport-session nonce. A typed JSON-RPC\nrequest id and that nonce deterministically produce the `Idempotency-Key`: a\nrepeated numeric id is stable, numeric `1` differs from string `\"1\"`, and a\nsame-id changed payload reaches ActionProxy's conflict check. `tools/call`\nnotifications without an id are ignored and cannot create a side effect.\n\nHTTP responses, stdio frames, newline buffers, discovered tool counts/schemas,\nand tool results have conservative size limits. ActionProxy and downstream MCP\nrequests have timeouts. A downstream timeout after one-time grant consumption\nis reported as `timed_out`; a disconnect, unconfirmed cancellation, malformed\noutput, or other transport ambiguity is `unknown_outcome`. Neither state is\nretried automatically. Stdio idempotency is scoped to the running wrapper\nsession; process restart is not presented as safe recovery for an unknown\noutcome.\n\n## Scope\n\nThis package implements a bounded stdio JSON-RPC wrapper. The authenticated\nActionProxy server remains authoritative for tenant, actor, source protocol,\npolicy, approvals, execution attempts, and executor authorization. The wrapper\ndoes not add a connector marketplace, identity provider, approval authority,\nor retry/recovery engine.\n\nIt is also not a prompt-injection detector, content scanner, model gateway, or\nproof that the host cannot bypass the wrapper.\n\n## Support and Security\n\nFor usage questions and confirmed non-sensitive defects, use\n[GitHub Issues](https://github.com/ActionProxy/actionproxy/issues). For a\nsuspected vulnerability, follow the\n[ActionProxy security policy](https://github.com/ActionProxy/actionproxy/security/policy)\nand do not disclose credentials, exploit details, or other sensitive evidence\nin a public issue.\n","readmeFilename":"README.md","_rev":"1-3cd57dd295dfbf91556f4151e71a370d"}