mcp-elicitation-proxy

Un proxy MCP transparente que añade elicitación para argumentos de herramientas requeridos faltantes, preservando el descubrimiento de herramientas y esquemas ascendentes.

Documentación

mcp-elicitation-proxy

PyPI version Python versions License: MIT

Un proxy MCP transparente que añade elicitación para argumentos de herramienta obligatorios faltantes mientras preserva el descubrimiento y los esquemas de herramientas upstream.

mcp-elicitation-proxy es un proxy MCP de Python independiente construido sobre FastMCP. Preserva el descubrimiento nativo de herramientas upstream mientras añade middleware de llamadas a herramientas para la elicitación de campos obligatorios y el bloqueo de campos obligatorios sensibles.

La regla arquitectónica central es estricta: el descubrimiento upstream permanece nativo. El proxy debe preservar la salida tools/list upstream en lugar de reemplazarla con un envoltorio sintético como call_upstream_tool.

Instalación

Ejecute directamente con uvx:

uvx mcp-elicitation-proxy --config config.yaml

Para desarrollo desde una copia local, use los pasos de configuración de desarrollo a continuación.

Configuración de Desarrollo

uv sync

Ejecute las pruebas:

uv run pytest -q

Lint opcional:

uv run ruff check .

Los artefactos de compilación se pueden producir con uv build. Los resultados locales bajo dist/ no están destinados a ser confirmados.

Configuración

Ejemplo de config.yaml con un upstream HTTP:

proxy:
  name: "mcp-elicitation-proxy"

upstream:
  url: "http://localhost:8001/mcp"

elicitation:
  enabled: true
  fallback_on_unsupported: "structured_error"

policies:
  schema_required:
    enabled: true
  sensitive_required:
    enabled: true

tools:
  search_docs:
    required:
      - query
      - project
    elicit:
      message: "Provide the missing search details."
      fields:
        project:
          type: "string"
          description: "Project or scope to search."

Ejemplo de config.yaml con un upstream basado en comandos:

proxy:
  name: "mcp-elicitation-proxy"

upstream:
  command: "npx"
  args:
    - -y
    - "@modelcontextprotocol/server-everything"

upstream.url y upstream.command son mutuamente excluyentes. Debe configurarse exactamente uno. upstream.args por defecto es una lista vacía y solo es válido con upstream.command. Los upstreams basados en comandos también pueden proporcionar variables de entorno de cadena con upstream.env.

Ejecute el proxy:

uv run mcp-elicitation-proxy --config config.yaml

También puede proporcionar la ruta de configuración mediante MCP_ELICITATION_PROXY_CONFIG.

Configuración del Cliente MCP

Al configurar un cliente MCP, use mcp-elicitation-proxy como paquete y comando CLI. El alias local del servidor del cliente MCP puede ser más corto; el alias recomendado es elicitation-proxy.

{
  "mcpServers": {
    "elicitation-proxy": {
      "command": "uvx",
      "args": [
        "mcp-elicitation-proxy",
        "--config",
        "/path/to/config.yaml"
      ]
    }
  }
}

En este ejemplo, elicitation-proxy es solo el alias local del servidor del cliente. mcp-elicitation-proxy sigue siendo el nombre del paquete PyPI y el comando CLI. Estos nombres no necesitan coincidir. Si se desea, el nombre del propio servidor MCP del proxy también se puede configurar por separado en YAML:

proxy:
  name: "elicitation-proxy"

Invariantes de Descubrimiento

  • Las herramientas upstream permanecen visibles en tools/list nativo.
  • El proxy no registra un call_upstream_tool genérico.
  • Los nombres de las herramientas no tienen prefijos como upstream_.
  • Los nombres de las herramientas, las descripciones y los esquemas de entrada permanecen con los valores upstream a menos que una característica explícita de descubrimiento futuro cambie ese contrato.

El servidor upstream se delega al proxy nativo de FastMCP mediante fastmcp.server.create_proxy(...).

Campos Obligatorios y Elicitación

schema_required utiliza campos nativos de JSON Schema required del upstream. Las entradas tools.<tool_name>.required por herramienta se añaden en tiempo de ejecución solo para la validación de tools/call. Los campos obligatorios del esquema mantienen su orden original, y luego se añaden los campos configurados sin duplicados.

Cuando elicitation.enabled es true, los campos obligatorios no sensibles faltantes pueden solicitarse con la capacidad de elicitación MCP del cliente y fusionarse en los argumentos originales antes de reenviarlos al upstream. Si la elicitación está deshabilitada, no es compatible, se rechaza, se cancela o falla, el proxy devuelve un resultado estructurado en lugar de llamar a la herramienta upstream.

La política sensitive_required se ejecuta antes de la elicitación normal de campos obligatorios. Si un campo obligatorio faltante parece ser una credencial o secreto, el proxy bloquea la elicitación en modo formulario y devuelve un resultado estructurado tool_call_blocked. La entrada explícita completa aún se reenvía.

Los ajustes ambiguous_if y confirm_if se analizan para una configuración compatible con versiones futuras, pero las políticas avanzadas de ambigüedad, confirmación y basadas en LLM no están implementadas en v0.1.0.

Prueba de Humo Manual con MCP Inspector

Hay una prueba manual repetible disponible con MCP Inspector y el servidor de referencia oficial @modelcontextprotocol/server-everything.

npx @modelcontextprotocol/inspector -- uv run mcp-elicitation-proxy --config examples/manual-everything.config.yaml

Esta prueba verifica el inicio del upstream basado en comandos, el descubrimiento nativo de herramientas upstream, el reenvío, la elicitación de campos obligatorios faltantes, el bloqueo de campos sensibles obligatorios y la propagación de upstream.env.

Comprobaciones esperadas de alto nivel:

  • echo es visible como herramienta upstream;
  • call_upstream_tool no está presente;
  • los nombres de las herramientas no tienen el prefijo upstream_;
  • llamar a echo con un message completo se reenvía;
  • llamar a echo sin message activa la elicitación;
  • se utiliza el texto de elicitación configurado de examples/manual-everything.config.yaml;
  • marcar un campo obligatorio faltante como sensible bloquea la elicitación;
  • la variable de entorno configurada es visible para la herramienta de entorno upstream.

Consulte docs/manual-inspector-test.md para más detalles.

Estado

v0.1.0 es la primera línea base lista para uso público. Incluye un proxy FastMCP de un solo upstream, preservación del descubrimiento nativo, elicitación de campos obligatorios, bloqueo de campos obligatorios sensibles, inicio de upstream basado en comandos, configuración YAML y cobertura automatizada para los principales invariantes del proxy.