mcp-elicitation-proxy

Um proxy MCP transparente que adiciona elicitação para argumentos de ferramenta obrigatórios ausentes, preservando a descoberta de ferramentas upstream e os esquemas.

Documentação

mcp-elicitation-proxy

PyPI version Python versions License: MIT

Um proxy MCP transparente que adiciona elicitação para argumentos obrigatórios ausentes de ferramentas, preservando a descoberta e os esquemas da ferramenta upstream.

mcp-elicitation-proxy é um proxy MCP Python independente construído sobre FastMCP. Ele preserva a descoberta nativa de ferramentas upstream, adicionando middleware de chamada de ferramenta para elicitação de campos obrigatórios e bloqueio de campos obrigatórios sensíveis.

A regra arquitetural central é estrita: a descoberta upstream permanece nativa. O proxy deve preservar a saída tools/list do upstream em vez de substituí-la por um wrapper sintético como call_upstream_tool.

Instalação

Execute diretamente com uvx:

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

Para desenvolvimento a partir de um checkout local, use as etapas de configuração de desenvolvimento abaixo.

Configuração de Desenvolvimento

uv sync

Execute os testes:

uv run pytest -q

Lint opcional:

uv run ruff check .

Artefatos de build podem ser produzidos com uv build. Saídas locais em dist/ não devem ser commitadas.

Configuração

Exemplo de config.yaml com um 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."

Exemplo de config.yaml com um upstream baseado em comando:

proxy:
  name: "mcp-elicitation-proxy"

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

upstream.url e upstream.command são mutuamente exclusivos. Exatamente um deve ser configurado. upstream.args tem como padrão uma lista vazia e é válido apenas com upstream.command. Upstreams baseados em comando também podem fornecer variáveis de ambiente de string com upstream.env.

Execute o proxy:

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

Você também pode fornecer o caminho do config via MCP_ELICITATION_PROXY_CONFIG.

Configuração do Cliente MCP

Ao configurar um cliente MCP, use mcp-elicitation-proxy como o pacote e o comando CLI. O alias do servidor MCP local do cliente pode ser mais curto; o alias recomendado é elicitation-proxy.

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

Neste exemplo, elicitation-proxy é apenas o alias do servidor local do cliente. mcp-elicitation-proxy permanece como o nome do pacote PyPI e o comando CLI. Esses nomes não precisam corresponder. Se desejado, o próprio nome do servidor MCP do proxy também pode ser definido separadamente em YAML:

proxy:
  name: "elicitation-proxy"

Invariantes de Descoberta

  • As ferramentas upstream permanecem visíveis no tools/list nativo.
  • O proxy não registra um call_upstream_tool genérico.
  • Os nomes das ferramentas não são prefixados com valores como upstream_.
  • Os nomes, descrições e esquemas de entrada das ferramentas permanecem os valores upstream, a menos que um recurso explícito de descoberta futura altere esse contrato.

O servidor upstream é delegado ao proxy nativo do FastMCP via fastmcp.server.create_proxy(...).

Campos Obrigatórios e Elicitação

schema_required usa campos nativos de required do JSON Schema upstream. Entradas tools.<tool_name>.required por ferramenta são adicionadas em tempo de execução apenas para validação tools/call. Os campos obrigatórios do esquema mantêm sua ordem original, e os campos configurados são anexados sem duplicatas.

Quando elicitation.enabled é true, campos obrigatórios ausentes não sensíveis podem ser solicitados com o recurso de elicitação MCP do cliente e mesclados nos argumentos originais antes do encaminhamento upstream. Se a elicitação estiver desabilitada, não for suportada, for recusada, cancelada ou falhar, o proxy retorna um resultado estruturado em vez de chamar a ferramenta upstream.

A política sensitive_required é executada antes da elicitação normal de campos obrigatórios. Se um campo obrigatório ausente parecer uma credencial ou segredo, o proxy bloqueia a elicitação em modo de formulário e retorna um resultado estruturado tool_call_blocked. A entrada explícita completa ainda é encaminhada.

As configurações ambiguous_if e confirm_if são analisadas para configuração compatível com versões futuras, mas políticas avançadas de ambiguidade, confirmação e baseadas em LLM não são implementadas em v0.1.0.

Teste de Fumaça Manual com MCP Inspector

Um teste manual repetível está disponível com o MCP Inspector e o servidor de referência oficial @modelcontextprotocol/server-everything.

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

Este teste verifica a inicialização do upstream baseado em comando, a descoberta nativa de ferramentas upstream, o encaminhamento, a elicitação de campos obrigatórios ausentes, o bloqueio de campos obrigatórios sensíveis e a propagação de upstream.env.

Verificações esperadas de alto nível:

  • echo é visível como uma ferramenta upstream;
  • call_upstream_tool não está presente;
  • os nomes das ferramentas não são prefixados com upstream_;
  • chamar echo com um message completo é encaminhado;
  • chamar echo sem message aciona a elicitação;
  • o texto de elicitação configurado de examples/manual-everything.config.yaml é usado;
  • marcar um campo obrigatório ausente como sensível bloqueia a elicitação;
  • a variável de ambiente configurada é visível para a ferramenta de ambiente upstream.

Veja docs/manual-inspector-test.md para detalhes.

Status

v0.1.0 é a primeira linha de base pronta para o público. Inclui um proxy FastMCP de upstream único, preservação de descoberta nativa, elicitação de campos obrigatórios, bloqueio de campos obrigatórios sensíveis, inicialização de upstream baseado em comando, configuração YAML e cobertura automatizada para os principais invariantes do proxy.