npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@usewombat/gateway

v0.1.0

Published

Resource-level permissions for MCP agents — rwxd on any resource, deny by default

Readme

Wombat

Resource-level permissions for MCP agents.

Wombats protect their burrow with their reinforced rear end.
Wombat protects your agent with a permissions manifest.

Agent (Claude Code, Cursor, OpenClaw, etc.)
        │
        ▼
┌──────────────────────────────┐
│           wombat             │
│   checks permissions.json    │  deny by default
│   on every single tool call  │
└──────┬───────────────────────┘
       │ allowed calls only
  ┌────┴────┬──────────┐
  │         │          │
GitHub    Slack    Filesystem

Why Wombat?

Every MCP permission system today controls which tools an agent can use:

# Everyone else
permissions:
  allow: ["mcp:github:get_*", "mcp:slack:send_message"]
  deny:  ["mcp:github:delete_*"]

This is tool-name pattern matching. The tool is either on or off.

Wombat controls what the agent can do with those tools:

{ "resource": "github/org/repo/main", "mode": "r---" }

The same push_files tool is allowed on feature/x and denied on main. No other MCP permission system can express this.

This is the Unix model applied to AI agents: rwxd on any resource, deny by default, most specific rule wins.


Install

npm install -g @wombat/gateway
# or just: npx @wombat/gateway

Requires Node.js 22+


Quick start

1. Create a manifest

cp $(wombat --example) ./permissions.json
# edit permissions.json

2. Add Wombat to Claude Code

claude mcp add wombat -- wombat \
  --manifest ./permissions.json \
  --upstream github \
  --upstream filesystem \
  --dashboard 7842

Add your token to .claude.json:

{
  "mcpServers": {
    "wombat": {
      "command": "wombat",
      "args": ["--manifest", "./permissions.json", "--upstream", "github", "--dashboard", "7842"],
      "env": { "GITHUB_TOKEN": "your_token_here" }
    }
  }
}

3. Open the dashboard

open http://localhost:7842

Every tool call appears live — allowed in green, denied in red.


The manifest

{
  "version": "0.1",
  "umask": "----",
  "grants": [
    { "resource": "github/my-org/my-repo",      "mode": "rw--", "comment": "Read and write" },
    { "resource": "github/my-org/my-repo/main",  "mode": "r---", "comment": "Main is read-only" },
    { "resource": "filesystem/project",          "mode": "rw--", "comment": "Project files" },
    { "resource": "filesystem/project/.env",     "mode": "----", "comment": "Never touch .env" }
  ],
  "sudo": { "enabled": false }
}

Mode strings

4 characters: rwxd. Use - to deny that position.

| Pos | Char | Meaning | |---|---|---| | 0 | r | read — get, list, view | | 1 | w | write — create, update, push | | 2 | x | execute — run, merge, shell | | 3 | d | delete |

r--- = read only · rw-- = read+write · rwxd = full access · ---- = explicit deny

Specificity rules

More specific paths win. Exact match beats wildcard.

github/org/repo/main   ← wins (most specific)
github/org/repo        ← second
github/org/*           ← third
github/**              ← least specific

The umask

Default for anything not in a grant. Always set to ----.


Built-in servers

Use short names — Wombat auto-expands to the right package:

wombat --upstream github      # @github/mcp-server
wombat --upstream filesystem  # @modelcontextprotocol/server-filesystem
wombat --upstream slack       # @modelcontextprotocol/server-slack
wombat --upstream postgres    # @modelcontextprotocol/server-postgres
wombat --upstream brave       # @modelcontextprotocol/server-brave-search
wombat --upstream puppeteer   # @modelcontextprotocol/server-puppeteer
wombat --upstream memory      # @modelcontextprotocol/server-memory
wombat --upstream fetch       # @modelcontextprotocol/server-fetch

# Or specify the full command manually:
wombat --upstream "myserver:npx @my/mcp-package"

See all registered servers:

wombat --list

Wombat warns at startup if required env vars are missing.


Plugin system

Wombat has three tiers of server support:

Tier 1 — Built-in

The servers above, maintained by the Wombat team. Full resolver tables, well-tested.

Tier 2 — Community plugins

Install a community plugin and Wombat auto-discovers it:

npm install @wombat-plugin/notion
npm install @wombat-plugin/linear
npm install @wombat-plugin/jira
# restart wombat — plugins are loaded automatically

Then use them like any built-in server:

wombat --upstream notion --upstream linear

And grant access in permissions.json:

{ "resource": "notion/page/*",       "mode": "r---" },
{ "resource": "linear/issue/*",      "mode": "rw--" }

Tier 3 — Local plugins

For internal MCP servers that will never be published. Create wombat.plugins.js in your project root:

// wombat.plugins.js
export default [
  {
    name: "mycompany",
    tools: {
      mycompany__get_customer:    ["r", (p) => `mycompany/customer/${p.id}`],
      mycompany__update_customer: ["w", (p) => `mycompany/customer/${p.id}`],
      mycompany__delete_customer: ["d", (p) => `mycompany/customer/${p.id}`],
    },
    exampleGrants: [
      { resource: "mycompany/customer/*", mode: "r---", comment: "Read any customer" },
    ],
  }
];

No npm account, no PR, no waiting. Loaded automatically on startup.

Publishing a community plugin

Copy the plugin template, fill in the tool table, publish:

npm publish --access public

That's it. Anyone who installs @wombat-plugin/yourserver gets your resolver table automatically. No PR to the Wombat repo required.


Manifest integrity

Wombat computes a hash of permissions.json at startup and verifies it on every call. If the file is modified after startup — including by the agent — all calls are denied until you restart.

# Default — integrity enforced (production)
wombat --manifest ./permissions.json --upstream github

# Development — live reload, no integrity check
wombat --manifest ./permissions.json --upstream github --live-reload

Store permissions.json outside any directory the agent can write to. The default working directory is writable by the agent — move your manifest to a parent directory:

wombat --manifest ~/wombat/permissions.json --upstream github

How it works

Claude Code spawns Wombat as a child process and talks via stdio MCP. Wombat simultaneously:

  1. Acts as an MCP server to Claude Code — advertises all upstream tools
  2. Acts as an MCP client to each upstream — forwards allowed calls
Claude Code calls github__push_files(owner, repo, branch: "main")
    │
    ▼
resolver: "write on github/org/repo/main"
    │
    ▼
manifest: github/org/repo/main has r--- → write denied
    │
    ▼
error returned to Claude Code ✗ GitHub never sees the call
Claude Code calls github__get_file_contents(owner, repo, path: "README.md")
    │
    ▼
resolver: "read on github/org/repo"
    │
    ▼
manifest: github/org/repo has rw-- → read allowed
    │
    ▼
forwarded to GitHub MCP server ✓ result returned

Dashboard

Local dashboard at http://localhost:7842 — every tool call in real time.

  • allow (green) — forwarded to upstream
  • deny (red) — blocked, error returned to agent
  • Filter by decision, server, or resource
  • "Clear session" resets the view without deleting audit history

Only accessible on localhost. No data leaves your machine.


Audit log

Every call logged to wombat-audit.jsonl:

{"ts":"2026-03-17T10:23:01Z","session":"sess_abc","agent":"claude-code","tool":"github__push_files","server":"github","resource":"github/org/repo/main","mode":"w","decision":"deny","ms":2,"manifest_hash":"sha256:abc..."}

Logged: tool name, resource path, mode, decision, timing.
Never logged: parameter values, file contents, API responses, personal data.


CLI reference

wombat [options]

  --manifest <path>     Path to permissions.json (required)
  --upstream <n>     Server name or "name:command" — repeat for multiple
  --dashboard <n>       Dashboard port (default: 7842)
  --agent <n>        Agent ID for audit log (default: unknown)
  --audit <path>        Audit log path (default: ./wombat-audit.jsonl)
  --live-reload         Reload manifest on every call, disable integrity checks
                        WARNING: development only
  --lock <path>         Integrity lock file path (default: /tmp/wombat-<session>.lock)
  --list                List all servers in the built-in registry
  --example             Print path to example permissions.json
  --help                Show this help

How Wombat differs

| | Tool-name permissions | Wombat | |---|---|---| | Claude Code built-in | Bash(git push:*) — allow/deny by tool name | ✗ | | Cogvel / agent YAML | allow: ["mcp:github:push_*"] — same tool for all repos | ✗ | | Runlayer / MintMCP | Role-based, enterprise sales call required, not open source | ✗ | | Wombat | github/org/repo/main: r--- — same tool, different decision per resource | ✓ |

They control which tools the agent can use. Wombat controls what the agent can do with those tools.

No other tool lets you say: allow push_files to feature branches, deny it to main. In Wombat:

{ "resource": "github/org/repo",      "mode": "rw--" },
{ "resource": "github/org/repo/main", "mode": "r---" }

Known limitation

The local Wombat is a process-level proxy. An agent that knows the real MCP server addresses could connect directly, bypassing Wombat. This is a documented limitation of the local open-source version.

The hosted version (coming) enforces this structurally — real API tokens never reach the developer's machine, so there is nothing to bypass.


Security

See SECURITY.md to report vulnerabilities. Email [email protected]. Do not open a public issue.


License

MIT — LICENSE

Built by Wombat