The langfuse-mcp-java server connects MCP-compatible AI agents to Langfuse, enabling natural language querying and management of LLM pipeline observability data. It provides 54 tools covering all major Langfuse capabilities — including write operations not available in the official Python version.
Traces & Observations
List, filter (by user, name, session, tags, time), and fetch full trace details including nested observations, input/output, latency, token usage, and cost
Find ERROR-level traces, filter by file name in metadata, and get error counts
Fetch individual observations by ID or filter by type (GENERATION, SPAN, EVENT)
Delete single or multiple traces
Sessions & Users
List sessions with time filters; get full session details including all traces
Retrieve all sessions or traces for a specific user
Prompts
List, fetch (by name, version, or label), create, update labels, and delete prompt versions
Supports text and chat types, versioning, labels (e.g.
production,staging), and tags
Datasets & Runs
List, fetch, create datasets and dataset items; upsert items linked to traces/observations
List, create, and delete dataset runs and run items
Scores & Score Configs
List and fetch scores filtered by trace, observation, name, data type, or time range
Create and update score config schemas (numeric, categorical, boolean)
Annotation Queues
Create and manage human-in-the-loop review queues linked to score configs
Add traces/observations/sessions to queues, update item status, and remove items
Comments
List and fetch comments; attach comments to traces, observations, sessions, or prompts
Models & LLM Connections
List, create, and delete custom model definitions for cost tracking
List and manage LLM provider connections (OpenAI, Anthropic, Azure, Google) with masked secret keys
Project & Schema Introspection
Retrieve project metadata and verify API key access
Fetch the full Langfuse data model schema (entity types, fields, enum values)
Deployment: Runs as a standalone Java 21/Spring Boot application or Docker container, compatible with Cursor, Claude Desktop, VS Code/GitHub Copilot, and any MCP-compatible client.
Langfuse MCP Server — Java / Spring AI
A production-grade MCP server that connects any MCP-compatible AI agent to your Langfuse observability data.
Query traces, debug errors, inspect sessions, manage prompts, run evaluations, annotate data, and configure models — all through natural language.
Transport: Streamable HTTP on port 8080, compatible with Cursor, Claude Desktop, VS Code / GitHub Copilot, and any MCP client that supports HTTP transport.
Why this server?
Capability | This server | Official Langfuse MCP |
Traces & Observations | ✅ | ❌ |
Sessions & Users | ✅ | ❌ |
Exception tracking | ✅ | ❌ |
Prompt management (read + write) | ✅ | ✅ read-only |
Dataset & run management | ✅ | ❌ |
Scores & score configs | ✅ | ❌ |
Annotation queues | ✅ | ❌ |
Comments | ✅ | ❌ |
Model definitions | ✅ | ❌ |
LLM connections | ✅ | ❌ |
Project introspection | ✅ | ❌ |
Schema introspection | ✅ | ❌ |
Java / Spring AI | ✅ | ❌ (Python) |
Prerequisites
Java 21 or later
Maven 3.9+ (or use the Docker build — no local Maven required)
A Langfuse account with an API key pair (
public-key+secret-key)
Quick Start
# 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/mcpGet credentials from Langfuse Cloud → Settings → API Keys.
Self-hosted Langfuse? Set LANGFUSE_HOST to your instance URL.
Configuration
All configuration is driven by environment variables (or application.yml for local overrides).
Property | Env var | Required | Default | Description |
|
| ✅ | — | Langfuse project public key |
|
| ✅ | — | Langfuse project secret key |
|
| ✅ | — | Langfuse base URL, e.g. |
|
| ❌ |
| HTTP request timeout — Spring Duration format, e.g. |
| — | ❌ |
| Informational flag; write operations are available through specific tools |
Trailing slash handling
LANGFUSE_HOST may be specified with or without a trailing slash — the server normalises it automatically.
Client Configuration
Cursor (.cursor/mcp.json)
{
"mcpServers": {
"langfuse": {
"url": "http://localhost:8080/mcp"
}
}
}Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"langfuse": {
"url": "http://localhost:8080/mcp"
}
}
}On macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
VS Code / GitHub Copilot
URL mode:
{
"github.copilot.chat.mcp.servers": {
"langfuse": {
"url": "http://localhost:8080/mcp"
}
}
}Command mode (stdio-only clients):
{
"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"
}
}
}
}Note: The MCP endpoint is
/mcp(streamable HTTP). The legacy SSE/sseendpoint is not used by this server.
Docker
The Dockerfile is a multi-stage build: it compiles the Spring Boot jar inside Docker and runs the MCP server on port 8080. No local Maven installation is needed.
# 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:latestAfter the container starts:
Endpoint | URL |
Health check |
|
Ping |
|
MCP endpoint |
|
Langfuse running in another container on the same host:
-e LANGFUSE_HOST=http://host.docker.internal:3000Tools Reference (54 total)
Every tool returns a consistent ApiResponse<T> envelope:
{ "success": true, "data": { ... }, "timestamp": "2025-01-15T10:30:00Z" }
{ "success": false, "errorCode": "TRACE_NOT_FOUND", "errorMessage": "...", "timestamp": "..." }Paginated list responses wrap their items in a PagedResponse<T>:
{
"data": [ ... ],
"meta": { "page": 1, "limit": 20, "totalItems": 142, "totalPages": 8 }
}Pagination is 1-based (page defaults to 1). limit defaults to 20 and is capped at 100 where noted. To page through results, increment page while keeping limit fixed.
Traces (8 tools)
Tool | Description |
| Paginated list of traces. Filter by |
| Full detail of a single trace including nested observations, input/output, metadata, latency, and token usage. Requires |
| Traces whose |
| Error-level traces whose metadata contains a given file name substring. Requires |
| Full detail of a single error trace. Requires |
| Count of |
| Permanently deletes a single trace by ID. Irreversible. |
| Permanently deletes multiple traces. Pass a comma-separated list of trace IDs. Irreversible. |
Sessions (3 tools)
Tool | Description |
| Paginated list of sessions with optional time range filter. |
| Full session detail including all its traces. Requires |
| All sessions for a specific user with pagination. Requires |
Prompts (5 tools)
Tool | Description |
| Paginated list of all prompts in the project. |
| Fetch a prompt by name. Optionally pin to a |
| Create a new prompt or append a new version to an existing prompt. |
| Delete prompt versions by name. Scope to a specific |
| Replace the full label set on a specific prompt version. Supply an empty string to remove all labels. The |
Datasets (7 tools)
Tool | Description |
| Paginated list of all evaluation datasets. |
| Fetch a dataset by exact name. |
| Create a new dataset. Optionally supply |
| Paginated list of items in a dataset. Requires |
| Fetch a single dataset item by ID. |
| Create or upsert a dataset item. Optionally link to a |
| Permanently delete a dataset item by ID. Irreversible. |
Dataset Runs (5 tools)
Tool | Description |
| Paginated list of experiment runs for a dataset. Requires |
| Full run detail including all run items. Requires |
| Delete a run and all its items. Irreversible. Requires |
| Paginated list of items in a run. Requires |
| Create a run item linking a dataset item to a trace/observation. Creates the run automatically if it does not yet exist. |
Scores (6 tools)
Tool | Description |
| Paginated list of evaluation scores. Filter by |
| Fetch a single score by ID. |
| Paginated list of score config schemas. |
| Fetch a single score config by ID. |
| Create a score config. |
| Update an existing score config. Optionally set |
Annotation Queues (8 tools)
Tool | Description |
| Paginated list of annotation queues. |
| Fetch a single queue by ID. |
| Create a queue for human-in-the-loop review. Optionally link a |
| Paginated list of items in a queue. Optionally filter by |
| Fetch a specific queue item by |
| Add a trace, observation, or session to a queue for review. |
| Update the status of a queue item ( |
| Remove an item from a queue. Irreversible. |
Comments (3 tools)
Tool | Description |
| Paginated list of comments. Optionally filter by |
| Fetch a single comment by ID. |
| Attach a comment to a trace, observation, session, or prompt. |
Models (4 tools)
Tool | Description |
| Paginated list of all model definitions (Langfuse-managed and custom). |
| Fetch a model definition by ID. |
| Create a custom model for cost tracking. Requires |
| Delete a custom model definition. Langfuse-managed models cannot be deleted. Irreversible. |
LLM Connections (2 tools)
Tool | Description |
| Paginated list of LLM provider connections (secret keys are masked in the response). |
| Create or update a provider connection by |
Project (1 tool)
Tool | Description |
| Returns the project(s) visible to the configured API key. Useful for confirming credentials and project metadata. |
Users (1 tool)
Tool | Description |
| All traces for a specific Langfuse user ID with pagination. Requires |
Schema (1 tool)
Tool | Description |
| Returns the full Langfuse data model: all entity types, fields, and valid enum values. Call this first to understand the available data structures before running queries. |
Architecture
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 APIThe architecture is strictly layered:
client/— Langfuse integration boundary: HTTP with Basic-Auth (Apache HttpComponents 5), typed exceptions,UriComponentsBuilderfor query paramsservice/— domain logic: filtering, mapping, pagination, error translation intoApiResponsetools/— MCP surface: agent-friendly descriptions, parameter validation, delegation to servicesSpring Boot — runtime and transport wrapper only
API Client
LangfuseApiClient supports four HTTP methods. All methods throw LangfuseApiException or ResourceNotFoundException on error, which the service layer converts into structured ApiResponse.error(...) responses — agents never see raw stack traces.
Method | Used for |
| All read operations |
| Create operations |
| Update operations |
| Delete operations |
Package Structure
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 (14): Trace · Session · Prompt · PromptWrite · Dataset · DatasetRun
│ │ · Score · AnnotationQueue · Comment · Model · LlmConnection · Project · User · Schema
│ └── impl/ *ServiceImpl (14) — business logic, filtering, error mapping
├── tools/ @McpTool classes (14) — 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)
└── util/
└── JsonPageMapper.java Centralised JSON → PagedResponse mapper (no duplication)Running Tests
mvn testTest coverage includes:
LangfusePropertiesBindingTest— config binding fromapplication-test.ymland property-level validationPromptWriteServiceImplTest— service logic for prompt create / delete / label updateProjectServiceImplTest— project API response mappingObservationServiceImplTest— observation fetch and field mappingMetricsServiceImplTest— metrics aggregation logic
Tests run with spring.ai.mcp.server.enabled=false (set in src/test/resources/application-test.yml) so no MCP transport is started during test execution.
Troubleshooting
TRACE_FETCH_ERROR: HTTP/1.1 header parser received no bytes
Connectivity issue — not a code bug. Check:
LANGFUSE_HOSTpoints to a running Langfuse instanceThe host is reachable from the JVM process
For Docker: use
host.docker.internalinstead oflocalhostThe scheme matches your server (
http://vshttps://)Confirm the API is up:
curl $LANGFUSE_HOST/api/public/health
INVALID_INPUT: <param> is required
A required parameter was not provided. All required = true parameters are validated at the tool layer before any HTTP call is made.
Connection timeouts
Increase the timeout:
export LANGFUSE_TIMEOUT=60sAgent cannot see the server
Confirm the server is running:
curl http://localhost:8080/actuator/healthConfirm the MCP endpoint is reachable:
curl http://localhost:8080/pingCheck that the client config URL points to
http://localhost:8080/mcpInspect all available tools:
npx @modelcontextprotocol/inspector http://localhost:8080/mcp
Langfuse-managed models cannot be deleted
delete_model only works for custom model definitions you have created. To override a Langfuse-managed model's pricing, create a new custom model with the same modelName.