About JFSecure
JFSecure’s `jfs` is a CLI and MCP server for letting AI agents use vault secrets without exposing their values. Each use requires approval in the running app, while returned output masks secret values.
Key features
- 01Approval for each secret use
- 02Masked command output
- 03Run commands with secret environment variables
- 04Render secrets into templates
- 05List secret and key names
Use cases
- 01Let an agent call a command requiring credentials
- 02Fill a `.env` file from a template
- 03Review and approve a command’s secret access
MCP support
The MCP server exposes tools to list secret names, run commands with secrets, and render templates. It has no tool for retrieving secret values; use requests trigger approval in JFSecure.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEjfs — secrets for AI agents that never see them
jfs is the command line and MCP server of JFSecure, an offline password and
snippet manager. It lets Claude Code, Cursor or any MCP agent use a secret without ever getting it — and you
approve every use in the app.
This repository is the source of jfs itself, so you can read exactly what an agent talks to. It is a thin client:
it sends one JSON request over a local pipe to the running, unlocked JFSecure app and prints the answer. It never
opens vault files, never sees the vault password and has no crypto. (The app is a separate download; jfs ships with it.)

MCP tools
| Tool | What it does | What the agent gets back |
|---|---|---|
list_secrets | Lists secret and key names, with the environment variable each key becomes | Names only |
run_with_secrets | Runs a command with a secret's keys as environment variables (all, some, or one on stdin) | Exit code and output, every value masked as [JFSecure: NAME] |
render_template | Fills {{Secret:key}} in a template and writes the file (e.g. .env) | Which names were filled in |
There is no "get" tool, on purpose. Every use opens an approval window in JFSecure that shows the program, the exact command and the secret: allow once, allow 15 minutes, or deny. For Claude Code a 15-minute approval covers only that command and that secret.
# the agent called run_with_secrets(secret: "github", command: …)
exit code 0
variables set: TOKEN
--- stdout ---
token is [JFSecure: TOKEN]
{"login": "octocat", "plan": {"name": "pro"}}
Set up
- Install JFSecure and open your vault:
brew install theone55/jfsecure/jfsecure(macOS),scoop bucket add jfsecure https://github.com/theone55/scoop-jfsecure; scoop install jfsecure/jfsecure(Windows), or the installer (Windows, macOS, Linux).jfscomes with it: on Windows the app puts it on PATH at its first start (open a new terminal afterwards); on macOS (.dmg) and the Linux AppImage use Settings → Install the jfs command; Homebrew and the .deb install it for you. - Add the MCP server:
claude mcp add --scope user jfsecure -- jfs mcp
Cursor (~/.cursor/mcp.json), Claude Desktop, Windsurf, VS Code — any stdio MCP client:
{ "mcpServers": { "jfsecure": { "command": "jfs", "args": ["mcp"] } } }
More: https://secure.jfolio.org/agents
Also as an MCP bundle (.mcpb, Windows / macOS / Linux) on the releases page, and in the official MCP Registry as io.github.theone55/jfs.
Command line
jfs status is the app running and unlocked
jfs ls [secret|folder] names only, no approval needed
jfs get github/token print a value (approved in the app)
jfs copy github/token to the clipboard, nothing printed
jfs run github -- gh api user run with the secret's keys as env vars ($token → TOKEN); output masked when piped
jfs render .env.tpl -o .env fill {{Secret:key}} into a file
git config --global credential.helper "!jfs git-credential"
Full guide: https://secure.jfolio.org/cli
What it protects — and what it doesn't
- The model never receives a value, so it can't end up in a transcript or a log.
- A prompt-injected agent can only ask; you see the exact command.
- The pipe is your OS user's only, and the app identifies the caller through the OS, not by what it says.
- Masking is a seatbelt, not a wall: a command you approve can still send a value away. Read the command.
Build
cargo build --release # Rust stable; Windows, macOS, Linux
cargo test
The copy here follows each JFSecure release (version in Cargo.toml = the app's version it shipped with).
Issues and questions are welcome here.
MIT License.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.