LABSCO SUMMARY
It refuses to replace the tool list, and that is the point.
Most proxies flatten an upstream server into one generic call tool and lose the schemas; here the invariant is stated and tested — upstream names, descriptions and schemas survive, and no call_upstream_tool is registered. Read the version line before relying on the advanced policies: ambiguous_if and confirm_if are parsed for forward compatibility but are not implemented in v0.1.0, so what works today is required-field elicitation and sensitive-field blocking.
What it is
A transparent MCP proxy. It forwards an upstream server's tools untouched, and adds one behaviour on the call path: when a required argument is missing, it elicits that value from the user through the client, merges it into the arguments, and only then calls upstream.
What you get
- Upstream tools kept exactly as they are — same names, descriptions and input schemas, visible in native
tools/list, with no synthetic wrapper tool and noupstream_prefix - Missing required fields requested from the user through the client's MCP elicitation capability, with your own prompt copy per tool
- A definite outcome when elicitation is unavailable: if the client cannot elicit, or the user declines or cancels, it returns a structured result instead of calling upstream with holes
- Required fields from two sources: the upstream JSON Schema
requiredlist, plus per-tool extras declared in YAML for call-time validation, in schema order with the configured ones appended - A credential guard that runs first — a missing required field that looks like a secret blocks form-mode elicitation and returns a
tool_call_blockedresult, while complete explicit input is still forwarded - Either kind of upstream: an HTTP
upstream.url, or aupstream.commandwith args and string environment variables
Requirements
Python via uvx mcp-elicitation-proxy --config config.yaml; the config path can also come from MCP_ELICITATION_PROXY_CONFIG. The YAML needs exactly one of upstream.url or upstream.command — they are mutually exclusive — and carries the elicitation, policies and per-tool tools blocks. The client entry is the same uvx command; the README suggests the shorter local alias elicitation-proxy. A repeatable smoke test against @modelcontextprotocol/server-everything is documented with MCP Inspector. This is version 0.1.0.
Setup effort
One command — uvx mcp-elicitation-proxy --config config.yaml
USE CASES
01
Stopping a tool call that is missing an argument
Let the proxy ask the user for the missing field instead of forwarding an incomplete call upstream.
02
Requiring a field the upstream schema does not
Declare it per tool in the YAML so call-time validation catches it even though upstream marks it optional.
03
Keeping secrets out of a prompt box
Let the sensitive-field policy block elicitation for credential-shaped arguments and return a structured refusal.
04
Adding elicitation to a server you cannot modify
Point the proxy at the existing HTTP or command-launched server and leave its tool surface untouched.
BEFORE YOU INSTALL
What to know first
Requires
uvx on PATH
INSTALLATION
Connect your client
Server setup
Configuration file
JSON
{
"mcpServers": {
"elicitation-proxy": {
"command": "uvx",
"args": [
"mcp-elicitation-proxy",
"--config",
"<YOUR_PATH_TO_CONFIG>"
]
}
}
}<YOUR_PATH_TO_CONFIG> is the full path of your config.yaml — the file that names the upstream MCP server the proxy sits in front of (an HTTP url or a command, as in the project's examples). You can set MCP_ELICITATION_PROXY_CONFIG instead.
uvx
TERMINAL
uvx mcp-elicitation-proxy --config config.yaml