{"_id":"@abhinavallani/mayi","name":"@abhinavallani/mayi","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@abhinavallani/mayi","version":"1.0.0","description":"An MCP proxy that enforces allow/deny/ask policy on tool calls between an MCP client and server.","main":"mayi.mjs","bin":{"mayi":"mayi.mjs"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["mcp","proxy","policy"],"author":{"name":"Abhinav Allani"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/abhinavallani02-cyber/mayI.git"},"type":"commonjs","dependencies":{"@modelcontextprotocol/server-filesystem":"^2026.7.10","yaml":"^2.9.0"},"gitHead":"2929228d9d601c9bc4f900ec87be79249733175b","_id":"@abhinavallani/mayi@1.0.0","bugs":{"url":"https://github.com/abhinavallani02-cyber/mayI/issues"},"homepage":"https://github.com/abhinavallani02-cyber/mayI#readme","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-2NCQbL51mUBSESEYWDrfXesw0KrD+jrjGz3A9Mi44O0XSYMpguGXEf9n35C9DOyHzmQPuKHqExLUvUfDItH6rg==","shasum":"390293a694090fc5238b6af0f38703ed9f387280","tarball":"https://registry.npmjs.org/@abhinavallani/mayi/-/mayi-1.0.0.tgz","fileCount":5,"unpackedSize":24470,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFglxv6nYhGpNShXxYoWkwi9D9BGkfWK7z549rHdCZH7AiAEOl2j6v0RURMZwYEYnbpqATs6nVWmv9NwN/kIAj/XJQ=="}]},"_npmUser":{"name":"abhinavallani","email":"abhinavallani02@gmail.com"},"directories":{},"maintainers":[{"name":"abhinavallani","email":"abhinavallani02@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mayi_1.0.0_1786247531765_0.8045612945698559"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T03:52:11.608Z","1.0.0":"2026-08-09T03:52:11.932Z","modified":"2026-08-09T03:52:12.192Z"},"maintainers":[{"name":"abhinavallani","email":"abhinavallani02@gmail.com"}],"description":"An MCP proxy that enforces allow/deny/ask policy on tool calls between an MCP client and server.","homepage":"https://github.com/abhinavallani02-cyber/mayI#readme","keywords":["mcp","proxy","policy"],"repository":{"type":"git","url":"git+https://github.com/abhinavallani02-cyber/mayI.git"},"author":{"name":"Abhinav Allani"},"bugs":{"url":"https://github.com/abhinavallani02-cyber/mayI/issues"},"license":"MIT","readme":"# mayI\n\nmayI is a proxy for [MCP](https://modelcontextprotocol.io) (Model Context\nProtocol), the standard AI agents use to call external tools. It sits\nbetween an MCP client (an AI agent) and an MCP server (a set of tools the\nagent can call — read/write files, run queries, send messages, and so on),\nenforcing a policy on every `tools/call` request before it reaches the\nserver. For each call it decides `allow`, `deny`, or `ask` — and `ask`\npauses to prompt a human at the terminal before letting the call through.\nEverything else (initialization, tool listing, responses, notifications)\npasses through unmodified. The goal is that a human can put real limits on\nwhat an agent is allowed to do without needing to trust the agent, or the\nserver, to enforce them itself.\n\n## Status\n\nEarly and small. It has only been tested against one server\n(`@modelcontextprotocol/server-filesystem`) over stdio, which is currently\nthe only transport it supports — no HTTP or SSE. Policy matching is tool\nname (with glob support) plus an optional path-prefix check on arguments;\nthere's no general condition language yet. It has not had a security\nreview. Treat it as a working prototype, not a hardened boundary.\n\n## Install\n\nNot published to npm yet. For now, run it from a checkout:\n\n```\ngit clone https://github.com/abhinavallani02-cyber/mayI\ncd mayI && npm install\nnode mayi.mjs -- npx -y @modelcontextprotocol/server-filesystem /path/to/allow\n```\n\nOnce it's published, the intended usage is `npx` (no install needed) or a\nglobal install:\n\n```\nnpx mayi -- npx -y @modelcontextprotocol/server-filesystem /path/to/allow\n\nnpm install -g mayi\nmayi -- npx -y @modelcontextprotocol/server-filesystem /path/to/allow\n```\n\nWith no `--policy` flag and no `policy.yaml` in the current directory,\nmayI runs with a built-in conservative default: reads are allowed,\neverything else asks. So the commands above work with zero config — it'll\nprompt you the first time the agent tries to write, move, or otherwise\nchange anything.\n\n## Usage\n\n```\nmayi [--policy <file>] [--audit <file>] [--audit-include-args] -- <command> [args...]\n```\n\nEverything after `--` is the real MCP server to spawn and front. For\nexample, to guard the filesystem server with your own policy:\n\n```\nmayi --policy policy.yaml --audit audit.jsonl -- \\\n  npx -y @modelcontextprotocol/server-filesystem /path/to/allow\n```\n\nPoint your MCP client at `mayi` (with its arguments) instead of at the\nreal server directly — mayI spawns the real server itself and speaks the\nsame stdio protocol on its own stdin/stdout, so from the client's\nperspective nothing else changes.\n\nFlags:\n\n- `--policy <file>` — path to the policy YAML file. Defaults to\n  `policy.yaml` in the current directory if it exists, otherwise the\n  built-in default described above.\n- `--audit <file>` — path to the audit log. Defaults to `audit.jsonl`.\n- `--audit-include-args` — include each call's arguments in the audit log.\n  Off by default; see [Audit logging](#audit-logging).\n- `-h`, `--help` — print usage and exit.\n\nRun from a git checkout instead of installed: replace `mayi` above with\n`node mayi.mjs`.\n\n## Policy\n\nA policy file is a list of rules, checked in order — the first matching\nrule wins. Each rule matches on the tool name (supporting `*` as a glob)\nand, optionally, a `path_prefix` checked against the call's `path`,\n`source`, or `destination` argument, whichever is present.\n\n```yaml\nrules:\n  - tool: read_*\n    action: allow\n\n  - tool: write_file\n    path_prefix: /etc\n    action: deny\n\n  - tool: write_*\n    action: ask\n\n  - tool: \"*\"\n    action: allow\n```\n\nThe three actions:\n\n- **`allow`** — the call is forwarded to the server immediately, no\n  logging beyond the normal verdict line.\n- **`deny`** — the call never reaches the server. mayI sends a JSON-RPC\n  error back to the client on the same request id instead.\n- **`ask`** — mayI prints the tool name and arguments to the terminal and\n  waits (up to 30 seconds) for a human to type `y` or `n`. `y` forwards\n  the call as if it were `allow`; `n`, any other answer, or a timeout\n  denies it as if it were `deny`. If there's no controlling terminal to\n  ask (e.g. mayI's own input/output are both piped, with no tty attached),\n  `ask` always resolves to deny — there's no human to ask, so the safe\n  default applies.\n\nIf no rule matches a call, mayI defaults to `ask` rather than silently\nallowing it.\n\n## Audit logging\n\nEvery verdict — `allow`, `deny`, `ask` → approved, or `ask` → denied — is\nappended to the audit log as one JSON object per line:\n\n```json\n{\"timestamp\":\"2026-08-09T03:21:42.139Z\",\"id\":3,\"tool\":\"write_file\",\"verdict\":\"ask→approved\"}\n```\n\nBy default the log records only the decision: timestamp, request id, tool\nname, and verdict. It does **not** include the call's arguments — file\npaths, file contents, or anything else passed to the tool — because\narguments can carry sensitive data that shouldn't end up in a plaintext\nlog file just from running the proxy. Pass `--audit-include-args` to\ninclude them anyway, if you want a more detailed log and understand what\nthat means for the log file's contents.\n\nResponse payloads (what the server actually returned) are never written\nto the audit log, in either mode.\n","readmeFilename":"README.md","_rev":"1-bbde1687af97f640f5a7fac3172d85b0"}