FrankfurterMCP

Servidor MCP que atua como interface para a API Frankfurter de dados de câmbio de moedas.

Documentação

Python 3.12+ pytest GitHub commits since latest release PyPI PyPI - Downloads OpenSSF Scorecard

Frankfurter MCP

Frankfurter é uma API útil para taxas de câmbio mais recentes, dados históricos ou séries temporais publicados por fontes como o Banco Central Europeu. Se você precisar acessar a API Frankfurter como ferramentas para agentes de modelos de linguagem expostos através do Model Context Protocol (MCP), o Frankfurter MCP é o que você precisa.

Instalação

Se o seu objetivo é usar as ferramentas disponíveis neste servidor MCP, consulte a subseção uso > cliente abaixo.

O diretório onde você clona este repositório será referido como diretório de trabalho ou WD daqui em diante.

Instale o just para gerenciar tarefas do projeto.

Instale o uv. Para instalar o projeto com suas dependências mínimas em um ambiente virtual, execute o just install no WD. Para instalar todas as dependências não essenciais (que são necessárias para desenvolvimento e testes), execute just install-all em vez disso.

Variáveis de ambiente

A seguir está uma lista de variáveis de ambiente que podem ser usadas para configurar o aplicativo. Um modelo de variáveis de ambiente é fornecido no arquivo .env.template. Observe que os valores padrão listados na tabela abaixo nem sempre são os mesmos do arquivo .env.template.

As seguintes variáveis de ambiente podem ser especificadas, prefixadas com FASTMCP_: HOST, PORT, DEBUG e LOG_LEVEL.

O cliente HTTP subjacente também respeita algumas variáveis de ambiente, conforme documentado na biblioteca HTTPX. Além disso, SSL_CERT_FILE e SSL_CERT_DIR podem ser configurados para usar certificados autoassinados do endpoint da API hospedada ou servidor(es) proxy HTTP(S) intermediário(s).

O Frankfurter MCP armazenará em cache as chamadas à API Frankfurter para melhorar o desempenho. O cache ocorre com duas estratégias diferentes. Para chamadas de API cujas respostas não mudam para determinados parâmetros, por exemplo, consulta de taxa histórica, é usado um cache de menos recentemente usado (LRU). Para chamadas de API cujas respostas mudam, por exemplo, consulta de taxa mais recente, é usado um cache de tempo de vida (TTL) com um tempo de vida padrão definido para 15 minutos. Os parâmetros do cache podem ser ajustados usando as variáveis de ambiente, veja abaixo.

Variável[Valor padrão] e descrição
LOG_LEVEL[INFO] O nível para registro de log. Alterar esse nível também afeta a saída de log de outras bibliotecas dependentes que podem usar a mesma variável de ambiente. Consulte os valores válidos na documentação de registro do Python.
HTTPX_TIMEOUT[5.0] O tempo que o cliente HTTP subjacente deve aguardar, em segundos, por uma resposta da API Frankfurter. A faixa aceitável de valores está entre 5.0 e 60.0.
HTTPX_VERIFY_SSL[True] Esta variável pode ser definida como False para desativar a verificação de certificado SSL, se, por exemplo, você estiver usando um servidor proxy com certificado autoassinado. No entanto, definir isso como False não é recomendado: em vez disso, use as variáveis SSL_CERT_FILE e SSL_CERT_DIR para configurar corretamente os certificados autoassinados.
FAST_MCP_HOST[localhost] Esta variável especifica a qual host o servidor MCP deve se vincular, a menos que o transporte do servidor (veja abaixo) esteja definido como stdio. Observe que executar o servidor para vincular a qualquer IP especificando 0.0.0.0 representa uma ameaça à segurança. Essa configuração só deve ser usada em ambientes de demonstração.
FAST_MCP_PORT[8000] Esta variável especifica em qual porta o servidor MCP deve escutar, a menos que o transporte do servidor (veja abaixo) esteja definido como stdio.
CORS_MIDDLEWARE_ALLOW_ORIGINS["localhost", "127.0.0.1"] Esta variável especifica as origens permitidas de Compartilhamento de Recursos de Origem Cruzada (CORS) para o servidor MCP, a menos que o transporte do servidor (veja abaixo) esteja definido como stdio. Você deve defini-la como "*" explicitamente (e receberá um aviso ao fazer isso) se quiser testar este servidor por transporte HTTP usando o inspetor MCP descrito abaixo.
MCP_SERVER_TRANSPORT[stdio] As opções aceitáveis são stdio, sse ou streamable-http. No entanto, no .env.template, o valor padrão é definido como stdio.
MCP_SERVER_INCLUDE_METADATA_IN_RESPONSE[True] Isso especifica se metadados adicionais serão incluídos na resposta MCP de cada chamada de ferramenta. Os metadados adicionais, por exemplo, incluirão a URL da API do servidor Frankfurter, entre outros, que é usada para obter as respostas.
FRANKFURTER_API_URL[https://api.frankfurter.dev/v1] Se você estiver hospedando a API Frankfurter por conta própria, você deve alterar isso para o endereço do endpoint da API da sua implantação.
LRU_CACHE_MAX_SIZE[1024] O tamanho máximo do cache de menos recentemente usado (LRU) para chamadas de API. A faixa aceitável de valores está entre 128 e 65536.
TTL_CACHE_MAX_SIZE[256] O tamanho máximo do cache de tempo de vida (TTL) para chamadas de API. A faixa aceitável de valores está entre 64 e 16384.
TTL_CACHE_TTL_SECONDS[900] O limite de tempo, em segundos, do cache de tempo de vida (TTL) para chamadas de API. A faixa aceitável de valores está entre 60 e 3600.
UVICORN_LIMIT_CONCURRENCY[100] O número máximo de conexões simultâneas que o servidor aceitará. Isso ajuda a evitar o esgotamento de recursos devido a muitas conexões simultâneas. Aplica-se apenas ao usar transportes HTTP (sse ou streamable-http). A faixa aceitável de valores está entre 10 e 10000.
UVICORN_TIMEOUT_KEEP_ALIVE[60] O tempo limite em segundos para manter conexões ociosas ativas. Conexões ociosas serão fechadas após esse período para liberar recursos. Aplica-se apenas ao usar transportes HTTP (sse ou streamable-http). A faixa aceitável de valores está entre 60 e 300.
UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN[5] O tempo limite em segundos para desligamento gracioso. O servidor aguardará esse tempo para que as conexões ativas sejam concluídas antes de desligar à força. Aplica-se apenas ao usar transportes HTTP (sse ou streamable-http). A faixa aceitável de valores está entre 5 e 60.
RATE_LIMIT_MAX_REQUESTS_PER_SECOND[10.0] O número máximo de solicitações permitidas por segundo usando um algoritmo de balde de tokens. Isso implementa limitação de taxa para evitar abuso da API e garantir alocação justa de recursos. A faixa aceitável de valores está entre 1.0 e 10000.0.
RATE_LIMIT_BURST_CAPACITY[20] A capacidade de rajada para o limitador de taxa, permitindo rajadas curtas de solicitações acima do limite por segundo. Isso fornece flexibilidade para padrões de uso legítimos, ainda protegendo contra altas taxas de solicitação sustentadas. A faixa aceitável de valores está entre 2x e 5x o valor de RATE_LIMIT_MAX_REQUESTS_PER_SECOND.
REQUEST_SIZE_LIMIT_BYTES[102400] O tamanho máximo em bytes para corpos de solicitação HTTP (padrão 100KB). Solicitações que excederem esse limite serão rejeitadas com um código de status 413. Isso evita ataques de esgotamento de memória por cargas úteis grandes. Aplica-se apenas ao usar transportes HTTP (sse ou streamable-http). A faixa aceitável de valores está entre 10240 (10KB) e 524288 (512KB).
DOCKER_TMPFS_SIZE_MB[100] O tamanho em megabytes para o sistema de arquivos temporário (/tmp) ao executar no Docker com sistema de arquivos raiz somente leitura. Esse armazenamento temporário é usado para operações de arquivo em tempo de execução. Aumente esse valor se o aplicativo precisar de mais armazenamento temporário para cache ou processamento de grandes conjuntos de dados. Relevante apenas ao implantar com Docker Compose.

Uso

As subseções a seguir ilustram como executar o Frankfurter MCP como servidor e como acessá-lo a partir de clientes MCP.

Servidor

Ao executar o servidor, você tem a opção de usar o transporte stdio ou opções HTTP (sse ou o mais novo streamable-http).

Usando as configurações padrão e MCP_SERVER_TRANSPORT definido como sse ou streamable-http, o endpoint MCP estará disponível via HTTP em http://localhost:8000/sse para o transporte Server Sent Events (SSE), ou http://localhost:8000/mcp para o transporte HTTP transmissível.

Se você quiser executar o Frankfurter MCP com transporte stdio e os parâmetros padrão, execute os comandos abaixo sem usar o arquivo .env.template.

Servidor com uv

Opcional: Copie o arquivo .env.template para um arquivo .env no WD, para modificar as variáveis de ambiente mencionadas acima, se você quiser usar algo diferente das configurações padrão. Ou, no seu shell, você pode exportar as variáveis de ambiente que deseja modificar.

Execute o seguinte no WD para iniciar o servidor MCP.

uv run frankfurtermcp

Servidor com pip do pacote PyPI

Adicione este pacote do PyPI usando pip em um ambiente virtual (possivelmente gerenciado por uv, pyenv ou conda) e então inicie o servidor executando o seguinte.

Opcional: Adicione um arquivo .env com o conteúdo do arquivo .env.template se desejar modificar os valores padrão das variáveis de ambiente mencionadas acima. Ou, no seu shell, você pode exportar as variáveis de ambiente que deseja modificar.

pip install frankfurtermcp
python -m frankfurtermcp.server

Servidor usando Docker

Há um Dockerfile fornecido neste repositório, local.dockerfile, para containerizar o servidor Frankfurter MCP. Primeiro, faça uma cópia do .env.template para um arquivo .env. Em seguida, modifique as seguintes variáveis no arquivo .env conforme necessário.

  • FASTMCP_HOST: Defina como 0.0.0.0 para permitir acesso externo ao contêiner. Isso é apenas para testes locais e não é recomendado para implantações de produção.
  • CORS_MIDDLEWARE_ALLOW_ORIGINS: Defina como * para permitir acesso externo ao servidor MCP de qualquer origem. Isso é necessário se você quiser testar o servidor usando o MCP Inspector por transporte HTTP e não é recomendado para implantações de produção.

Para construir a imagem, criar o contêiner e iniciá-lo usando Docker Compose, execute o seguinte no WD.

Se você alterar a porta para algo diferente de 8000 em .env, lembre-se de alterar o número da porta em docker-compose.yml.

Nota: A versão mínima do Docker Compose necessária é 2.24.0. Você pode verificar sua versão executando docker compose version. Se você tiver uma versão mais antiga, atualize o Docker Desktop para obter o Docker Compose mais recente. Além disso, o backend deve ser capaz de BuildKit.

docker compose up --build

Para executar em modo destacado (segundo plano), adicione o sinalizador -d:

docker compose up -d --build

Para parar o contêiner:

docker compose down

Para executar o contêiner e usar o servidor local da API Frankfurter, execute o seguinte comando. Anexe o sinalizador -d para executar em modo destacado. Verifique o arquivo local_api.env.template para especificar as variáveis de ambiente opcionais usadas pelo servidor local da API.

Nota: Ao iniciar pela primeira vez, a API Frankfurter local pode precisar de algum tempo para buscar taxas de câmbio atualizadas. Para execuções subsequentes, a API Frankfurter local usará dados em cache e deve iniciar mais rápido, embora ainda busque as taxas mais recentes.

FRANKFURTER_API_URL=http://frankfurter_api:8080/v1 docker compose --profile local_api up --build frankfurtermcp frankfurter_api

Para parar o grupo de contêineres criado com o perfil local_api, execute o seguinte comando.

docker compose --profile local_api down

O arquivo docker-compose.yml inclui endurecimento de segurança com sistema de arquivos somente leitura (quando relevante), capacidades removidas e limites de recursos.

Nota: O servidor local da API é construído usando o código mais recente do repositório GitHub do Frankfurter, portanto, isso pode ser instável. Se você quiser usar um commit específico, altere o campo context para build sob frankfurter_api_base no arquivo docker-compose.yml para apontar para o hash do commit específico, por exemplo, https://github.com/lineofflight/frankfurter.git#0b6dbd80716f5abe27e8759fc548b74d35fa82b9 para usar o commit 0b6dbd80716f5abe27e8759fc548b74d35fa82b9. Após a compilação bem-sucedida e a inicialização do contêiner, o servidor MCP estará disponível via HTTP em http://localhost:8000/sse para o transporte Server Sent Events (SSE), ou em http://localhost:8000/mcp para o transporte HTTP transmissível. Se você também estiver iniciando o servidor local da API Frankfurter, o endpoint da API estará disponível em http://localhost:8080/v1.

Servidores hospedados na nuvem

As opções de hospedagem em nuvem atualmente disponíveis são as seguintes.

Acesso do cliente

Esta subseção explica maneiras de um cliente se conectar e testar o servidor FrankfurterMCP.

O inspetor visual oficial do MCP

O Inspetor MCP é uma ferramenta oficial do Model Context Protocol que pode ser usada por desenvolvedores para testar e depurar servidores MCP. Esta é a maneira mais abrangente de explorar o servidor MCP.

Para usá-lo, você deve ter o Node.js instalado. A melhor maneira de instalar e gerenciar o node, bem como pacotes como o Inspetor MCP, é usar o Node Version Manager (ou, nvm). Depois de ter o nvm instalado, você pode instalar e usar a versão mais recente de Long Term Release do node executando o seguinte.

nvm install --lts
nvm use --lts

Em seguida, (instale e) execute o Inspetor MCP executando o seguinte no WD.

npx @modelcontextprotocol/inspector uv run frankfurtermcp

Isso criará uma URL local na porta 6274 com um token de autenticação, que você pode copiar e acessar no seu navegador. Uma vez na interface do Inspetor MCP, pressione Conectar para conectar ao servidor MCP. A partir daí, você pode explorar as ferramentas disponíveis no servidor.

Claude Desktop, Visual Studio e outros

A entrada do servidor para executar com o transporte stdio que você pode usar com sistemas como Claude Desktop, Visual Studio Code e outros é a seguinte.

{
    "command": "uv",
    "args": [
        "run",
        "frankfurtermcp"
    ]
}

Ou, usando uvx:

{
    "command": "uvx",
    "args": [
        "frankfurtermcp"
    ]
}

Em vez de ter frankfurtermcp como o último item na lista de args, talvez seja necessário especificar o caminho completo para o script, por exemplo, WD/.venv/bin/frankfurtermcp. Da mesma forma, em vez de usar uv, você também pode ter a seguinte configuração JSON com o caminho devidamente substituído por python3.12, por exemplo, como WD/.venv/bin/python3.12.

{
    "command": "python3.12",
    "args": [
        "-m",
        "frankfurtermcp.server"
    ]
}

Lista de recursos MCP disponíveis

O FrankfurterMCP possui os seguintes recursos MCP.

Ferramentas

A tabela a seguir lista os nomes das ferramentas conforme expostas pelo servidor FrankfurterMCP. As descrições mostradas aqui são para fins de documentação e podem diferir das descrições reais expostas pelo protocolo de contexto do modelo.

NomeDescrição
get_supported_currenciesObter uma lista de moedas suportadas pela API Frankfurter.
get_latest_exchange_ratesObter as taxas de câmbio mais recentes em moedas específicas para uma moeda base fornecida.
convert_currency_latestConverter um valor de uma moeda para outra usando as taxas de câmbio mais recentes.
get_historical_exchange_ratesObter taxas de câmbio históricas para uma data específica ou intervalo de datas em moedas específicas para uma moeda base fornecida.
convert_currency_specific_dateConverter um valor de uma moeda para outra usando as taxas de câmbio de uma data específica.
greetObter uma saudação do servidor FrankfurterMCP. Isso é usado principalmente para testes internos.

Os argumentos obrigatórios e opcionais de cada ferramenta não estão listados na tabela a seguir por brevidade, mas estão disponíveis para o cliente MCP por meio do protocolo.

Contribuindo

Instale o prek. Em seguida, habilite o prek executando o seguinte no WD.

prek install

Pull requests são bem-vindos. Para mudanças importantes, abra uma issue primeiro para discutir o que você gostaria de alterar.

Testes e cobertura

Para executar os casos de teste fornecidos, execute o seguinte. Adicione o sinalizador --capture=tee-sys ao comando para exibir mais saída no console.

uv run --group test pytest tests/

Invoque o just test-coverage para executar todos os testes e gerar um relatório de cobertura da seguinte forma. Se todos os testes forem executados, o relatório de cobertura gerado pode se parecer com o abaixo.

---------------------------------------------------------------------------------------- benchmark: 2 tests ---------------------------------------------------------------------------------------
Name (time in ms)                         Min               Max              Mean            StdDev            Median               IQR            Outliers       OPS            Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_get_historical_exchange_rates     4.4944 (1.0)      5.1512 (1.0)      4.7919 (1.0)      0.2460 (1.0)      4.7819 (1.0)      0.3249 (1.0)           2;0  208.6840 (1.0)           5           1
test_get_latest_exchange_rates         4.7937 (1.07)     5.6976 (1.11)     5.3257 (1.11)     0.3345 (1.36)     5.4182 (1.13)     0.3575 (1.10)          2;0  187.7702 (0.90)          5           1
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean
=============================================================== 15 passed in 4.09s ===============================================================
Name    Stmts   Miss    Cover   Missing
---------------------------------------
TOTAL     265      0  100.00%

6 files skipped due to complete coverage.
Test coverage complete.

Licença

MIT.

Considerações de segurança

Esta seção documenta descobertas relacionadas à segurança de varreduras de vulnerabilidades e fornece contexto para decisões de implantação.

Descobertas da varredura de vulnerabilidades do Airtable e justificativa

Verifique as descobertas relacionadas à segurança da varredura de vulnerabilidades do Airtable (procure por frankfurtermcp) abaixo, juntamente com a justificativa e contra-argumentos.

ID da regraProblema e contra-argumentos
MCP-R001Problema: As ferramentas são registradas dinamicamente na inicialização do servidor sem assinaturas criptográficas, versionamento imutável ou verificações de integridade. A arquitetura permite cenários de recarga a quente (via padrão register_features), mas não existe verificação de assinatura ou fluxo de aprovação.

Contra-argumentos: As ferramentas não são carregadas de fontes externas ou plugins—elas são definidas diretamente no código-fonte do aplicativo. A integridade é garantida por meio de controle de versão e processos de revisão de código. Como as ferramentas fazem parte do binário do aplicativo (não são plugins carregados dinamicamente), a assinatura criptográfica adicionaria complexidade sem benefício significativo de segurança.
MCP-R004Problema: O servidor emite um aviso, mas aceita curinga nas origens CORS.

Contra-argumentos: Este servidor não se destina a ser executado diretamente em um ambiente de produção ao usar transportes HTTP. Para implantações com controle mais rígido de origens CORS, os usuários devem usar os padrões de .env.template (127.0.0.1) e implantar o servidor atrás de seu próprio proxy reverso com controles de origem CORS apropriados no nível do proxy reverso.
MCP-R013Problema: Não há suporte para HTTPS quando o servidor vincula a qualquer IP diferente de 127.0.0.1.

Contra-argumentos: Este servidor não se destina a ser executado diretamente em um ambiente de produção com suporte a HTTPS ao usar transportes HTTP. Para implantações que exigem suporte a HTTPS, os usuários devem usar os padrões de .env.template (127.0.0.1) e implantar o servidor atrás de seu próprio proxy reverso com configuração HTTPS apropriada.
MCP-R018Problema: Não há verificações de autenticação ou autorização.

Contra-argumentos: Este servidor não se destina a ser executado diretamente em um modo de operação multiusuário ao usar transportes HTTP. Para implantações com controle de acesso, os usuários devem usar os padrões de .env.template (127.0.0.1) e implantar o servidor atrás de seu próprio proxy reverso com controles de segurança apropriados.

Status do projeto

O status atual do projeto é ativo a partir da última atualização deste README. Consulte o CHANGELOG para obter uma lista detalhada de alterações.