{"_id":"@apralabs/blindfold","_rev":"2-460b49d9847fd2eb01135cf729160ee7","name":"@apralabs/blindfold","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@apralabs/blindfold","version":"0.1.0","keywords":["mcp","credentials","secrets","ai-agents","claude","oob","vault"],"author":{"name":"Apra Labs"},"license":"Apache-2.0","_id":"@apralabs/blindfold@0.1.0","maintainers":[{"name":"kumaakh","email":"akhil@apra.in"},{"name":"dpkay","email":"deepakjha.dpk@gmail.com"},{"name":"mr4du1-apra","email":"mradul@apra.in"}],"homepage":"https://github.com/Apra-Labs/blindfold","bugs":{"url":"https://github.com/Apra-Labs/blindfold/issues"},"bin":{"blindfold":"dist/cli/index.js"},"dist":{"shasum":"9bc6a315ea1fcd5a412a4e7b3d4bde982fa778da","tarball":"https://registry.npmjs.org/@apralabs/blindfold/-/blindfold-0.1.0.tgz","fileCount":91,"integrity":"sha512-bhVgmVbF/rBGpOVmyazLfGmCCFIm8iNnY74dolhyChxyL+PpM2MieQU6BswYEtVX63fdj+O7FkAdnLK4VXHLGw==","signatures":[{"sig":"MEUCIDv8qM9KIqV6p15VD7Iqmcayn7kx0PIAcDEUDvcdSHinAiEArBNUaA+RU07/91PHVVKMZZ2PssHy/aHC6va4xhlILjk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":198845},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./mcp":{"types":"./dist/mcp/server.d.ts","import":"./dist/mcp/server.js"}},"gitHead":"8db5cae4f84b684f25ab8ac1376233887344428b","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","prepack":"npm run build","test:watch":"vitest","build:binary":"node scripts/build-sea.mjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr4du1-apra","email":"mradul@apra.in"},"repository":{"url":"git+https://github.com/Apra-Labs/blindfold.git","type":"git"},"_npmVersion":"10.8.2","description":"Secure credential vault for AI agents — OOB collection, encryption, and token resolution that keeps secrets out of LLM context windows","directories":{},"_nodeVersion":"20.20.1","dependencies":{"zod":"^3.25.0","@inquirer/password":"^5.0.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","esbuild":"^0.25.0","postject":"^1.0.0-alpha.6","typescript":"^5.5.0","@types/node":"^22.0.0","@modelcontextprotocol/sdk":"^1.27.0"},"peerDependencies":{"@modelcontextprotocol/sdk":"^1.27.0"},"peerDependenciesMeta":{"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/blindfold_0.1.0_1780049953227_0.8765417079853262","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@apralabs/blindfold","version":"0.1.1","description":"Secure credential vault for AI agents — OOB collection, encryption, and token resolution that keeps secrets out of LLM context windows","author":{"name":"Apra Labs"},"homepage":"https://github.com/Apra-Labs/blindfold","repository":{"type":"git","url":"git+https://github.com/Apra-Labs/blindfold.git"},"license":"Apache-2.0","type":"module","main":"dist/index.js","types":"dist/index.d.ts","bin":{"blindfold":"dist/cli/index.js"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./mcp":{"types":"./dist/mcp/server.d.ts","import":"./dist/mcp/server.js"}},"publishConfig":{"access":"public"},"keywords":["mcp","credentials","secrets","ai-agents","claude","oob","vault"],"engines":{"node":">=20"},"scripts":{"build":"tsc","build:binary":"node scripts/build-sea.mjs","dev":"tsc --watch","test":"vitest run","test:watch":"vitest","prepack":"npm run build","prepublishOnly":"npm run build"},"dependencies":{"@inquirer/password":"^5.0.11","zod":"^3.25.0"},"peerDependencies":{"@modelcontextprotocol/sdk":"^1.27.0"},"peerDependenciesMeta":{"@modelcontextprotocol/sdk":{"optional":true}},"devDependencies":{"@modelcontextprotocol/sdk":"^1.27.0","@types/node":"^22.0.0","esbuild":"^0.25.0","postject":"^1.0.0-alpha.6","typescript":"^5.5.0","vitest":"^4.0.18"},"_id":"@apralabs/blindfold@0.1.1","bugs":{"url":"https://github.com/Apra-Labs/blindfold/issues"},"_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-48nJrmyKjy3LSdhSNE142MYivcmfxOU71j425Fgj8NpNzxuC+o3xW+URnqzqhWHTDJerKSPIC87N7W1XvLsk2Q==","shasum":"0ad35b08f38e95cc7c7b6b2389b6caf20e2e74ce","tarball":"https://registry.npmjs.org/@apralabs/blindfold/-/blindfold-0.1.1.tgz","fileCount":91,"unpackedSize":199414,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGd8/U057p9lKNH/vOPXjqG7tyCeHd8FgZIR3If5t5yQAiEAoudJreRT8oy9CN1Wt6jq5c8Yw5QIAytFtld56E3kfwQ="}]},"_npmUser":{"name":"mr4du1-apra","email":"mradul@apra.in"},"directories":{},"maintainers":[{"name":"kumaakh","email":"akhil@apra.in"},{"name":"dpkay","email":"deepakjha.dpk@gmail.com"},{"name":"mr4du1-apra","email":"mradul@apra.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/blindfold_0.1.1_1780900684613_0.9318770234350633"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T10:19:13.053Z","modified":"2026-06-08T06:38:04.923Z","0.1.0":"2026-05-29T10:19:13.382Z","0.1.1":"2026-06-08T06:38:04.758Z"},"bugs":{"url":"https://github.com/Apra-Labs/blindfold/issues"},"author":{"name":"Apra Labs"},"license":"Apache-2.0","homepage":"https://github.com/Apra-Labs/blindfold","keywords":["mcp","credentials","secrets","ai-agents","claude","oob","vault"],"repository":{"type":"git","url":"git+https://github.com/Apra-Labs/blindfold.git"},"description":"Secure credential vault for AI agents — OOB collection, encryption, and token resolution that keeps secrets out of LLM context windows","maintainers":[{"name":"kumaakh","email":"akhil@apra.in"},{"name":"dpkay","email":"deepakjha.dpk@gmail.com"},{"name":"mr4du1-apra","email":"mradul@apra.in"}],"readme":"# blindfold\n\n**Secure credential vault for AI agents.** Blindfold keeps secrets out of LLM context windows by collecting them through an out-of-band (OOB) side-channel, encrypting them with AES-256-GCM, and resolving them only at the last moment — right before a shell command runs. The LLM only ever sees a `{{secure.NAME}}` token; the plaintext never touches the model.\n\n---\n\n## Quick start\n\n```bash\nnpm install -g @apralabs/blindfold\nblindfold install        # registers the MCP server with Claude Desktop and Claude Code\n# Restart your AI client\n```\n\nThe package is published scoped (`@apralabs/blindfold`); the command installed on `PATH` is `blindfold`.\n\nOnce registered, Claude will have four new MCP tools for managing credentials.\n\n---\n\n## Library usage\n\nFor most use cases, store credentials through the MCP tool (`credential_store_set`) rather than calling the lower-level API directly. The MCP tool handles the full OOB flow. If you need to drive the flow programmatically:\n\n```typescript\nimport { initBlindfold, collectOobApiKey, decryptPassword, resolveSecureTokens, redactOutput } from 'blindfold';\n\ninitBlindfold({ dataDir: '/var/lib/myapp/blindfold' });\n\n// Collect a secret from the user via OOB side-channel (terminal popup / GUI prompt).\n// Returns { password?: string; fallback?: string; persist?: boolean }\n// `password` is encrypted — call decryptPassword() to get the plaintext.\nconst result = await collectOobApiKey('MY_API_KEY', 'credential_store_set', {\n  prompt: 'Enter your API key',\n});\nif (result.password) {\n  const plaintext = decryptPassword(result.password);\n  // use plaintext...\n} else if (result.fallback) {\n  // User could not open a terminal — handle gracefully\n}\n\n// Later: resolve {{secure.MY_API_KEY}} tokens inside a command string.\n// Returns { resolved: string; credentials: ResolvedCredential[] } | { error: string }\nconst result2 = resolveSecureTokens('curl -H \"Authorization: Bearer {{secure.MY_API_KEY}}\" https://api.example.com');\nif ('error' in result2) throw new Error(result2.error);\nconst { resolved, credentials } = result2;\n// Run `resolved` as a shell command, then scrub secrets from the output:\n// const safeOutput = redactOutput(rawOutput, credentials);\n```\n\nThe MCP server entrypoint is importable separately:\n\n```typescript\nimport { startMcpServer } from 'blindfold/mcp';\nawait startMcpServer();\n```\n\n---\n\n## MCP tool reference\n\n| Tool | Description |\n|------|-------------|\n| `credential_store_set` | Collect a new secret from the user via OOB side-channel and store it |\n| `credential_store_update` | Update an existing credential (rotate secret, change TTL, adjust policy) |\n| `credential_store_delete` | Delete a stored credential by name |\n| `credential_store_list` | List stored credentials (names and metadata only -- no plaintext) |\n\n---\n\n## Standalone vs host-integrated usage\n\nBlindfold's MCP surface covers vault management only: `credential_store_set`,\n`credential_store_list`, `credential_store_update`, and `credential_store_delete`.\nThere is no `resolve_secure` MCP tool. This is intentional.\n\nResolving a `{{secure.NAME}}` token means producing the plaintext credential.\nIf that resolution happened inside an MCP tool response, the plaintext would\nland directly in the LLM's context window -- defeating the entire purpose of\nthe token model.\n\nTo use stored credentials inside an agentic workflow, you need a host\nintegration: an application that imports blindfold as a library and calls\n`resolveSecureTokens` (or `resolveSecureField`) immediately before executing\na command or API call -- keeping the plaintext inside application memory and\nout of the LLM stream.\n\napra-fleet is the reference host integration. Its `execute_command` tool\nresolves `{{secure.NAME}}` tokens just before spawning the subprocess, then\nredacts the output with `redactOutput` before returning results to the model.\n\nWithout a host integration your LLM can store and list credentials but cannot\nresolve them into plaintext. That restriction is deliberate: it is the whole\npoint of the design.\n\n---\n\n## `{{secure.NAME}}` token syntax\n\nPass `{{secure.NAME}}` anywhere you would normally put a secret (command arguments, environment values, API call parameters). Blindfold resolves it just before execution:\n\n```\n# In a shell command:\ndocker login -u myuser -p {{secure.DOCKER_TOKEN}} registry.example.com\n\n# In a URL parameter passed to a tool:\ncurl https://api.example.com/data?key={{secure.API_KEY}}\n```\n\nToken names must match `[a-zA-Z0-9_-]{1,64}`. Unresolved tokens cause an error rather than silently passing an empty value.\n\n---\n\n## CLI reference\n\n| Command | Description |\n|---------|-------------|\n| `blindfold` | Start the MCP server (stdio transport) |\n| `blindfold serve` | Alias for starting the MCP server |\n| `blindfold install` | Register blindfold with Claude Desktop and Claude Code |\n| `blindfold install --for claude` | Register with Claude Desktop only |\n| `blindfold secret --set NAME` | Store a secret interactively |\n| `blindfold secret --set NAME --persist` | Store and persist the secret to disk (encrypted) |\n| `blindfold secret --set NAME -y` | Read secret value from stdin (non-interactive) |\n| `blindfold secret --list` | List stored credentials (names and metadata only) |\n| `blindfold secret --update NAME` | Rotate or update a stored credential |\n| `blindfold secret --update NAME --members LIST` | Restrict credential to comma-separated member list |\n| `blindfold secret --update NAME --ttl SECONDS` | Set credential expiry (TTL in seconds from now) |\n| `blindfold secret --update NAME --allow` | Set network policy to allow |\n| `blindfold secret --update NAME --deny` | Set network policy to deny |\n| `blindfold secret --delete NAME` | Delete a named credential |\n| `blindfold secret --delete --all` | Delete all stored credentials (prompts for confirmation) |\n| `blindfold auth --confirm` | Confirm a pending OOB authentication request |\n| `blindfold --version` | Print version |\n| `blindfold --help` | Print usage |\n\n---\n\n## Security model\n\nSecrets are collected through a **Unix Domain Socket (UDS) side-channel** that is inaccessible to the LLM. When a credential is needed, the agent calls `credential_store_set`; blindfold opens a separate terminal or GUI prompt on the user's desktop, collects the secret there, and delivers it back through the UDS — never through the MCP stdio stream that the LLM reads. Persisted credentials are encrypted with **AES-256-GCM** using a randomly generated key stored in a file with owner-only (`0600`) permissions. In-memory (session) credentials are held in a process-local map and never written to disk. Token resolution applies shell escaping by default, preventing injection through crafted credential values.\n\n---\n\n## Requirements\n\n- **Node.js 20+** (the MCP SDK requires Node 18+; Node 20 LTS is recommended)\n- **Platforms**: Linux (primary), macOS (supported), Windows (supported, UDS requires Windows 10 1903+)\n- **Peer dependency**: `@modelcontextprotocol/sdk ^1.27.0` (required when using blindfold as an MCP server; optional for library-only use)\n","readmeFilename":"README.md"}