New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@twiceshy/mcp-proxy

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@twiceshy/mcp-proxy

MCP proxy with repeat-action guard

latest
Source
npmnpm
Version
0.1.2
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

@twiceshy/mcp-proxy

The Twiceshy proxy is an MCP server that stands in front of your existing MCP servers and stops an AI agent from repeating a money-moving action.

The Kola scenario, in four lines:

  • Kola runs a food delivery app in Lagos. His agent calls a slow payment server to refund Ife 1,500 naira.
  • The payment server commits the charge and then delays its reply past the timeout.
  • The agent retries through the proxy, but Twiceshy has the action in doubt and blocks it.
  • The late reply arrives, Twiceshy upgrades the record to succeeded, and Ife is charged exactly once.

30 second install and use

Add one entry to your MCP client config:

{
  "mcpServers": {
    "twiceshy": {
      "command": "npx",
      "args": ["-y", "@twiceshy/mcp-proxy", "--config", "/path/to/twiceshy.config.json"]
    }
  }
}

Then write twiceshy.config.json:

{
  "$schema": "https://unpkg.com/@twiceshy/mcp-proxy/schema.json",
  "store": { "type": "sqlite", "path": "~/.twiceshy/actions.db" },
  "window": "10m",
  "onStoreFailure": "closed",
  "toolNaming": "prefix",
  "mcpServers": {
    "paystack": {
      "command": "npx",
      "args": ["-y", "paystack-mcp"],
      "env": { "PAYSTACK_SECRET_KEY": "${PAYSTACK_SECRET_KEY}" },
      "tools": {
        "create_refund": { "guard": true, "keyFields": ["transaction", "amount"] },
        "list_transactions": { "guard": false }
      }
    }
  }
}

Check the config before your agent uses it:

npx -y @twiceshy/mcp-proxy doctor --config /path/to/twiceshy.config.json

Real output from the runnable example in this repository:

Store    sqlite  ./.twiceshy/actions.db  0 records in doubt

counter       connected   3 tools
  create_charge   GUARDED    (config: guard true)
  get_count       open       (config: guard false)
  upsert          open       (annotation: idempotentHint (trusted))

1 of 1 server connected. 1 tool guarded, 2 open. 0 warnings.

doctor starts every downstream server, lists every tool as GUARDED or open with the reason, and exits 1 when any server fails. It always shuts down the servers it started.

A runnable version of this setup lives in examples/proxy-claude-config. Run it with pnpm --filter @twiceshy/example-proxy-claude-config run doctor.

Concepts

  • MCP: Model Context Protocol, the standard way agents connect to outside tools.
  • Proxy: a process that speaks MCP to the agent on one side and to your real servers on the other side.
  • Downstream server: a real MCP server behind the proxy, for example a Paystack server or a calendar server.
  • Guarded tool: a tool the proxy protects with the Twiceshy guard.
  • Open tool: a tool the proxy forwards untouched, for example a read-only tool.
  • Annotations: hints a tool can carry, such as readOnlyHint or idempotentHint. Twiceshy treats them as hints, not guarantees.
  • Duplicate result: the stored result, which was redacted before storage, plus a note under _meta["dev.twiceshy/outcome"]. A visible text line explains what happened. The note says resultRedacted: true when any field was replaced, and when storeResult: false kept no result the duplicate is a short text summary instead.
  • Blocked result: a tool error with isError: true that tells the agent what happened, why, and what to do next. The proxy never sends a protocol error for a block.

Which tools are guarded

The first rule that gives an answer wins:

  • Your config: guard: true or guard: false.
  • Tool annotations: readOnlyHint: true means open. idempotentHint: true means open while trustIdempotentHint is true.
  • Default: guarded. An unknown tool is protected until you say otherwise.

doctor shows the reason for every decision.

Configuration reference

Global options:

OptionDefaultWhat it does
storerequired{ "type": "sqlite", "path": "~/.twiceshy/actions.db" } or { "type": "memory" }.
window'10m'How long a finished action counts as a duplicate.
retention'7d'How long records are kept for audit.
onStoreFailure'closed''closed' refuses guarded calls when the store is down. 'open' runs them unprotected and emits guard-bypassed.
toolNaming'prefix''prefix' exposes server__tool. 'none' passes names through and fails when two servers collide.
trustIdempotentHinttrueTrusts the idempotentHint annotation.
annotateDuplicatestrueAdds a visible text line to duplicate results.
exposeRecentActionsfalseAdds the read-only twiceshy_recent_actions tool.
mcpServersrequiredOne entry per downstream server.

Server options:

OptionWhat it does
command and argsStarts a local server over stdio.
urlConnects to a remote server over Streamable HTTP.
envExtra environment variables for the child process. ${VAR} reads from the environment. A missing variable is a config error.
cwdWorking directory for the child process. ~ expands to your home folder.
toolsPer-tool options, keyed by the downstream tool name.

Per-tool options:

OptionWhat it does
guardtrue or false overrides the annotation rules.
keyFieldsThe argument fields that define the action.
ignoreFieldsUsed when keyFields is not set.
normalizePer field: number, trim, lowercase, or lowercase-trim.
timeoutMsTime limit for this tool. A timeout becomes IN_DOUBT.
treatToolErrorsAsDefiniteTreats a tool result with isError: true as a definite failure instead of in doubt.
storeResultfalse stores no result at all; a duplicate then returns a short text summary saying the action already ran.

CLI

This package installs the twiceshy command. If you have not installed it, run every command in the table as npx -y @twiceshy/mcp-proxy <command>, for example npx -y @twiceshy/mcp-proxy doctor --config twiceshy.config.json. The core twiceshy library does not include a command-line tool.

CommandWhat it does
twiceshy proxy --config <file>Runs the proxy. This is what your MCP client launches. With no subcommand, the package runs proxy.
twiceshy doctor --config <file>Checks the config, starts every server, lists every tool with its reason, and warns about free-text fields.
twiceshy list [--state IN_DOUBT] [--since 1h]Shows records in a table.
twiceshy show <id>Shows one record in full.
twiceshy resolve <id> --succeeded|--failed --by <name> [--note "..."]A person settles an in-doubt record.
twiceshy allow <fingerprint> --by <name> [--note "..."]A person approves one repeat.
twiceshy purge [--older-than 30d] [--yes]Removes records past retention.

Every command supports --help with an example and --json for machine output. Exit codes: 0 success, 1 error, 2 bad usage. Errors print what, why, and fix on separate lines.

Logs go to stderr as JSON lines. --log-level accepts error, warn, info, or debug. Standard output carries MCP messages only, so the stream stays clean.

At warn and info, a log line carries only an error's class name, Twiceshy code, and classification. The full downstream message appears only at debug, and debug logs may contain text printed by downstream servers, so treat them as sensitive.

A cancellation before the downstream tool is invoked records FAILED_DEFINITE with reason "cancelled before start", which is safe to retry. A cancellation after invocation leaves the record IN_DOUBT. A late result that contradicts a human resolution logs an error-level resolution-conflict event; if the human said "failed" but the action succeeded, the record blocks the next call with IN_DOUBT.

Proxy tools

  • twiceshy_status: read-only. Shows which servers are connected, how many tools are guarded, and how many records are in doubt.
  • twiceshy_recent_actions: read-only, off by default. Lists recent guarded actions with redacted arguments.

No proxy tool can resolve, delete, purge, or approve anything. Those actions belong to a person, through the CLI.

Limits

  • SqliteStore protects one machine only. Agents on several servers need the future Redis or Postgres store.
  • Twiceshy does not forward sampling or elicitation in v1. A downstream server that asks gets UNSUPPORTED_FEATURE, and the message says the feature is planned for v1.1.
  • Annotations are hints. A tool marked idempotentHint: true that is not idempotent runs unguarded unless you set trustIdempotentHint: false or guard: true.

The full list is in Limits.

Guides

License

MIT. Copyright 2026 Joseph Brendan, Dev and Design HQ.

Keywords

mcp

FAQs

Package last updated on 15 Oct 2026

Related posts