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

@agentsoft/agent-vault

v0.8.0

Published

MCP server providing secure, access-controlled secret management for agentflow agents

Readme

@agentsoft/agent-vault

MCP server that gives Claude Code / agentflow agents secure, ACL-gated access to secrets stored in Infisical. One Infisical organization, many agent-vault projects (each its own Infisical workspace), many agent identities — each scoped by domain, environment, and role.

Status: v0.8.0, actively iterated. Core flows verified end-to-end against a self-hosted Infisical. Not yet published to npm — install locally via npm link (see below).


What it does

  • Bootstraps Infisical workspaces from the MCP itself (vault_create_project) — no manual UI clicking to set up a new project's secret store.
  • Routes secret reads/writes through a four-segment namespace: {project}/{env}/{domain}/{key} — e.g. ecommerce/dev/backend/STRIPE_KEY.
  • Enforces a two-layer ACL:
    1. Namespace ACL — who can access what path, with role-based templates (worker, planner, tester, devops, shared-reader, auditor, custom), plus user-defined roles in YAML.
    2. Tool ACL — which MCP tools each agent can even call. Enforced at tool registration time when a default agent is set, at runtime always.
  • Every tool call is recorded in an append-only audit log.
  • Provides lifecycle commands: setup, add-agent, remove-agent, roles list/show, detect, health, rotate.

Install

Today — local dev via npm link

git clone <this-repo>
cd agent-vault
pnpm install
pnpm build
npm link     # makes `agent-vault` available on your PATH

Verify:

agent-vault        # → "No vault-config.yaml found — run agent-vault setup"

Later — once published

npx @agentsoft/agent-vault setup
# or install globally
npm install -g @agentsoft/agent-vault

Quick start (5 minutes)

1. Run Infisical

Use the bundled compose file, or point at an existing instance:

docker compose up -d    # starts Infisical + Postgres + Redis
# open http://localhost:8080, create an account, create an organization

2. Provision identities

Interactive wizard (scans for agentflow + user agents, prompts for role assignment):

agent-vault setup

Or non-interactive with an agents list:

# agents.yaml
agents:
  - { name: devops-executor,  domain: devops,  role: devops }
  - { name: backend-executor, domain: backend, role: worker }
  - { name: auditor,          domain: shared,  role: auditor }
VAULT_SETUP_URL=http://localhost:80 \
VAULT_SETUP_TOKEN=<your-admin-jwt> \
VAULT_SETUP_ORG=<your-org-id> \
VAULT_SETUP_ENVS=dev,qa,prod \
  agent-vault setup --agents-file ./agents.yaml

Writes to ~/.config/agent-vault/:

  • vault-config.yaml — credentials (gitignore this if you point it elsewhere)
  • vault-acl.yaml — role assignments and ACL rules
  • vault-state.json — runtime workspace mapping (populated as you create projects)

3. Verify

agent-vault health
# Summary: config=OK, connection=OK, identities=N/N valid

4. Add to your project's .mcp.json

{
  "mcpServers": {
    "agent-vault": { "command": "agent-vault" }
  }
}

That's the entire per-project footprint. The server auto-discovers ~/.config/agent-vault/vault-config.yaml.

Optionally set a session default identity:

{
  "mcpServers": {
    "agent-vault": {
      "command": "agent-vault",
      "env": { "VAULT_DEFAULT_AGENT": "backend-executor" }
    }
  }
}

5. Bootstrap a project and use it

Start a Claude Code session in the project. Then ask:

Create an agent-vault project called my-app, then save a secret STRIPE_KEY with value sk_test_xxx to my-app/dev/backend, using agent devops-executor.

Claude will call:

vault_create_project({ name: "my-app", agent: "devops-executor" })
vault_set({ namespace: "my-app/dev/backend", key: "STRIPE_KEY", value: "sk_test_xxx", agent: "backend-executor" })

A new Infisical workspace is created, folders provisioned, memberships granted, and the secret written.


Concepts

Namespace: {project}/{env}/{domain}/{key}

Every secret lives at a 4-segment path:

  • project — routes to an Infisical workspace. Created on demand via vault_create_project.
  • env — Infisical environment (dev, qa, prod). Created automatically inside the workspace when the project is bootstrapped.
  • domain — folder inside the env. Standard set: backend, frontend, mobile, devops, qa, shared.
  • key — the secret name.

Example: ecommerce/dev/backend/STRIPE_KEY → Infisical workspace ecommerce, env dev, folder /backend, secret STRIPE_KEY.

Roles

Role templates translate to ACL rules + tool allow-lists. Built-ins:

| Role | Namespace access | Tools | |---|---|---| | worker | R/W/D/L on {project}/{env}/{domain}; R/L on {project}/{env}/shared | all | | planner | R/L on own domain + shared | vault_get, vault_list, vault_exists | | tester | same as worker (for test fixtures) | all | | devops | override: R/W/D/L/create on {project}/* (cross-env/domain) | all | | shared-reader | R/L on {project}/{env}/* (all domains) | vault_get, vault_list, vault_exists | | auditor | L on {project}/* | vault_list, vault_exists (no value reads) | | custom | none — hand-edit ACL | all |

Assignments in vault-acl.yaml:

domains:
  backend: [backend-executor, backend-planner]
  devops:  [devops-executor]
  shared:  [auditor, software-architect]

agent_roles:
  backend-executor: worker
  backend-planner:  planner
  devops-executor:  devops
  auditor:          auditor
  software-architect: shared-reader

Custom roles

Define in the same YAML:

roles:
  reviewer:
    access:
      - { namespace: "{project}/*", permissions: [read, list] }
    tools: [vault_get, vault_list, vault_exists]

  release-captain:
    overrides:
      - { namespace: "{project}/prod/*", permissions: [read, write, list] }
    tools: null   # unrestricted

agent_roles:
  alice-reviewer: reviewer
  bob-captain:    release-captain

User-defined roles can override built-ins by using the same name (e.g. narrowing the stock auditor).

Identity — per-call

Every tool call takes an agent parameter. That identity:

  • Determines which namespace ACL rules apply
  • Determines which tool-level restrictions apply
  • Determines which Infisical credentials authenticate for that call

If you set VAULT_DEFAULT_AGENT=backend-executor in the MCP server env, calls without agent fall back to that identity. Otherwise agent is required.

Lazy auth

The server doesn't authenticate to Infisical at startup. First call per agent triggers a Universal Auth login; the token is cached for subsequent calls. Supports multi-agent sessions naturally — dispatching a new agent just means one extra login on its first call.


CLI reference

All commands find config via: VAULT_CONFIG_PATH./vault-config.yaml~/.config/agent-vault/vault-config.yaml.

agent-vault setup

Scans for agent definitions (./agentflow/agents, ./.claude/agents, ~/.claude/agents, plus any --scan <dir>), auto-assigns agentflow agents by naming convention, prompts for user agents. Provisions Infisical identities and writes config + ACL + empty state.

Flags:

  • --agents-file <path> — non-interactive; skip detection, use explicit list
  • --no-agentflow — skip the agentflow/ scan
  • --scan <dir> — add a directory to the user-scope scan (repeatable)
  • --project-scope — write files to $PWD instead of ~/.config/agent-vault/

Env-var fallbacks for non-interactive connection prompts:

  • VAULT_SETUP_URL, VAULT_SETUP_TOKEN, VAULT_SETUP_ORG, VAULT_SETUP_ENVS

agent-vault detect [--scan <dir>]

Read-only. Prints classified agents (agentflow vs user, with auto-assigned (domain, role) for agentflow). No side effects.

agent-vault add-agent <name> --domain <d> --role <r>

Provisions a new identity in Infisical, appends to vault-acl.yaml and vault-config.yaml, and grants workspace membership on every existing project in vault-state.json.

agent-vault remove-agent <name> [--keep-identity]

Removes the identity from every known workspace, deletes it from Infisical (unless --keep-identity), and strips from ACL + config.

agent-vault roles list

Prints built-in and custom roles with one-line summaries. Shows overrides when a built-in is shadowed by a user-defined role of the same name.

agent-vault roles show <name>

Dumps the role's full definition: access rules, overrides, tool allow-list, and whether it's built-in, custom, or a custom-overriding-built-in.

agent-vault health

Validates config parses, Infisical is reachable, and every identity can complete a Universal Auth login. Exits non-zero if any check fails.

agent-vault rotate <agent-name> / --all

Generates new Universal Auth client secrets for one agent or all agents. Updates vault-config.yaml in place. Requires INFISICAL_TOKEN env (a user JWT with admin perms) because machine-identity creds can't rotate themselves.


MCP tools reference

All secret tools take namespace and key arguments, plus an agent parameter (optional if VAULT_DEFAULT_AGENT is set, required otherwise).

vault_get({ namespace, key, agent? })

Returns the secret value + metadata, or a not-found message.

vault_set({ namespace, key, value, description?, tags?, agent? })

Creates or updates a secret. description → Infisical secret comment; tags → categorization.

vault_delete({ namespace, key, agent? })

Deletes the secret.

vault_list({ namespace, agent? })

Returns the list of keys in that folder (no values).

vault_exists({ namespace, key, agent? })

Returns a boolean. Gated by list permission (not read) so auditor-style roles can check existence without reading values.

vault_create_project({ name, agent? })

Bootstraps a new Infisical workspace. Creates the workspace, provisions all configured envs, grants every agent identity membership, and creates {backend, frontend, mobile, devops, qa, shared} folders in each env. Requires the create permission (typically devops-only).


Configuration

File layout

Default (user-scoped, XDG):

~/.config/agent-vault/
├── vault-config.yaml     # adapter settings + credentials
├── vault-acl.yaml        # roles + agent_roles + domains
├── vault-state.json      # project → workspace UUID map
└── vault-audit.jsonl     # append-only audit log

Respects $XDG_CONFIG_HOME/agent-vault if set.

Environment variables

| Var | Purpose | Default | |---|---|---| | VAULT_CONFIG_PATH | Explicit path to vault-config.yaml | auto-discover | | VAULT_DEFAULT_AGENT | Session default identity when call omits agent | unset | | VAULT_ENV | Default env for {env} ACL template resolution | from config | | VAULT_SETUP_URL | (setup only) skip URL prompt | — | | VAULT_SETUP_TOKEN | (setup only) skip admin token prompt | — | | VAULT_SETUP_ORG | (setup only) skip org ID prompt | — | | VAULT_SETUP_ENVS | (setup only) skip envs prompt | — | | INFISICAL_TOKEN | (rotate only) admin token for rotation | — | | VAULT_AGENT_ID | deprecated — falls back to VAULT_DEFAULT_AGENT | — |

vault-config.yaml schema

adapter:
  type: infisical
  connection:
    siteUrl: http://localhost:80
    organizationId: <uuid>
  environments: [dev, qa, prod]
  agentIdentities:
    backend-executor:
      identityId: <uuid>
      clientId:   <uuid>
      clientSecret: <hex>
    # ... one entry per agent
  adminIdentity:    # used for vault_create_project + add-agent + remove-agent
    identityId: <uuid>
    clientId:   <uuid>
    clientSecret: <hex>

defaultEnvironment: dev
aclPath: ./vault-acl.yaml
statePath: ./vault-state.json
auditLogPath: ./vault-audit.jsonl   # set to null to disable audit

Paths with ./ are resolved relative to the config file's directory.


Audit log

vault-audit.jsonl contains one JSON record per tool call:

{
  "ts": "2026-04-16T23:12:59.533Z",
  "agent": "backend-executor",
  "defaultAgent": null,
  "tool": "vault_set",
  "namespace": "ecommerce/dev/backend",
  "key": "DB_URL",
  "permission": "write",
  "result": "allowed"
}

Fields:

  • ts — ISO-8601 timestamp
  • agent — the identity the call ran as (from the agent param or default)
  • defaultAgent — what VAULT_DEFAULT_AGENT was set to, for context
  • tool — tool name
  • namespace, key, permission — what was attempted
  • result"allowed", "denied", or "error"
  • reason — only on denied / error — the message

Append-only, never rotated by the package. Use jq / grep to trace activity.


Architecture

Layers

  MCP client (Claude Code session)
       │
       ▼
  stdio (JSON-RPC 2.0)
       │
       ▼
  ┌────────────────────────────────────────┐
  │  MCP server (this package)             │
  │  ┌──────────────────────────────────┐  │
  │  │  Tool handlers (tools.ts)         │  │
  │  │   ├─ resolve agent (per-call)    │  │
  │  │   ├─ tool-level ACL              │  │
  │  │   ├─ audit log                   │  │
  │  │   └─ delegate to Vault           │  │
  │  └──────────────────────────────────┘  │
  │  ┌──────────────────────────────────┐  │
  │  │  Vault core (core/vault.ts)      │  │
  │  │   ├─ namespace parse             │  │
  │  │   ├─ ACL enforcement             │  │
  │  │   ├─ lazy per-agent auth cache   │  │
  │  │   └─ state lookup (StateStore)   │  │
  │  └──────────────────────────────────┘  │
  │  ┌──────────────────────────────────┐  │
  │  │  Adapter (adapters/infisical.ts) │  │
  │  │   ├─ Universal Auth login         │  │
  │  │   ├─ secret CRUD via SDK          │  │
  │  │   └─ workspace/folder ops (REST)  │  │
  │  └──────────────────────────────────┘  │
  └────────────────────────────────────────┘
       │                                    
       ▼                                    
  Infisical API (@infisical/sdk + REST)

Workspace-per-project model

One agent-vault project = one Infisical workspace. vault_create_project:

  1. Creates workspace (POST /api/v2/workspace)
  2. Creates each configured environment (POST /api/v1/workspace/:id/environments)
  3. Grants every agent identity membership as member
  4. Creates {backend, frontend, mobile, devops, qa, shared} folders per env
  5. Records project_name → workspace_id in vault-state.json

State is runtime-mutable; config is immutable (setup + CLI commands edit it, the server never does).

ACL enforcement layers

  1. MCP tool ACL (at registration, if VAULT_DEFAULT_AGENT is set): tools the default identity can't use are not registered. Client's tools/list never sees them.
  2. Tool ACL at runtime (every call): the actual calling identity is checked. A call to a tool the identity isn't allowed → denied with audit log.
  3. Namespace ACL: checked by Vault.assertPermission before the adapter is touched. Resolves {self}, {domain}, {env}, {project} templates against the call's identity and namespace.
  4. Backend-level (Infisical): the agent's identity is a workspace member, so Infisical itself authorizes the API call. The narrower agent-vault ACL is the real policy; Infisical is intentionally broad storage.

What's NOT enforced

  • In-session identity isolation: when one Claude Code session dispatches subagents via the Agent tool, they all share the same MCP process. The per-call agent param is authoritative but advisory — a subagent that "forgets" to declare its identity falls back to the session's VAULT_DEFAULT_AGENT, and there's no OS-level boundary between subagent calls. For hard role isolation, run each role in a separate Claude Code session. See commit 0949971 for the reasoning.

Development

Build + test

pnpm install
pnpm build          # tsc → dist/
pnpm test           # vitest, ~170 tests
pnpm test:watch

Project layout

src/
├── types.ts                    # Shared types
├── index.ts                    # Public exports
├── paths.ts                    # XDG config resolution
├── acl/
│   ├── acl-config.ts           # YAML parser
│   ├── acl-engine.ts           # Permission resolution + role expansion
│   └── roles.ts                # Built-in role templates
├── core/
│   └── vault.ts                # Orchestrator + lazy auth + namespace routing
├── adapters/
│   └── infisical.adapter.ts    # Infisical backend
├── ports/
│   └── vault-adapter.port.ts   # Backend-agnostic adapter interface
├── state/
│   └── state-store.ts          # vault-state.json persistence
├── audit/
│   └── audit-logger.ts         # JSONL append-only log
├── detection/
│   ├── scanner.ts              # Scans .md files for agents
│   └── agentflow-conventions.ts  # Name → (domain, role) mapping
├── mcp/
│   ├── server.ts               # MCP server factory
│   └── tools.ts                # Tool handlers
└── cli/
    ├── entry.ts                # Command dispatch
    ├── setup.ts                # Interactive/non-interactive wizard
    ├── detect.ts, health.ts, rotate.ts,
    ├── add-agent.ts, remove-agent.ts, roles.ts
    └── admin-ops.ts            # Shared admin-API helpers

Adding a new backend adapter

Implement VaultAdapter (see src/ports/vault-adapter.port.ts). Methods take backend-agnostic primitives — workspace identifier, env, folder path, secret name — so Vault-level code doesn't need changes. Register the adapter type in src/cli/entry.ts's createAdapter switch and update the setup wizard to prompt for that backend's connection details.

Contributing

PRs welcome. Conventional commits enforced via commitlint. Husky runs tests pre-commit.


License

MIT.