MCPTap can:
- Route traffic to OpenRouter or Requesty
- Force all requests to use a configured model
- Use a different model for plan mode
- Pin or restrict OpenRouter provider routing
- Intercept selected MCP tool calls
- Execute real MCP tools locally through stdio
- Log upstream requests and responses
- Run a configurable hook before client tool calls to allow or block them
- Rewrite tool call arguments via the hook (e.g. wrap shell commands with RTK for token compression)
- Serve simple UI interface for debugging requests
- Expose a local health endpoint
AI client
│
│ OpenAI-compatible request
▼
MCPTap
│ rewrites payload: forced model, plan-mode switching,
│ provider pinning, per-model instructions, tool injection
│
│ rewritten / routed request
▼
OpenRouter or Requesty
│
│ model response
▼
MCPTap
│
├─ model calls an intercepted MCP tool:
│ MCPTap calls the MCP server locally, feeds the tool
│ result back to the model, and loops to the upstream again
│
├─ model calls a client tool and the tool-call hook is enabled:
│ MCPTap runs the hook script —
│ allow: returns the saved model response to the client
│ block: feeds the block message back to the model,
│ then passes through the next response once
│
└─ final response (no intercepted or client tool calls pending)
▼
AI client
MCPTap is designed for workflows like:
- using Codex/Hermes Agent CLI through OpenRouter or Requesty,
- forcing a cheaper model for normal work and a stronger model for planning,
- giving a weaker model access to a stronger “expert” model through an MCP tool,
- disabling access to sensitive files,
- hiding complex MCP orchestration from the client,
- debugging model/tool traffic,
- testing provider fallback behavior,
- controlling OpenRouter provider selection.
Install the latest release:
curl -fsSL https://github.com/PCODE-pl/MCPTap/releases/latest/download/setup.sh | shIf curl is not available:
wget -qO- https://github.com/PCODE-pl/MCPTap/releases/latest/download/setup.sh | shThe installer creates a local Python virtual environment, installs MCPTap files, copies example configuration files, and tries to install a user service.
Default paths:
~/.local/share/mcptap application files and logs database
~/.local/bin/mcptap executable wrapper
~/.config/mcptap configuration files
To build and install the LD_PRELOAD file-block library during installation, pass --with-file-block:
sh setup.sh --with-file-blockOr when piping from curl/wget:
curl -fsSL https://github.com/PCODE-pl/MCPTap/releases/latest/download/setup.sh | sh -s -- --with-file-blockThis option is Linux-only. It requires a C compiler (gcc or cc), make, and C library headers (libc-dev/glibc-devel). The installer checks for these tools and reports installation instructions if any are missing.
When --with-file-block is used on a new installation (where proxy.env does not already exist), the installer:
- Builds
libmcptap_fileblock.sofrom thefile_block/source directory. - Installs it to
~/.local/lib/libmcptap_fileblock.so.
On subsequent runs with --with-file-block, the library is rebuilt and reinstalled, but proxy.env is left untouched (to preserve user edits). Use --force-config to reset proxy.env to defaults and re-wire the library path.
On macOS, --with-file-block is silently skipped (the file-block library is not yet supported on macOS).
After installation, start Codex with the library loaded:
LD_PRELOAD=~/.local/lib/libmcptap_fileblock.so codexHermes Agent can be started in the same way:
LD_PRELOAD=~/.local/lib/libmcptap_fileblock.so hermesSee the Tool-call hook section for details on how blocked_files from the hook are enforced by this library.
After installation, edit the files in:
~/.config/mcptap/Important files:
proxy.env main MCPTap configuration
openrouter.env OpenRouter model and API key configuration
requesty.env Requesty model and API key configuration
meta.env Meta model and API key configuration
nano-gpt.env NanoGPT model and API key configuration
llmtr.env LLMTR model and API key configuration
[...].env All other providers model and API key configuration
mcp-intercept.yaml optional MCP tool interception configuration
per-model.yaml optional per-model instruction overrides
use_tool_hook.py optional tool-call hook script (runs before client tool calls)
Edit:
~/.config/mcptap/proxy.envExample for OpenRouter:
MCPTAP_UPSTREAM_PROVIDER=openrouter
MCPTAP_LISTEN_HOST=127.0.0.1
MCPTAP_LISTEN_PORT=8787Example for Requesty:
MCPTAP_UPSTREAM_PROVIDER=requesty
MCPTAP_LISTEN_HOST=127.0.0.1
MCPTAP_LISTEN_PORT=8787Supported upstream providers:
302ai
abacus
abliteration-ai
above
agentrouter
agnes
ai-router
aiand
aihubmix
ainetcafe
aixy
aki-io
alibaba
alibaba-cn
alibaba-coding-plan
alibaba-coding-plan-cn
alibaba-token-plan
alibaba-token-plan-cn
amazon-bedrock
ambient
amd
anthropic
anyapi
arcee
atomic-chat
auriko
azure
azure-cognitive-services
bailing
baseten
berget
blueclaw
bothub
cerebras
chutes
clarifai
claudinio
cline-pass
cloudferro-sherlock
cloudflare-ai-gateway
cloudflare-workers-ai
cohere
coralbricks
cortecs
crof
crossmodel
crusoe
daoxe
databricks
deepinfra
deepseek
digitalocean
dinference
drun
ebcloud
echo
edenai
empiriolabs
evroc
fastrouter
fireworks-ai
freemodel
friendli
frogbot
github-copilot
gmicloud
google
google-vertex
google-vertex-anthropic
greenpt
groq
helicone
hetzner
hpc-ai
huggingface
hyper
iflowcn
impossibl
inception
inceptron
inco
infer
inference
inferx
infomaniak
io-net
iteracompute
jalapeno
jiekou
kenari
kilo
klokintegration
kosmik
kuae-cloud-coding-plan
lilac
llama
llmgateway
llmgateway-providers
llmtech
llmtr
lmstudio
longcat
lucidquery
lynkr
meganova
melious
merge-gateway
meta
minimax
minimax-cn
minimax-cn-coding-plan
minimax-coding-plan
mistral
mixlayer
moark
modal
model-oracle-ai
modelis
modelscope
moonshotai
moonshotai-cn
morph
nan
nano-gpt
nearai
nebius
neon
neosmith
neuralwatt
nova
novita-ai
nvidia
oci
ofox
ollama-cloud
openai
opencode
opencode-go
openreason
openrouter
opper
orcarouter
ovhcloud
pendra
perplexity
perplexity-agent
pioneer
poe
poolside
privatemode-ai
qihang-ai
qiniu-ai
qvac
regolo-ai
requesty
routing-run
runinfra
sakana
salad-cloud
sap-ai-core
sarvam
scaleway
scnet-token-plan
scx-ai
sensenova
siliconflow
siliconflow-cn
snowflake-cortex
stackit
standardcompute
stepfun
stepfun-ai
stepfun-step-plan
subconscious
submodel
synthetic
tencent-coding-plan
tencent-token-plan
tencent-tokenhub
tensorx
the-grid-ai
thinkingmachines
tinfoil
togetherai
tokengo
tokenrouter
trustedrouter
umans-ai
umans-ai-coding-plan
unorouter
upstage
v0
vancine
venice
vercel
vispark
vivgrid
volcengine
volcengine-coding-plan
vultr
wafer.ai
wallaby
wandb
watsonx
xai
xiaomi
xiaomi-token-plan-ams
xiaomi-token-plan-cn
xiaomi-token-plan-sgp
xpersona
zai
zai-coding-plan
zeldoc
zenifra
zenmux
zhipuai
zhipuai-coding-plan
For OpenRouter, edit:
~/.config/mcptap/openrouter.envExample:
MCPTAP_API_KEY=sk-or-v1-...
MCPTAP_MODEL=deepseek/deepseek-v4-flash:floor
MCPTAP_PLAN_MODE_MODEL=z-ai/glm-5.2:floorFor Requesty, edit:
~/.config/mcptap/requesty.envExample:
MCPTAP_API_KEY=rqsty-sk-...
MCPTAP_MODEL=nvidia/nemotron-3-nano-30b-a3b:free
MCPTAP_PLAN_MODE_MODEL=zai/glm-5.2:floorFor Meta, edit:
~/.config/mcptap/meta.envFor NanoGPT, edit:
~/.config/mcptap/nano-gpt.envExample:
MCPTAP_API_KEY=sk-nano-...
MCPTAP_MODEL=openai/gpt-5.6-sol
MCPTAP_PLAN_MODE_MODEL=openai/gpt-5.6-solFor LLMTR, edit:
~/.config/mcptap/llmtr.envExample:
MCPTAP_API_KEY=llmtr-...
MCPTAP_MODEL=zai/glm-5.2
MCPTAP_PLAN_MODE_MODEL=zai/glm-5.2
MCPTAP_USE_CHAT_COMPLETIONS=trueExample Codex configuration:
model_provider = "mcptap"
model = "openai/gpt-5.5"
model_context_window = 1000000
# This value must be different from MCPTAP_PLAN_MODE_TRIGGER.
# For this reasoning effort, MCPTap will use MCPTAP_MODEL
# from the selected provider env file.
model_reasoning_effort = "xhigh"
# This value must match MCPTAP_PLAN_MODE_TRIGGER.
# For this reasoning effort, MCPTap will use MCPTAP_PLAN_MODE_MODEL
# from the selected provider env file.
plan_mode_reasoning_effort = "max"
model_supports_reasoning_summaries = false
web_search = "live"
[model_providers.mcptap]
name = "routed-via-mcptap"
base_url = "http://127.0.0.1:8787/v1"
wire_api = "responses"
http_headers = { "X-Title" = "OpenAI Codex" }
supports_websockets = false
[memories]
extract_model = "openai/gpt-5.5"
consolidation_model = "openai/gpt-5.5"Example Hermes Agent configuration:
model:
[...]
provider: custom
base_url: http://127.0.0.1:8787/v1
api_mode: codex_responses- 1. Model forcing
- 2. Plan mode model
- 3. OpenRouter provider controls
- 4. Requesty notes
- 5. MCP tool interception
- 6. Per-model instructions
- 7. Tool-call hook
- 8. Session tracking
- 9. UI interface
- 10. Logging
Start:
systemctl --user start mcptap.serviceRestart:
systemctl --user restart mcptap.serviceStop:
systemctl --user stop mcptap.serviceStatus:
systemctl --user status mcptap.serviceLogs:
journalctl --user -u mcptap.service -fMCPTap is installed as a launchd user service:
pl.pcode.mcptap
Restart:
launchctl kickstart -k "gui/$(id -u)/pl.pcode.mcptap"Logs:
tail -f ~/Library/Logs/mcptap.log ~/Library/Logs/mcptap.error.logIf the service is not installed, run MCPTap manually:
mcptapor:
~/.local/bin/mcptapCheck it with:
curl http://127.0.0.1:8787/healthSee docs/TROUBLESHOOTING.md for common issues and their solutions.
If MCPTAP_LOG_FILE is enabled, consider:
LOG_FILE_REDACT_HEADERS=1MCP tools are executed locally with the permissions of the MCPTap process.
See docs/DEVELOPMENT.md for development setup, running locally, and linting configuration.
The list of issues that MCPTap addresses (at least partially): docs/ISSUES.md.
| Variable | Default Value | Description |
|---|---|---|
MCPTAP_UPSTREAM_PROVIDER |
required | openrouter, requesty, meta, nano-gpt, or llmtr. |
MCPTAP_LISTEN_HOST |
127.0.0.1 |
Local host/interface to bind. |
MCPTAP_LISTEN_PORT |
8787 |
Local port to listen on. |
MCPTAP_OPENROUTER_PROVIDER |
empty | Optional OpenRouter provider slug. |
MCPTAP_OPENROUTER_DISABLE_PROVIDER_FALLBACKS |
1 |
Disable OpenRouter provider fallback when true. |
MCPTAP_PLAN_MODE_TRIGGER |
max |
Reasoning effort value that activates plan mode model. |
MCPTAP_PLAN_MODE_MAX_INPUT_SIZE |
300000 |
Maximum accepted input size for plan mode. |
MCPTAP_INTERCEPT_YAML |
empty | MCP interception YAML or @/path/to/file.yaml. |
MCPTAP_INTERCEPT_MAX_ITERATIONS |
8 |
Maximum hidden tool-call loop iterations. |
MCPTAP_INTERCEPT_TOOL_TIMEOUT |
120 |
Timeout for one MCP tool call, in seconds. |
MCPTAP_PER_MODEL_YAML |
empty | Per-model instruction YAML or @/path/to/file.yaml. |
MCPTAP_USE_TOOL_HOOK |
empty | Path to a Python hook script run before client tool calls. |
MCPTAP_USE_TOOL_HOOK_TIMEOUT |
30 |
Timeout for the hook script, in seconds. |
MCPTAP_USE_TOOL_HOOK_SYNTHETIC_TOOL |
get_goal |
Synthetic tool name to inject before the hook. Empty = direct mode. |
MCPTAP_PER_SESSION_DIR |
/tmp/mcptap/per_session |
Directory for per-session control files. |
MCPTAP_LOG_LEVEL |
INFO |
Python logging level. |
MCPTAP_LOG_FILE |
empty | Optional communication log file path. |
LOG_FILE_REDACT_HEADERS |
0 |
Redact sensitive headers in communication logs when true. |
| Variable | Required | Description |
|---|---|---|
MCPTAP_API_KEY |
yes | Upstream provider API key. |
MCPTAP_MODEL |
yes | Default forced model. |
MCPTAP_PLAN_MODE_MODEL |
yes | Forced model used when plan mode is active. |
MCPTAP_USE_CHAT_COMPLETIONS |
no | Convert Responses requests to Chat Completions for providers/models that require it. |
| Variable | Default Value | Description |
|---|---|---|
MCPTAP_FB_DIR |
/tmp/mcptap/per_session |
Directory for per-session control files. |
MCPTAP_FB_INTERPRETERS |
see file_block.c |
Colon-separated list of basenames treated as interpreters. |
MCPTAP_FB_ESCALATORS |
see file_block.c |
Colon-separated list of argv[0] basenames treated as privilege-escalators. |
MCPTAP_FB_DISABLE_ESCALATOR_CHECK |
unset | When set to 1, the surgical escalator+interpreter layer is disabled entirely (only the path-scan layer remains active). |