Langfuse-mcp-server

Servidor MCP para Langfuse — consulta trazas, depura errores, analiza sesiones y prompts desde cualquier agente de IA.

Documentación

Servidor MCP de Langfuse — Java / Spring AI

Spring Boot Spring AI Java Lombok

Un servidor MCP de nivel de producción que conecta cualquier agente de IA compatible con MCP a tus datos de observabilidad de Langfuse.
Consulta traces, depura errores, inspecciona sesiones, gestiona prompts, ejecuta evaluaciones, anota datos y configura modelos — todo mediante lenguaje natural.

Transporte: HTTP Streamable en el puerto 8080, compatible con Cursor, Claude Desktop, VS Code / GitHub Copilot y cualquier cliente MCP que admita transporte HTTP.


¿Por qué este servidor?

CapacidadEste servidorMCP oficial de Langfuse
Traces y observaciones✅❌
Sesiones y usuarios✅❌
Seguimiento de excepciones✅❌
Gestión de prompts (lectura + escritura)✅✅ solo lectura
Gestión de datasets y runs✅❌
Scores y configuraciones de scores✅❌
Colas de anotación✅❌
Comentarios✅❌
Definiciones de modelos✅❌
Conexiones LLM✅❌
Introspección de proyectos✅❌
Introspección de esquemas✅❌
Java / Spring AI✅❌ (Python)

Requisitos previos

  • Java 21 o posterior
  • Maven 3.9+ (o usa la compilación Docker — no se requiere Maven local)
  • Una cuenta de Langfuse con un par de claves API (public-key + secret-key)

Inicio rápido

# 1. Build
mvn clean package -DskipTests

# 2. Set credentials
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_HOST=https://cloud.langfuse.com

# 3. Run (Streamable HTTP transport — port 8080)
java -jar target/langfuse-mcp-1.0.0.jar

# 4. Verify
curl http://localhost:8080/actuator/health

# 5. Inspect all tools
npx @modelcontextprotocol/inspector http://localhost:8080/mcp

Obtén las credenciales en Langfuse Cloud → Configuración → Claves API.
¿Langfuse autoalojado? Establece LANGFUSE_HOST con la URL de tu instancia.


Configuración

Toda la configuración se gestiona mediante variables de entorno (o application.yml para anulaciones locales).

PropiedadVariable de entornoObligatoriaValor predeterminadoDescripción
langfuse.public-keyLANGFUSE_PUBLIC_KEY✅—Clave pública del proyecto Langfuse
langfuse.secret-keyLANGFUSE_SECRET_KEY✅—Clave secreta del proyecto Langfuse
langfuse.hostLANGFUSE_HOST✅—URL base de Langfuse, p. ej. https://cloud.langfuse.com
langfuse.timeoutLANGFUSE_TIMEOUT❌30sTiempo de espera de solicitudes HTTP — formato Duration de Spring, p. ej. 30s, 1m, 90s
langfuse.read-only—❌trueIndicador informativo; las operaciones de escritura están disponibles mediante herramientas específicas

Manejo de la barra final

LANGFUSE_HOST puede especificarse con o sin barra final — el servidor la normaliza automáticamente.


Configuración del cliente

Cursor (.cursor/mcp.json)

{
  "mcpServers": {
    "langfuse": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "langfuse": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

En macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

VS Code / GitHub Copilot

Modo URL:

{
  "github.copilot.chat.mcp.servers": {
    "langfuse": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Modo comando (clientes solo stdio):

{
  "github.copilot.chat.mcp.servers": {
    "langfuse": {
      "command": "java",
      "args": ["-jar", "/absolute/path/to/langfuse-mcp-1.0.0.jar"],
      "env": {
        "LANGFUSE_PUBLIC_KEY": "pk-lf-...",
        "LANGFUSE_SECRET_KEY": "sk-lf-...",
        "LANGFUSE_HOST": "https://cloud.langfuse.com"
      }
    }
  }
}

Nota: El endpoint MCP es /mcp (HTTP streamable). El endpoint SSE heredado /sse no lo utiliza este servidor.


Docker

El Dockerfile es una compilación de varias etapas: compila el jar de Spring Boot dentro de Docker y ejecuta el servidor MCP en el puerto 8080. No se necesita instalación local de Maven.

# Build image (compiles inside Docker)
docker build -t langfuse-mcp:latest .

# Run
docker run --rm -p 8080:8080 \
  -e LANGFUSE_PUBLIC_KEY=pk-lf-... \
  -e LANGFUSE_SECRET_KEY=sk-lf-... \
  -e LANGFUSE_HOST=https://cloud.langfuse.com \
  langfuse-mcp:latest

Después de que el contenedor se inicie:

EndpointURL
Comprobación de estadohttp://localhost:8080/actuator/health
Pinghttp://localhost:8080/ping
Endpoint MCPhttp://localhost:8080/mcp

Langfuse ejecutándose en otro contenedor en el mismo host:

-e LANGFUSE_HOST=http://host.docker.internal:3000

Referencia de herramientas (55 en total)

Cada herramienta devuelve un envoltorio ApiResponse<T> coherente:

{ "success": true,  "data": { ... }, "timestamp": "2025-01-15T10:30:00Z" }
{ "success": false, "errorCode": "TRACE_NOT_FOUND", "errorMessage": "...", "timestamp": "..." }

Las respuestas de listas paginadas envuelven sus elementos en un PagedResponse<T>:

{
  "data": [ ... ],
  "meta": { "page": 1, "limit": 20, "totalItems": 142, "totalPages": 8 }
}

La paginación se basa en 1 (page tiene como valor predeterminado 1). limit tiene como valor predeterminado 20 y está limitado a 100 cuando se indica. Para paginar los resultados, incrementa page manteniendo limit fijo.


Traces (8 herramientas)

HerramientaDescripción
fetch_tracesLista paginada de traces. Filtra por userId, name, sessionId, tags, fromTimestamp, toTimestamp.
fetch_traceDetalle completo de un único trace, incluidas observaciones anidadas, entrada/salida, metadatos, latencia y uso de tokens. Requiere traceId.
find_exceptionsTraces cuyo level es igual a ERROR. Admite rango de tiempo y paginación.
find_exceptions_in_fileTraces de nivel de error cuyos metadatos contienen una subcadena de nombre de archivo determinada. Requiere fileName.
get_exception_detailsDetalle completo de un único trace de error. Requiere traceId.
get_error_countRecuento de traces de nivel ERROR en un rango de tiempo (escanea hasta 500 traces).
delete_traceElimina permanentemente un único trace por ID. Irreversible.
delete_tracesElimina permanentemente varios traces. Pasa una lista separada por comas de IDs de traces. Irreversible.

Sesiones (3 herramientas)

HerramientaDescripción
fetch_sessionsLista paginada de sesiones con filtro opcional de rango de tiempo.
get_session_detailsDetalle completo de la sesión, incluidos todos sus traces. Requiere sessionId.
get_user_sessionsTodas las sesiones de un usuario específico con paginación. Requiere userId.

Prompts (5 herramientas)

HerramientaDescripción
list_promptsLista paginada de todos los prompts del proyecto.
get_promptObtiene un prompt por nombre. Opcionalmente, fija un número de version o un label (p. ej. production, staging).
create_promptCrea un nuevo prompt o añade una nueva versión a un prompt existente. type es text (cadena simple) o chat (matriz JSON de mensajes {role, content}). Admite labels y tags separados por comas.
delete_promptElimina versiones de prompts por nombre. Limita a un label o version específicos; omite ambos para eliminar todas las versiones. Irreversible.
update_prompt_labelsReemplaza el conjunto completo de etiquetas en una versión específica de prompt. Proporciona una cadena vacía para eliminar todas las etiquetas. La etiqueta latest está reservada por Langfuse.

Datasets (7 herramientas)

HerramientaDescripción
list_datasetsLista paginada de todos los datasets de evaluación.
get_datasetObtiene un dataset por nombre exacto.
create_datasetCrea un nuevo dataset. Opcionalmente, proporciona description, metadataJson, inputSchemaJson y expectedOutputSchemaJson (todos como cadenas JSON).
list_dataset_itemsLista paginada de elementos de un dataset. Requiere datasetName.
get_dataset_itemObtiene un único elemento de dataset por ID.
create_dataset_itemCrea o actualiza un elemento de dataset. Opcionalmente, vincula a un sourceTraceId o sourceObservationId. Admite itemId para semántica de actualización.
delete_dataset_itemElimina permanentemente un elemento de dataset por ID. Irreversible.

Runs de datasets (5 herramientas)

HerramientaDescripción
list_dataset_runsLista paginada de runs de experimentos para un dataset. Requiere datasetName.
get_dataset_runDetalle completo del run, incluidos todos sus elementos. Requiere datasetName y runName.
delete_dataset_runElimina un run y todos sus elementos. Irreversible. Requiere datasetName y runName.
list_dataset_run_itemsLista paginada de elementos de un run. Requiere datasetId y runName.
create_dataset_run_itemCrea un elemento de run que vincula un elemento de dataset a un trace/observación. Crea el run automáticamente si aún no existe.

Métricas (1 herramienta)

HerramientaDescripción
get_cost_metricsConsulta análisis de coste, tokens, latencia y uso de Langfuse mediante la API de Métricas v1. Refleja: GET /api/public/metrics?query=. Pasa la consulta completa como una cadena JSON. Toda la agregación se realiza en el servidor.

Esta herramienta acepta un único parámetro obligatorio query que debe ser una cadena serializada en JSON que coincida con el esquema de la API de Métricas. Ejemplos (pásalos como una única cadena JSON):

  • Coste total de los últimos 7 días:

    {"view":"traces","metrics":[{"measure":"totalCost","aggregation":"sum"}],"fromTimestamp":"2026-03-18T00:00:00Z","toTimestamp":"2026-03-25T23:59:59Z"}

  • Tendencia de coste diario de esta semana:

    {"view":"traces","metrics":[{"measure":"totalCost","aggregation":"sum"},{"measure":"count","aggregation":"count"}],"timeDimension":{"granularity":"day"},"fromTimestamp":"2026-03-18T00:00:00Z","toTimestamp":"2026-03-25T23:59:59Z"}

  • Coste por modelo:

    {"view":"observations","dimensions":[{"field":"providedModelName"}],"metrics":[{"measure":"totalCost","aggregation":"sum"},{"measure":"totalTokens","aggregation":"sum"}],"fromTimestamp":"2026-03-18T00:00:00Z","toTimestamp":"2026-03-25T23:59:59Z"}

  • Coste para un usuario específico:

    {"view":"traces","metrics":[{"measure":"totalCost","aggregation":"sum"}],"filters":[{"column":"userId","operator":"=","value":"user-123","type":"string"}],"fromTimestamp":"2026-03-18T00:00:00Z","toTimestamp":"2026-03-25T23:59:59Z"}

  • Solo entorno de producción:

    filters: [{"column":"environment","operator":"=","value":"production","type":"string"}]


Scores (6 herramientas)

HerramientaDescripción
get_scoresLista paginada de scores de evaluación. Filtra por traceId, observationId, name, dataType (NUMERIC|CATEGORICAL|BOOLEAN) y rango de tiempo.
get_scoreObtiene un único score por ID.
get_score_configsLista paginada de esquemas de configuración de scores.
get_score_configObtiene una única configuración de score por ID.
create_score_configCrea una configuración de score. NUMERIC admite minValue/maxValue opcionales. CATEGORICAL acepta una matriz categoriesJson de objetos {label, value}.
update_score_configActualiza una configuración de score existente. Opcionalmente, establece isArchived para archivarla.

Colas de anotación (8 herramientas)

HerramientaDescripción
list_annotation_queuesLista paginada de colas de anotación.
get_annotation_queueObtiene una única cola por ID.
create_annotation_queueCrea una cola para revisión humana en el circuito. Opcionalmente, vincula un scoreConfigId.
list_annotation_queue_itemsLista paginada de elementos de una cola. Opcionalmente, filtra por status (PENDING|COMPLETED). Requiere queueId.
get_annotation_queue_itemObtiene un elemento específico de cola por queueId y itemId.
create_annotation_queue_itemAñade un trace, observación o sesión a una cola para revisión. objectType es TRACE, OBSERVATION o SESSION.
update_annotation_queue_itemActualiza el estado de un elemento de cola (PENDING|COMPLETED).
delete_annotation_queue_itemElimina un elemento de una cola. Irreversible.

Comentarios (3 herramientas)

HerramientaDescripción
get_commentsLista paginada de comentarios. Opcionalmente, filtra por objectType (TRACE|OBSERVATION) y objectId.
get_commentObtiene un único comentario por ID.
create_commentAdjunta un comentario a un trace, observación, sesión o prompt. Valores de objectType: TRACE, OBSERVATION, SESSION, PROMPT.

Modelos (4 herramientas)

HerramientaDescripción
list_modelsLista paginada de todas las definiciones de modelos (gestionados por Langfuse y personalizados).
get_modelObtiene una definición de modelo por ID.
create_modelCrea un modelo personalizado para el seguimiento de costes. Requiere modelName, matchPattern (regex) y unit (TOKENS|CHARACTERS|MILLISECONDS|SECONDS|IMAGES|REQUESTS). Opcionalmente, establece precios en USD por unidad.
delete_modelElimina una definición de modelo personalizado. Los modelos gestionados por Langfuse no se pueden eliminar. Irreversible.

Conexiones LLM (2 herramientas)

HerramientaDescripción
list_llm_connectionsLista paginada de conexiones de proveedores de LLM (las claves secretas están enmascaradas en la respuesta).
upsert_llm_connectionCrea o actualiza una conexión de proveedor por nombre de provider (p. ej., openai, anthropic, azure, google). Realiza upsert por proveedor: si ya existe una conexión, se actualiza.

Proyecto (1 herramienta)

HerramientaDescripción
get_projects_for_api_keyDevuelve el/los proyecto(s) visibles para la clave API configurada. Útil para confirmar credenciales y metadatos del proyecto.

Usuarios (1 herramienta)

HerramientaDescripción
get_user_tracesTodos los traces para un ID de usuario específico de Langfuse con paginación. Requiere userId.

Esquema (1 herramienta)

HerramientaDescripción
get_data_schemaDevuelve el modelo de datos completo de Langfuse: todos los tipos de entidad, campos y valores de enumeración válidos. Llama a esto primero para comprender las estructuras de datos disponibles antes de ejecutar consultas.

Arquitectura

MCP Client (Cursor / Claude Desktop / Copilot / other)
    │   Streamable HTTP transport (/mcp)
    ▼
Tool class  (@McpTool — validates required params, delegates to service)
    ▼
Service interface + impl  (business logic, filtering, error mapping)
    ▼
LangfuseApiClient  (HTTP gateway — GET / POST / PATCH / DELETE, typed exceptions)
    ▼
Langfuse Public REST API

La arquitectura está estrictamente en capas:

  • client/ — límite de integración con Langfuse: HTTP con autenticación básica (Apache HttpComponents 5), excepciones tipadas, UriComponentsBuilder para parámetros de consulta
  • service/ — lógica de dominio: filtrado, mapeo, paginación, traducción de errores a ApiResponse
  • tools/ — superficie MCP: descripciones amigables para agentes, validación de parámetros, delegación a servicios
  • Spring Boot — solo envoltorio de ejecución y transporte

Cliente API

LangfuseApiClient admite cuatro métodos HTTP. Todos los métodos lanzan LangfuseApiException o ResourceNotFoundException en caso de error, que la capa de servicio convierte en respuestas estructuradas de ApiResponse.error(...) — los agentes nunca ven trazas de pila sin procesar.

MétodoSe usa para
GETTodas las operaciones de lectura
POSTOperaciones de creación
PATCHOperaciones de actualización
DELETEOperaciones de eliminación

Estructura de Paquetes

com.langfuse.mcp
├── LangfuseMcpApplication.java          @SpringBootApplication @ConfigurationPropertiesScan
├── config/
│   ├── LangfuseProperties.java          @ConfigurationProperties — publicKey, secretKey, host, timeout, readOnly
│   ├── LangfuseClientConfig.java        RestClient bean — Basic-Auth, Apache HttpComponents 5, configurable timeout
│   └── JacksonConfig.java               Primary ObjectMapper (JSR310, ignore unknown fields)
├── client/
│   └── LangfuseApiClient.java           HTTP gateway (GET/POST/PATCH/DELETE); typed exceptions; UriComponentsBuilder queries
├── controller/
│   └── PingController.java              GET /ping → {"status":"ok"}
├── exception/
│   ├── LangfuseApiException.java        Wraps HTTP/connectivity errors — statusCode + endpoint
│   └── ResourceNotFoundException.java   Thrown on HTTP 404
├── dto/
│   ├── common/    ApiResponse · PagedResponse · PaginationMeta
│   ├── request/   Filter/get request classes (12 classes)
│   └── response/  Response classes (19 classes — JsonNode for open-schema fields)
├── service/       Interfaces (15): Trace · Session · Prompt · PromptWrite · Dataset · DatasetRun
│   │              · Score · AnnotationQueue · Comment · Model · LlmConnection · Project · User · Schema · CostMetrics
│   └── impl/      *ServiceImpl (15) — business logic, filtering, error mapping
├── tools/         @McpTool classes (15) — param validation, delegation, agent-friendly descriptions
│   ├── TraceTools.java             (8 tools)
│   ├── SessionTools.java           (3 tools)
│   ├── PromptTools.java            (2 tools)
│   ├── PromptWriteTools.java       (3 tools)
│   ├── DatasetTools.java           (7 tools)
│   ├── DatasetRunTools.java        (5 tools)
│   ├── ScoreTools.java             (6 tools)
│   ├── AnnotationQueueTools.java   (8 tools)
│   ├── CommentTools.java           (3 tools)
│   ├── ModelTools.java             (4 tools)
│   ├── LlmConnectionTools.java     (2 tools)
│   ├── ProjectTools.java           (1 tool)
│   ├── UserTools.java              (1 tool)
│   ├── SchemaTools.java            (1 tool)
│   └── CostMetricsTools.java       (1 tool)
└── util/
    └── JsonPageMapper.java         Centralised JSON → PagedResponse mapper (no duplication)

Ejecución de Pruebas

mvn test

La cobertura de pruebas incluye:

  • LangfusePropertiesBindingTest — vinculación de configuración desde application-test.yml y validación a nivel de propiedad
  • PromptWriteServiceImplTest — lógica de servicio para creación/eliminación de prompts y actualización de etiquetas
  • ProjectServiceImplTest — mapeo de respuestas de la API de proyectos
  • ObservationServiceImplTest — obtención de observaciones y mapeo de campos
  • MetricsServiceImplTest — lógica de agregación de métricas

Las pruebas se ejecutan con spring.ai.mcp.server.enabled=false (configurado en src/test/resources/application-test.yml) para que no se inicie ningún transporte MCP durante la ejecución de las pruebas.


Solución de Problemas

TRACE_FETCH_ERROR: HTTP/1.1 header parser received no bytes

Problema de conectividad — no es un error de código. Verifica:

  1. LANGFUSE_HOST apunta a una instancia de Langfuse en ejecución
  2. El host es accesible desde el proceso JVM
  3. Para Docker: usa host.docker.internal en lugar de localhost
  4. El esquema coincide con tu servidor (http:// vs https://)
  5. Confirma que la API está activa: curl $LANGFUSE_HOST/api/public/health

INVALID_INPUT: <param> is required

No se proporcionó un parámetro requerido. Todos los parámetros de required = true se validan en la capa de herramientas antes de realizar cualquier llamada HTTP.

Tiempos de espera de conexión

Aumenta el tiempo de espera:

export LANGFUSE_TIMEOUT=60s

El agente no puede ver el servidor

  1. Confirma que el servidor está en ejecución: curl http://localhost:8080/actuator/health
  2. Confirma que el endpoint MCP es accesible: curl http://localhost:8080/ping
  3. Verifica que la URL de configuración del cliente apunte a http://localhost:8080/mcp
  4. Inspecciona todas las herramientas disponibles: npx @modelcontextprotocol/inspector http://localhost:8080/mcp

Los modelos gestionados por Langfuse no se pueden eliminar

delete_model solo funciona para definiciones de modelos personalizados que hayas creado. Para anular el precio de un modelo gestionado por Langfuse, crea un nuevo modelo personalizado con el mismo modelName.


Licencia

License: MIT