Langfuse-mcp-server

Servidor MCP para Langfuse — consultar traces, depurar erros, analisar sessões e prompts de qualquer agente de IA

Documentação

Langfuse MCP Server — Java / Spring AI

Spring Boot Spring AI Java Lombok

Um servidor MCP de nível de produção que conecta qualquer agente de IA compatível com MCP aos seus dados de observabilidade do Langfuse.
Consulte traces, depure erros, inspecione sessões, gerencie prompts, execute avaliações, anote dados e configure modelos — tudo por meio de linguagem natural.

Transporte: HTTP Streamable na porta 8080, compatível com Cursor, Claude Desktop, VS Code / GitHub Copilot e qualquer cliente MCP que suporte transporte HTTP.


Por que este servidor?

RecursoEste servidorMCP oficial do Langfuse
Traces e Observações
Sessões e Usuários
Rastreamento de exceções
Gerenciamento de prompts (leitura + escrita)✅ somente leitura
Gerenciamento de datasets e execuções
Scores e configurações de score
Filas de anotação
Comentários
Definições de modelo
Conexões LLM
Introspecção de projeto
Introspecção de esquema
Java / Spring AI❌ (Python)

Pré-requisitos

  • Java 21 ou posterior
  • Maven 3.9+ (ou use o build Docker — não é necessário Maven local)
  • Uma conta Langfuse com um par de chaves de API (public-key + secret-key)

Início 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

Obtenha as credenciais em Langfuse Cloud → Settings → API Keys.
Langfuse auto-hospedado? Defina LANGFUSE_HOST para a URL da sua instância.


Configuração

Toda a configuração é controlada por variáveis de ambiente (ou application.yml para substituições locais).

PropriedadeVariável de ambienteObrigatórioPadrãoDescrição
langfuse.public-keyLANGFUSE_PUBLIC_KEYChave pública do projeto Langfuse
langfuse.secret-keyLANGFUSE_SECRET_KEYChave secreta do projeto Langfuse
langfuse.hostLANGFUSE_HOSTURL base do Langfuse, ex.: https://cloud.langfuse.com
langfuse.timeoutLANGFUSE_TIMEOUT30sTempo limite de requisição HTTP — formato Spring Duration, ex.: 30s, 1m, 90s
langfuse.read-onlytrueSinalizador informativo; operações de escrita estão disponíveis por meio de ferramentas específicas

Tratamento de barra final

LANGFUSE_HOST pode ser especificado com ou sem barra final — o servidor a normaliza automaticamente.


Configuração do 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"
    }
  }
}

No 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 somente 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: O endpoint MCP é /mcp (HTTP streamable). O endpoint SSE legado /sse não é usado por este servidor.


Docker

O Dockerfile é um build multi-estágio: ele compila o jar do Spring Boot dentro do Docker e executa o servidor MCP na porta 8080. Não é necessária instalação local do 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

Após o contêiner iniciar:

EndpointURL
Verificação de saúdehttp://localhost:8080/actuator/health
Pinghttp://localhost:8080/ping
Endpoint MCPhttp://localhost:8080/mcp

Langfuse executando em outro contêiner no mesmo host:

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

Referência de Ferramentas (55 no total)

Cada ferramenta retorna um envelope ApiResponse<T> consistente:

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

Respostas de listas paginadas envolvem seus itens em um PagedResponse<T>:

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

A paginação é baseada em 1 (page tem como padrão 1). limit tem como padrão 20 e é limitado a 100 quando indicado. Para navegar pelos resultados, incremente page mantendo limit fixo.


Traces (8 ferramentas)

FerramentaDescrição
fetch_tracesLista paginada de traces. Filtre por userId, name, sessionId, tags, fromTimestamp, toTimestamp.
fetch_traceDetalhes completos de um único trace, incluindo observações aninhadas, entrada/saída, metadados, latência e uso de tokens. Requer traceId.
find_exceptionsTraces cujo level é igual a ERROR. Suporta intervalo de tempo e paginação.
find_exceptions_in_fileTraces de nível de erro cujos metadados contêm uma substring de nome de arquivo. Requer fileName.
get_exception_detailsDetalhes completos de um único trace de erro. Requer traceId.
get_error_countContagem de traces de nível ERROR em um intervalo de tempo (verifica até 500 traces).
delete_traceExclui permanentemente um único trace por ID. Irreversível.
delete_tracesExclui permanentemente vários traces. Passe uma lista separada por vírgulas de IDs de trace. Irreversível.

Sessões (3 ferramentas)

FerramentaDescrição
fetch_sessionsLista paginada de sessões com filtro opcional de intervalo de tempo.
get_session_detailsDetalhes completos da sessão, incluindo todos os seus traces. Requer sessionId.
get_user_sessionsTodas as sessões de um usuário específico com paginação. Requer userId.

Prompts (5 ferramentas)

FerramentaDescrição
list_promptsLista paginada de todos os prompts do projeto.
get_promptBusca um prompt por nome. Opcionalmente, fixe em um número de version ou em um label (ex.: production, staging).
create_promptCria um novo prompt ou adiciona uma nova versão a um prompt existente. type é text (string simples) ou chat (array JSON de mensagens {role, content}). Suporta labels e tags separados por vírgulas.
delete_promptExclui versões de prompt por nome. Escopo para um label ou version específico; omita ambos para excluir todas as versões. Irreversível.
update_prompt_labelsSubstitui o conjunto completo de rótulos em uma versão específica de prompt. Forneça uma string vazia para remover todos os rótulos. O rótulo latest é reservado pelo Langfuse.

Datasets (7 ferramentas)

FerramentaDescrição
list_datasetsLista paginada de todos os datasets de avaliação.
get_datasetBusca um dataset pelo nome exato.
create_datasetCria um novo dataset. Opcionalmente, forneça description, metadataJson, inputSchemaJson e expectedOutputSchemaJson (todos como strings JSON).
list_dataset_itemsLista paginada de itens em um dataset. Requer datasetName.
get_dataset_itemBusca um único item de dataset por ID.
create_dataset_itemCria ou faz upsert de um item de dataset. Opcionalmente, vincule a um sourceTraceId ou sourceObservationId. Suporta itemId para semântica de upsert.
delete_dataset_itemExclui permanentemente um item de dataset por ID. Irreversível.

Execuções de Dataset (5 ferramentas)

FerramentaDescrição
list_dataset_runsLista paginada de execuções de experimento para um dataset. Requer datasetName.
get_dataset_runDetalhes completos da execução, incluindo todos os itens da execução. Requer datasetName e runName.
delete_dataset_runExclui uma execução e todos os seus itens. Irreversível. Requer datasetName e runName.
list_dataset_run_itemsLista paginada de itens em uma execução. Requer datasetId e runName.
create_dataset_run_itemCria um item de execução vinculando um item de dataset a um trace/observação. Cria a execução automaticamente se ela ainda não existir.

Métricas (1 ferramenta)

FerramentaDescrição
get_cost_metricsConsulte análises de custo, tokens, latência e uso do Langfuse por meio da Metrics API v1. Espelha: GET /api/public/metrics?query=. Passe a consulta completa como uma string JSON. Toda a agregação é feita no servidor.

Esta ferramenta aceita um único parâmetro obrigatório query que deve ser uma string serializada em JSON correspondente ao esquema da Metrics API. Exemplos (passe-os como uma única string JSON):

  • Custo total nos últimos 7 dias:

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

  • Tendência diária de custo nesta 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"}

  • Custo 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"}

  • Custo para um usuário 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"}

  • Somente ambiente de produção:

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


Scores (6 ferramentas)

FerramentaDescrição
get_scoresLista paginada de scores de avaliação. Filtre por traceId, observationId, name, dataType (NUMERIC|CATEGORICAL|BOOLEAN) e intervalo de tempo.
get_scoreBusca um único score por ID.
get_score_configsLista paginada de esquemas de configuração de score.
get_score_configBusca uma única configuração de score por ID.
create_score_configCria uma configuração de score. NUMERIC suporta minValue/maxValue opcionais. CATEGORICAL aceita um array categoriesJson de objetos {label, value}.
update_score_configAtualiza uma configuração de score existente. Opcionalmente, defina isArchived para arquivá-la.

Filas de Anotação (8 ferramentas)

FerramentaDescrição
list_annotation_queuesLista paginada de filas de anotação.
get_annotation_queueBusca uma única fila por ID.
create_annotation_queueCria uma fila para revisão humana no processo. Opcionalmente, vincule um scoreConfigId.
list_annotation_queue_itemsLista paginada de itens em uma fila. Opcionalmente, filtre por status (PENDING|COMPLETED). Requer queueId.
get_annotation_queue_itemBusca um item específico da fila por queueId e itemId.
create_annotation_queue_itemAdiciona um trace, observação ou sessão a uma fila para revisão. objectType é TRACE, OBSERVATION ou SESSION.
update_annotation_queue_itemAtualiza o status de um item da fila (PENDING|COMPLETED).
delete_annotation_queue_itemRemove um item de uma fila. Irreversível.

Comentários (3 ferramentas)

FerramentaDescrição
get_commentsLista paginada de comentários. Opcionalmente, filtre por objectType (TRACE|OBSERVATION) e objectId.
get_commentBusca um único comentário por ID.
create_commentAnexa um comentário a um trace, observação, sessão ou prompt. Valores de objectType: TRACE, OBSERVATION, SESSION, PROMPT.

Modelos (4 ferramentas)

FerramentaDescrição
list_modelsLista paginada de todas as definições de modelo (gerenciadas pelo Langfuse e personalizadas).
get_modelBusca uma definição de modelo por ID.
create_modelCria um modelo personalizado para rastreamento de custos. Requer modelName, matchPattern (regex) e unit (TOKENS|CHARACTERS|MILLISECONDS|SECONDS|IMAGES|REQUESTS). Opcionalmente, defina preços em USD por unidade.
delete_modelExclui uma definição de modelo personalizada. Modelos gerenciados pelo Langfuse não podem ser excluídos. Irreversível.

Conexões LLM (2 ferramentas)

FerramentaDescrição
list_llm_connectionsLista paginada de conexões de provedores de LLM (as chaves secretas são mascaradas na resposta).
upsert_llm_connectionCria ou atualiza uma conexão de provedor pelo nome provider (ex.: openai, anthropic, azure, google). Faz upsert por provedor — se uma conexão já existir, ela é atualizada.

Projeto (1 ferramenta)

FerramentaDescrição
get_projects_for_api_keyRetorna o(s) projeto(s) visíveis para a chave de API configurada. Útil para confirmar credenciais e metadados do projeto.

Usuários (1 ferramenta)

FerramentaDescrição
get_user_tracesTodos os traces para um ID de usuário Langfuse específico com paginação. Requer userId.

Esquema (1 ferramenta)

FerramentaDescrição
get_data_schemaRetorna o modelo de dados completo do Langfuse: todos os tipos de entidade, campos e valores de enum válidos. Chame isso primeiro para entender as estruturas de dados disponíveis antes de executar consultas.

Arquitetura

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

A arquitetura é estritamente em camadas:

  • client/ — fronteira de integração Langfuse: HTTP com Basic-Auth (Apache HttpComponents 5), exceções tipadas, UriComponentsBuilder para parâmetros de consulta
  • service/ — lógica de domínio: filtragem, mapeamento, paginação, tradução de erros em ApiResponse
  • tools/ — superfície MCP: descrições amigáveis para agentes, validação de parâmetros, delegação para serviços
  • Spring Boot — apenas wrapper de runtime e transporte

Cliente de API

LangfuseApiClient suporta quatro métodos HTTP. Todos os métodos lançam LangfuseApiException ou ResourceNotFoundException em caso de erro, que a camada de serviço converte em respostas estruturadas ApiResponse.error(...) — os agentes nunca veem stack traces brutos.

MétodoUsado para
GETTodas as operações de leitura
POSTOperações de criação
PATCHOperações de atualização
DELETEOperações de exclusão

Estrutura de Pacotes

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)

Executando Testes

mvn test

A cobertura de testes inclui:

  • LangfusePropertiesBindingTest — vinculação de configuração a partir de application-test.yml e validação em nível de propriedade
  • PromptWriteServiceImplTest — lógica de serviço para criação / exclusão / atualização de rótulo de prompt
  • ProjectServiceImplTest — mapeamento de resposta da API de projeto
  • ObservationServiceImplTest — busca de observação e mapeamento de campos
  • MetricsServiceImplTest — lógica de agregação de métricas

Os testes são executados com spring.ai.mcp.server.enabled=false (definido em src/test/resources/application-test.yml) para que nenhum transporte MCP seja iniciado durante a execução dos testes.


Solução de Problemas

TRACE_FETCH_ERROR: HTTP/1.1 header parser received no bytes

Problema de conectividade — não é um bug de código. Verifique:

  1. LANGFUSE_HOST aponta para uma instância Langfuse em execução
  2. O host é acessível a partir do processo JVM
  3. Para Docker: use host.docker.internal em vez de localhost
  4. O esquema corresponde ao seu servidor (http:// vs https://)
  5. Confirme se a API está ativa: curl $LANGFUSE_HOST/api/public/health

INVALID_INPUT: <param> is required

Um parâmetro obrigatório não foi fornecido. Todos os parâmetros required = true são validados na camada de ferramenta antes de qualquer chamada HTTP ser feita.

Timeouts de conexão

Aumente o timeout:

export LANGFUSE_TIMEOUT=60s

O agente não consegue ver o servidor

  1. Confirme se o servidor está em execução: curl http://localhost:8080/actuator/health
  2. Confirme se o endpoint MCP está acessível: curl http://localhost:8080/ping
  3. Verifique se a URL de configuração do cliente aponta para http://localhost:8080/mcp
  4. Inspecione todas as ferramentas disponíveis: npx @modelcontextprotocol/inspector http://localhost:8080/mcp

Modelos gerenciados pelo Langfuse não podem ser excluídos

delete_model só funciona para definições de modelos personalizados que você criou. Para substituir o preço de um modelo gerenciado pelo Langfuse, crie um novo modelo personalizado com o mesmo modelName.


Licença

License: MIT