FrankfurterMCP

Servidor MCP que actúa como interfaz para la API de Frankfurter para datos de cambio de divisas.

Documentación

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

Frankfurter MCP

Frankfurter es una API útil para los últimos tipos de cambio de divisas, datos históricos o series temporales publicados por fuentes como el Banco Central Europeo. Si necesitas acceder a la API de Frankfurter como herramientas para agentes de modelos de lenguaje expuestos a través del Protocolo de Contexto de Modelos (MCP), Frankfurter MCP es lo que necesitas.

Instalación

Si tu objetivo es utilizar las herramientas disponibles en este servidor MCP, consulta la subsección de uso > cliente a continuación.

El directorio donde clonas este repositorio se referirá como directorio de trabajo o WD en adelante.

Instala just para gestionar las tareas del proyecto.

Instala uv. Para instalar el proyecto con sus dependencias mínimas en un entorno virtual, ejecuta just install en el WD. Para instalar todas las dependencias no esenciales (que son necesarias para el desarrollo y las pruebas), ejecuta just install-all en su lugar.

Variables de entorno

A continuación se presenta una lista de variables de entorno que se pueden utilizar para configurar la aplicación. Se proporciona una plantilla de variables de entorno en el archivo .env.template. Ten en cuenta que los valores predeterminados que se enumeran en la tabla siguiente no siempre son los mismos que los del archivo .env.template.

Las siguientes variables de entorno se pueden especificar, con el prefijo FASTMCP_: HOST, PORT, DEBUG y LOG_LEVEL.

El cliente HTTP subyacente también respeta algunas variables de entorno, como se documenta en la biblioteca HTTPX. Además, SSL_CERT_FILE y SSL_CERT_DIR se pueden configurar para usar certificados autofirmados del punto final de API alojado o servidores proxy HTTP(S) intermedios.

Frankfurter MCP almacenará en caché las llamadas a la API de Frankfurter para mejorar el rendimiento. El caché se realiza con dos estrategias diferentes. Para las llamadas a la API cuyas respuestas no cambian para ciertos parámetros, por ejemplo, la consulta de tasas históricas, se utiliza un caché de uso menos reciente (LRU). Para las llamadas a la API cuyas respuestas sí cambian, por ejemplo, la consulta de la última tasa, se utiliza un caché de tiempo de vida (TTL) con un tiempo de vida predeterminado de 15 minutos. Los parámetros del caché se pueden ajustar mediante las variables de entorno, como se muestra a continuación.

Variable[Valor predeterminado] y descripción
LOG_LEVEL[INFO] El nivel de registro. Cambiar este nivel también afecta la salida de registro de otras bibliotecas dependientes que pueden usar la misma variable de entorno. Consulte los valores válidos en documentación de registro de Python.
HTTPX_TIMEOUT[5.0] El tiempo que el cliente HTTP subyacente espera, en segundos, una respuesta de la API de Frankfurter. El rango aceptable de valores está entre 5.0 y 60.0.
HTTPX_VERIFY_SSL[True] Esta variable se puede establecer en False para desactivar la verificación de certificados SSL, si, por ejemplo, estás usando un servidor proxy con un certificado autofirmado. Sin embargo, establecer esto en False se desaconseja: en su lugar, usa las variables SSL_CERT_FILE y SSL_CERT_DIR para configurar correctamente los certificados autofirmados.
FAST_MCP_HOST[localhost] Esta variable especifica a qué host debe vincularse el servidor MCP a menos que el transporte del servidor (ver más abajo) esté configurado en stdio. Ten en cuenta que ejecutar el servidor para vincularse a cualquier IP especificando 0.0.0.0 representa una amenaza de seguridad. Dicha configuración solo debe usarse en entornos de demostración.
FAST_MCP_PORT[8000] Esta variable especifica en qué puerto debe escuchar el servidor MCP a menos que el transporte del servidor (ver más abajo) esté configurado en stdio.
CORS_MIDDLEWARE_ALLOW_ORIGINS["localhost", "127.0.0.1"] Esta variable especifica los orígenes permitidos de Intercambio de Recursos de Origen Cruzado (CORS) para el servidor MCP a menos que el transporte del servidor (ver más abajo) esté configurado en stdio. Debes establecerlo explícitamente en "*" (y recibirás una advertencia al hacerlo) si quieres probar este servidor a través de un transporte HTTP utilizando el inspector MCP descrito a continuación.
MCP_SERVER_TRANSPORT[stdio] Las opciones aceptables son stdio, sse o streamable-http. Sin embargo, en el .env.template, el valor predeterminado se establece en stdio.
MCP_SERVER_INCLUDE_METADATA_IN_RESPONSE[True] Esto especifica si se incluirán metadatos adicionales con la respuesta MCP de cada llamada a herramienta. Los metadatos adicionales, por ejemplo, incluirán la URL de la API del servidor de Frankfurter, entre otros, que se utiliza para obtener las respuestas.
FRANKFURTER_API_URL[https://api.frankfurter.dev/v1] Si estás alojando la API de Frankfurter por tu cuenta, debes cambiar esto a la dirección del punto final de API de tu implementación.
LRU_CACHE_MAX_SIZE[1024] El tamaño máximo del caché de uso menos reciente (LRU) para llamadas a la API. El rango aceptable de valores está entre 128 y 65536.
TTL_CACHE_MAX_SIZE[256] El tamaño máximo del caché de tiempo de vida (TTL) para llamadas a la API. El rango aceptable de valores está entre 64 y 16384.
TTL_CACHE_TTL_SECONDS[900] El límite de tiempo, en segundos, del caché de tiempo de vida (TTL) para llamadas a la API. El rango aceptable de valores está entre 60 y 3600.
UVICORN_LIMIT_CONCURRENCY[100] El número máximo de conexiones concurrentes que aceptará el servidor. Esto ayuda a prevenir el agotamiento de recursos por demasiadas conexiones simultáneas. Solo aplica cuando se utilizan transportes HTTP (sse o streamable-http). El rango aceptable de valores está entre 10 y 10000.
UVICORN_TIMEOUT_KEEP_ALIVE[60] El tiempo de espera en segundos para mantener las conexiones inactivas. Las conexiones inactivas se cerrarán después de este período para liberar recursos. Solo aplica cuando se utilizan transportes HTTP (sse o streamable-http). El rango aceptable de valores está entre 60 y 300.
UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN[5] El tiempo de espera en segundos para el apagado gradual. El servidor esperará este tiempo para que las conexiones activas se completen antes de apagarse forzosamente. Solo aplica cuando se utilizan transportes HTTP (sse o streamable-http). El rango aceptable de valores está entre 5 y 60.
RATE_LIMIT_MAX_REQUESTS_PER_SECOND[10.0] El número máximo de solicitudes permitidas por segundo utilizando un algoritmo de balde de tokens. Esto implementa limitación de velocidad para prevenir el abuso de la API y garantizar una asignación justa de recursos. El rango aceptable de valores está entre 1.0 y 10000.0.
RATE_LIMIT_BURST_CAPACITY[20] La capacidad de ráfaga para el limitador de velocidad, que permite ráfagas cortas de solicitudes por encima del límite por segundo. Esto proporciona flexibilidad para patrones de uso legítimos mientras se sigue protegiendo contra altas tasas de solicitudes sostenidas. El rango aceptable de valores está entre 2x y 5x el valor de RATE_LIMIT_MAX_REQUESTS_PER_SECOND.
REQUEST_SIZE_LIMIT_BYTES[102400] El tamaño máximo en bytes para los cuerpos de solicitudes HTTP (predeterminado 100KB). Las solicitudes que superen este límite serán rechazadas con un código de estado 413. Esto previene ataques de agotamiento de memoria por cargas útiles grandes. Solo aplica cuando se utilizan transportes HTTP (sse o streamable-http). El rango aceptable de valores está entre 10240 (10KB) y 524288 (512KB).
DOCKER_TMPFS_SIZE_MB[100] El tamaño en megabytes para el sistema de archivos temporal (/tmp) cuando se ejecuta en Docker con sistema de archivos raíz de solo lectura. Este almacenamiento temporal se utiliza para operaciones de archivos en tiempo de ejecución. Aumenta este valor si la aplicación requiere más almacenamiento temporal para almacenar en caché o procesar conjuntos de datos grandes. Solo relevante cuando se implementa con Docker Compose.

Uso

Las siguientes subsecciones ilustran cómo ejecutar Frankfurter MCP como servidor y cómo acceder a él desde clientes MCP.

Servidor

Mientras se ejecuta el servidor, tienes la opción de usar el transporte stdio o las opciones HTTP (sse o el más nuevo streamable-http).

Usando la configuración predeterminada y MCP_SERVER_TRANSPORT establecido en sse o streamable-http, el punto final MCP estará disponible a través de HTTP en http://localhost:8000/sse para el transporte de Eventos Enviados por el Servidor (SSE), o en http://localhost:8000/mcp para el transporte HTTP transmisible.

Si deseas ejecutar Frankfurter MCP con el transporte stdio y los parámetros predeterminados, ejecuta los comandos a continuación sin usar el archivo .env.template.

Servidor con uv

Opcional: Copia el archivo .env.template a un archivo .env en el WD, para modificar las variables de entorno mencionadas anteriormente, si deseas usar algo diferente a la configuración predeterminada. O, en tu shell, puedes exportar las variables de entorno que desees modificar.

Ejecuta lo siguiente en el WD para iniciar el servidor MCP.

uv run frankfurtermcp

Servidor con pip del paquete PyPI

Agrega este paquete desde PyPI usando pip en un entorno virtual (posiblemente administrado por uv, pyenv o conda) y luego inicia el servidor ejecutando lo siguiente.

Opcional: Agrega un archivo .env con el contenido del archivo .env.template si deseas modificar los valores predeterminados de las variables de entorno mencionadas anteriormente. O, en tu shell, puedes exportar las variables de entorno que desees modificar.

pip install frankfurtermcp
python -m frankfurtermcp.server

Servidor usando Docker

Hay un Dockerfile proporcionado en este repositorio, local.dockerfile, para contenerizar el servidor Frankfurter MCP. Primero, haz una copia de .env.template a un archivo .env. Luego, modifica las siguientes variables en el archivo .env según sea necesario.

  • FASTMCP_HOST: Establécelo en 0.0.0.0 para permitir el acceso externo al contenedor. Esto es solo para pruebas locales y no se recomienda para implementaciones de producción.
  • CORS_MIDDLEWARE_ALLOW_ORIGINS: Establécelo en * para permitir el acceso externo al servidor MCP desde cualquier origen. Esto es necesario si deseas probar el servidor usando el Inspector MCP a través de transporte HTTP y no se recomienda para implementaciones de producción.

Para construir la imagen, crear el contenedor e iniciarlo usando Docker Compose, ejecuta lo siguiente en WD.

Si cambias el puerto a cualquier otro que no sea 8000 en .env, recuerda cambiar el número de puerto en docker-compose.yml.

Nota: La versión mínima necesaria de Docker Compose es 2.24.0. Puedes verificar tu versión ejecutando docker compose version. Si tienes una versión anterior, actualiza Docker Desktop para obtener la última versión de Docker Compose. Además, el backend debe ser compatible con BuildKit.

docker compose up --build

Para ejecutar en modo desacoplado (fondo), agrega el indicador -d:

docker compose up -d --build

Para detener el contenedor:

docker compose down

Para ejecutar el contenedor y usar el servidor local de la API de Frankfurter, ejecuta el siguiente comando. Agrega el indicador -d para ejecutarlo en modo desacoplado. Consulta el archivo local_api.env.template para especificar las variables de entorno opcionales utilizadas por el servidor de API local.

Nota: Al iniciar por primera vez, la API local de Frankfurter puede necesitar algo de tiempo para obtener los tipos de cambio actualizados. En ejecuciones posteriores, la API local de Frankfurter utilizará datos en caché y debería iniciarse más rápido, aunque aún obtendrá las últimas tasas.

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

Para detener el grupo de contenedores creado con el perfil local_api, ejecuta el siguiente comando.

docker compose --profile local_api down

El archivo docker-compose.yml incluye endurecimiento de seguridad con sistema de archivos de solo lectura (donde corresponda), capacidades eliminadas y límites de recursos.

Nota: El servidor de API local se construye usando el código más reciente del repositorio de GitHub de Frankfurter, por lo que esto puede ser inestable. Si deseas usar un commit específico, cambia el campo context para build bajo frankfurter_api_base en el archivo docker-compose.yml para apuntar al hash del commit específico, por ejemplo, https://github.com/lineofflight/frankfurter.git#0b6dbd80716f5abe27e8759fc548b74d35fa82b9 para usar el commit 0b6dbd80716f5abe27e8759fc548b74d35fa82b9. Tras una compilación y un inicio de contenedor exitosos, el servidor MCP estará disponible a través de HTTP en http://localhost:8000/sse para el transporte de Server Sent Events (SSE), o en http://localhost:8000/mcp para el transporte HTTP transmisible. Si también está iniciando el servidor local de la API de Frankfurter, el endpoint de la API estará disponible en http://localhost:8080/v1.

Servidores alojados en la nube

Las opciones de alojamiento en la nube actualmente disponibles son las siguientes.

Acceso de clientes

Esta subsección explica las formas en que un cliente puede conectarse y probar el servidor FrankfurterMCP.

El inspector visual oficial de MCP

El Inspector MCP es una herramienta oficial del Model Context Protocol que los desarrolladores pueden usar para probar y depurar servidores MCP. Esta es la forma más completa de explorar el servidor MCP.

Para usarlo, debe tener Node.js instalado. La mejor manera de instalar y gestionar node, así como paquetes como el Inspector MCP, es usar el Node Version Manager (o, nvm). Una vez que tenga nvm instalado, puede instalar y usar la última versión de Long Term Release de node ejecutando lo siguiente.

nvm install --lts
nvm use --lts

Después de eso, (instale y) ejecute el Inspector MCP ejecutando lo siguiente en el WD.

npx @modelcontextprotocol/inspector uv run frankfurtermcp

Esto creará una URL local en el puerto 6274 con un token de autenticación, que puede copiar y abrir en su navegador. Una vez en la interfaz del Inspector MCP, presione Connect para conectarse al servidor MCP. A partir de ahí, puede explorar las herramientas disponibles en el servidor.

Claude Desktop, Visual Studio, etc.

La entrada del servidor para ejecutar con el transporte stdio que puede usar con sistemas como Claude Desktop, Visual Studio Code, etc., es la siguiente.

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

O, usando uvx:

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

En lugar de tener frankfurtermcp como último elemento en la lista de args, es posible que deba especificar la ruta completa al script, por ejemplo, WD/.venv/bin/frankfurtermcp. Del mismo modo, en lugar de usar uv, también podría tener la siguiente configuración JSON con la ruta sustituida adecuadamente para python3.12, por ejemplo, como WD/.venv/bin/python3.12.

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

Lista de funciones MCP disponibles

FrankfurterMCP tiene las siguientes funciones MCP.

Herramientas

La siguiente tabla enumera los nombres de las herramientas expuestas por el servidor FrankfurterMCP. Las descripciones que se muestran aquí son con fines de documentación y pueden diferir de las descripciones reales expuestas a través del protocolo de contexto de modelos.

NombreDescripción
get_supported_currenciesObtener una lista de las monedas admitidas por la API de Frankfurter.
get_latest_exchange_ratesObtener los tipos de cambio más recientes en monedas específicas para una moneda base determinada.
convert_currency_latestConvertir un importe de una moneda a otra utilizando los tipos de cambio más recientes.
get_historical_exchange_ratesObtener tipos de cambio históricos para una fecha específica o un rango de fechas en monedas específicas para una moneda base determinada.
convert_currency_specific_dateConvertir un importe de una moneda a otra utilizando los tipos de cambio de una fecha específica.
greetObtener un saludo del servidor FrankfurterMCP. Esto se usa principalmente para pruebas internas.

Los argumentos obligatorios y opcionales de cada herramienta no se enumeran en la siguiente tabla por brevedad, pero están disponibles para el cliente MCP a través del protocolo.

Contribuciones

Instale prek. Luego habilite prek ejecutando lo siguiente en el WD.

prek install

Las solicitudes de extracción son bienvenidas. Para cambios importantes, abra primero un issue para discutir lo que le gustaría cambiar.

Pruebas y cobertura

Para ejecutar los casos de prueba proporcionados, ejecute lo siguiente. Agregue el indicador --capture=tee-sys al comando para mostrar más salida de consola.

uv run --group test pytest tests/

Invoque just test-coverage para ejecutar todas las pruebas y generar un informe de cobertura de la siguiente manera. Si se ejecutan todas las pruebas, el informe de cobertura generado puede parecerse al siguiente.

---------------------------------------------------------------------------------------- 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.

Licencia

MIT.

Consideraciones de seguridad

Esta sección documenta los hallazgos relacionados con la seguridad de los análisis de vulnerabilidades y proporciona contexto para las decisiones de implementación.

Hallazgos del análisis de vulnerabilidades de Airtable y justificación

Consulte los hallazgos relacionados con la seguridad de el análisis de vulnerabilidades de Airtable (busque frankfurtermcp) a continuación, junto con la justificación y los contraargumentos.

ID de reglaProblema y contraargumentos
MCP-R001Problema: Las herramientas se registran dinámicamente al iniciar el servidor sin firmas criptográficas, versionado inmutable ni comprobaciones de integridad. La arquitectura permite escenarios de recarga en caliente (mediante el patrón register_features), pero no existe verificación de firmas ni flujo de aprobación.

Contraargumentos: Las herramientas no se cargan desde fuentes externas ni complementos; se definen directamente en el código fuente de la aplicación. La integridad se garantiza mediante el control de versiones y los procesos de revisión de código. Dado que las herramientas forman parte del binario de la aplicación (no son complementos cargados dinámicamente), la firma criptográfica añadiría complejidad sin un beneficio de seguridad significativo.
MCP-R004Problema: El servidor advierte pero acepta comodines en los orígenes CORS.

Contraargumentos: Este servidor no está pensado para ejecutarse directamente en un entorno de producción cuando se utilizan transportes HTTP. Para implementaciones con un control más estricto de los orígenes CORS, los usuarios deben usar los valores predeterminados de .env.template (127.0.0.1) e implementar el servidor detrás de su propio proxy inverso con los controles de orígenes CORS adecuados a nivel del proxy inverso.
MCP-R013Problema: No hay soporte para HTTPS cuando el servidor se vincula a cualquier IP distinta de 127.0.0.1.

Contraargumentos: Este servidor no está pensado para ejecutarse directamente en un entorno de producción con soporte HTTPS cuando se utilizan transportes HTTP. Para implementaciones que requieran soporte HTTPS, los usuarios deben usar los valores predeterminados de .env.template (127.0.0.1) e implementar el servidor detrás de su propio proxy inverso con la configuración HTTPS adecuada.
MCP-R018Problema: No hay comprobaciones de autenticación ni autorización.

Contraargumentos: Este servidor no está pensado para ejecutarse directamente en un modo de operación multiusuario cuando se utilizan transportes HTTP. Para implementaciones con control de acceso, los usuarios deben usar los valores predeterminados de .env.template (127.0.0.1) e implementar el servidor detrás de su propio proxy inverso con los controles de seguridad adecuados.

Estado del proyecto

El estado actual del proyecto es activo a partir de la última actualización de este README. Consulte el CHANGELOG para obtener una lista detallada de los cambios.