@lvasko/local-secret-store
v0.2.2
Published
Windows-focused local secret store for MCP tools and other local automation
Readme
Local Secret Store
Windows-focused local secret store for values that multiple MCP servers need to read at runtime, such as Jira PATs, Tempo tokens, Confluence PATs, API keys, or other per-user secrets.
The values are stored under the current Windows user profile and protected with DPAPI, so the file contents are not plain text.
Requirements
- Windows
- Node.js
- PowerShell 7 or Windows PowerShell
The package automatically tries these PowerShell executables in order:
PWSH_PATH, if you set it explicitlypwsh.exe- standard Windows PowerShell
Storage
Secrets are stored under:
C:\Users\<user>\.codex\secrets\local-secret-storeEach secret is stored as a DPAPI-protected blob plus a small metadata file.
CLI
Primary usage is through npx:
npx @lvasko/local-secret-store@latest set jira-prod-pat "your-token-here"
npx @lvasko/local-secret-store@latest get jira-prod-pat --preview
npx @lvasko/local-secret-store@latest list
npx @lvasko/local-secret-store@latest delete jira-prod-patClipboard-based setup:
npx @lvasko/local-secret-store@latest set-from-clipboard confluence-client-a-pat --clear-clipboard
npx @lvasko/local-secret-store@latest set-from-clipboard tempo-prod-token --replace-clipboard "Secret automatically removed from clipboard"
npx @lvasko/local-secret-store@latest set-from-clipboard api-key --trim-endset-from-clipboard reads the current clipboard value, stores it, and then optionally clears or replaces the clipboard.
get prints the raw secret to stdout. For manual checks, prefer --preview:
npx @lvasko/local-secret-store@latest get jira-prod-pat --previewIf you need the raw secret for scripting, use:
npx @lvasko/local-secret-store@latest get jira-prod-patIf you are developing from a local checkout instead of npx, the equivalent command is:
node .\src\cli.js get jira-prod-pat --previewSmoke Test
To verify the package works on a fresh Windows machine:
npx @lvasko/local-secret-store@latest smokeor from the repo checkout:
npm run --workspace ./packages/local-secret-store smokeThe smoke test verifies:
- PowerShell can be resolved
- DPAPI encryption works
- a temporary secret can be stored, read, listed, and deleted
Quick runtime test that simulates how an MCP server would consume a secret:
node .\src\use-secret-store.js jira-prod-patOr:
$env:SECRET_NAME = "jira-prod-pat"
node .\src\use-secret-store.jsLibrary API
Other MCP servers can use the store directly:
import { readSecret, maskSecretValue } from "@lvasko/local-secret-store";
const jiraToken = await readSecret(process.env.JIRA_TOKEN_SECRET_NAME);
console.log(maskSecretValue(jiraToken));Available functions:
storeSecret(name, value, options?)readSecret(name)listSecrets()deleteSecret(name)maskSecretValue(value, options?)readClipboardText()writeClipboardText(value)clearClipboardText(replacementText?)
MCP Usage Example
The secret store is meant to stay outside MCP. Each MCP server only gets a secret name, not the secret itself.
Confluence example:
[mcp_servers.confluence-client]
command = "npx"
args = ["-y", "@lvasko/confluence-rw-mcp@latest"]
[mcp_servers.confluence-client.env]
CONFU_BASE_URL = "https://confluence.client.local"
CONFU_DEPLOYMENT_TYPE = "ON_PREM"
CONFU_CERT_PATH = "C:\\certs\\client-ca.crt"
CONFU_ALLOWED_READ_PAGE_IDS = '["123456","234567"]'
CONFU_ALLOWED_WRITE_PAGE_IDS = '["345678"]'
CONFU_PAT_SECRET_NAME = "confluence-client-a-pat"Jira and Tempo example:
[mcp_servers.jira-client.env]
JIRA_BASE_URL = "https://jira.client.local"
JIRA_TOKEN_SECRET_NAME = "jira-prod-pat"
[mcp_servers.tempo-client.env]
TEMPO_BASE_URL = "https://tempo.client.local"
TEMPO_TOKEN_SECRET_NAME = "tempo-prod-token"The MCP server resolves the secret at runtime:
import { readSecret } from "@lvasko/local-secret-store";
const token = await readSecret(process.env.JIRA_TOKEN_SECRET_NAME);Security Notes
- Do not store raw secrets in Codex config files.
- Do not log the raw secret value.
- The secret file is protected for the current Windows user, but any code running under the same user can still read it.
--clear-clipboardis the safest clipboard option after setup.--replace-clipboardis useful if you want a visible reminder instead of an empty clipboard.
