The oteltester service now exposes an MCP interface at /mcp that allows AI agents to interact with and control the oteltester functionality.
To use oteltester with MCP clients (such as Cursor, Claude Desktop, or other AI tools), add it to your MCP configuration.
- Start oteltester – The application must be running (e.g.
npm run devornpm start). - Default URL – oteltester listens at
http://localhost:3000by default.
| Client | Configuration File |
|---|---|
| Cursor | ~/.cursor/mcp.json (global) or .cursor/mcp.json (project) |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Other | Consult your client's MCP documentation |
Add oteltester to the mcpServers section:
{
"mcpServers": {
"oteltester": {
"url": "http://localhost:3000/mcp"
}
}
}{
"mcpServers": {
"oteltester": {
"url": "http://localhost:3000/mcp"
},
"other-server": {
"command": "node",
"args": ["path/to/other-mcp-server.js"]
}
}
}- Open Cursor Settings → Features → MCP
- Click + Add New MCP Server
- Select Streamable HTTP (or URL) as the transport type
- Enter:
- Name:
oteltester - URL:
http://localhost:3000/mcp
- Name:
- Save and refresh the MCP server list
You can also edit ~/.cursor/mcp.json directly with the JSON above.
If oteltester runs on a different host or port, adjust the URL accordingly:
{
"mcpServers": {
"oteltester": {
"url": "http://localhost:4000/mcp"
}
}
}For HTTPS (when using the built-in certs), use https://localhost:3001/mcp (or the port shown at startup).
After configuration:
- Restart your MCP client or refresh the MCP server list
- Ensure oteltester is running at the configured URL
- In Cursor: check MCP settings for a green status next to
oteltester - The Composer agent will have access to oteltester tools when relevant to your requests
The MCP interface implements the Model Context Protocol specification, providing a standardized way for AI agents to:
- Install and manage OpenTelemetry Collector and Refinery
- Configure and deploy collector/refinery configurations
- Start/stop processes
- Send test data
- Monitor outputs asynchronously
- MCP Endpoint:
POST http://localhost:3000/mcp - Task Status:
GET http://localhost:3000/mcp/tasks/:taskId
The MCP interface uses JSON-RPC 2.0 protocol. All requests should include:
jsonrpc:"2.0"id: Request identifiermethod: MCP method nameparams: Method parameters
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "tool_name",
"arguments": {
"param1": "value1"
}
}
}{
"jsonrpc": "2.0",
"id": 4,
"method": "tasks/get",
"params": {
"taskId": "task_1_1234567890"
}
}Or via HTTP GET:
GET /mcp/tasks/task_1_1234567890
In addition to tools (which perform actions), the MCP interface exposes resources for read-only access to system state. Resources provide AI agents with efficient discovery and status information without multiple tool calls.
{
"jsonrpc": "2.0",
"id": 5,
"method": "resources/list",
"params": {}
}{
"jsonrpc": "2.0",
"id": 6,
"method": "resources/read",
"params": {
"uri": "system://status"
}
}Complete system state in a single call. Replaces multiple tool calls (get_config, get_pids, version checks).
Example:
{
"version": "1.0.0",
"otelCollector": {
"installed": true,
"version": "0.142.0",
"running": false,
"pid": null,
"configPath": "./runtime/otelcol-config.yml",
"configExists": true
},
"refinery": {
"installed": true,
"version": "3.0.1",
"running": false,
"pid": null,
"configPath": "./runtime/refinery-config.yml",
"rulePath": "./runtime/refinery-rule.yml",
"configExists": true,
"ruleExists": true
},
"endpoints": {
"otlpHttp": "http://localhost:4318",
"otlpGrpc": "grpc://localhost:4317"
},
"system": {
"architecture": "arm64",
"platform": "darwin",
"is64bit": true
}
}Discover all available OTEL JSON templates with metadata.
Example:
{
"templates": [
{
"name": "simple_trace",
"path": "./templates/simple_trace.json",
"type": "trace",
"uri": "templates://simple_trace"
},
{
"name": "simple_log",
"path": "./templates/simple_log.json",
"type": "log",
"uri": "templates://simple_log"
}
]
}Get template content with metadata about placeholders and time fields.
Example: templates://simple_trace
{
"name": "simple_trace",
"path": "./templates/simple_trace.json",
"type": "trace",
"content": { ... },
"metadata": {
"placeholders": ["{{trace.1}}", "{{span.1}}"],
"timeFields": ["resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano"]
}
}All HTTP and WebSocket endpoints exposed by the server.
Example:
{
"http": {
"endpoints": [
{ "path": "/v1/traces", "method": "POST", "purpose": "Receive OTLP traces (HTTP)" },
{ "path": "/api/otel", "method": "POST", "purpose": "Send OTEL JSON data (internal API)" }
],
"baseUrl": "http://localhost:3000"
},
"websocket": {
"channels": [
{ "path": "/otelcol_out", "purpose": "OTEL Collector OTLP output" },
{ "path": "/refinery_out", "purpose": "Refinery batch output" }
],
"baseUrl": "ws://localhost:3000"
},
"otlp": {
"http": "http://localhost:4318",
"grpc": "grpc://localhost:4317"
}
}Parsed OTEL Collector configuration with pipeline structure.
Example:
{
"path": "./runtime/otelcol-config.yml",
"rawYaml": "...",
"parsed": {
"receivers": ["otlp", "filelog/simple"],
"processors": ["batch", "filter/log"],
"exporters": ["debug", "otlp/honeycomb"],
"extensions": [],
"pipelines": {
"logs": {
"receivers": ["otlp"],
"processors": ["batch"],
"exporters": ["debug"]
}
}
},
"fullConfig": { ... }
}Parsed Refinery configuration.
Example:
{
"path": "./runtime/refinery-config.yml",
"rawYaml": "...",
"parsed": { ... }
}Enhanced process information with context.
Example:
{
"processes": [
{
"pid": "12345",
"type": "otelcol",
"command": "./runtime/otelcol-contrib --config=...",
"user": "howardyoo",
"startTime": "10:30",
"configPath": "./runtime/otelcol-config.yml"
}
]
}List all saved JSON files with metadata.
Example:
{
"saved": [
{
"name": "test_trace",
"path": "./saved/test_trace.json",
"type": "trace",
"size": 2363,
"modified": "2025-01-25T18:13:00Z",
"uri": "saved://test_trace"
}
]
}Get saved JSON with validation results.
Example: saved://test_trace
{
"name": "test_trace",
"path": "./saved/test_trace.json",
"type": "trace",
"content": { ... },
"validation": {
"valid": true,
"errors": []
}
}All available versions for OTEL Collector and Refinery (cached for 5 minutes).
Example:
{
"otelCollector": ["0.142.0", "0.141.0", ...],
"refinery": ["3.0.1", "3.0.0", ...]
}Available OTEL Collector modules.
Example:
{
"version": "0.142.0",
"receiver": ["otlp", "filelog", "hostmetrics", ...],
"processor": ["batch", "filter", "transform", ...],
"exporter": ["debug", "otlp", "otlphttp", ...]
}OTEL JSON schema for validation reference.
Latest outputs (traces, metrics, logs) received from the OTEL Collector.
Example:
{
"count": 5,
"outputs": [
{
"type": "traces",
"data": { "resourceSpans": [...] },
"timestamp": "2024-01-15T10:30:00Z"
}
],
"note": "Outputs are ordered from newest to oldest"
}Latest outputs (traces, metrics, logs) received from Refinery.
Latest console output (stdout/stderr) from the OTEL Collector process.
Example:
[2024-01-15T10:30:00Z] 2024-01-15T10:30:00.000-0500 info service/service.go:161 Starting otelcol-contrib...
[2024-01-15T10:30:01Z] 2024-01-15T10:30:01.000-0500 info service/service.go:200 Everything is ready.
Latest console output (stdout/stderr) from the Refinery process.
Skills are read-only resources that teach AI agents how to use oteltester effectively. Read these to learn workflows, tool usage, and verification strategies.
| Resource | Purpose |
|---|---|
skills://list |
List all available skill resources |
skills://overview |
Executive overview of oteltester capabilities |
skills://installation |
Install and run different versions of OTEL Collector and Refinery |
skills://configuration |
Formulate YAML configs for OTEL Collector and Refinery |
skills://testing-workflow |
Submit OTLP JSON, monitor logs, re-submit to Refinery |
skills://collector-verification |
Verify OTEL Collector config correctness |
skills://refinery-verification |
Verify Refinery sampling rules |
skills://honeycomb-forwarding |
Send data to Honeycomb (requires API key from user) |
Example: skills://overview returns structured JSON describing what oteltester can do and which skills to read next. Each skill includes tool references, resource references, and step-by-step workflows.
Recommended order for agents: Start with skills://overview, then skills://installation if binaries need to be installed, then skills://configuration and skills://testing-workflow for the core testing flow.
When to use Resources:
- Read-only operations
- System state discovery
- Listing available options
- Understanding current configuration
When to use Tools:
- Modify state (install, start, stop)
- Send data
- Write files
- Create/delete saved JSON
Efficiency Comparison:
| Task | With Tools Only | With Resources | Improvement |
|---|---|---|---|
| Check system ready | 4-5 calls (get_config, get_pids, version checks) | 1 read (system://status) | 75% reduction |
| Find test template | Guess filenames, multiple get_json calls | 1 read (templates://list) | Enables discovery |
| Understand config | get_yaml + parse YAML yourself | 1 read (config://otelcol) | No client parsing |
get_config- Get current configurationsave_config- Save configuration
get_otelcol_versions- List available Collector versionsget_refinery_versions- List available Refinery versionsget_otelcol_version- Get installed Collector versionget_refinery_version- Get installed Refinery versioninstall_otelcol- Install Collector (async)install_refinery- Install Refinery (async)
get_pids- List running processesstart_otelcol- Start Collector (async output)start_refinery- Start Refinery (async output)stop_process- Stop a process by PIDrefresh_process- Reload config for a process
get_yaml- Read YAML filesave_yaml- Save YAML fileget_json- Read JSON filesave_json- Save JSON file
list_saved_json- List saved JSON filesget_saved_json- Get saved JSON by namesave_saved_json- Save JSON to saved directorydelete_saved_json- Delete saved JSON
send_otel_json- Send OTEL JSON to endpoint (async)get_otelcol_output- Collect Collector output (async)get_refinery_output- Collect Refinery output (async)
get_latest_otelcol_output- Get latest outputs from OTEL Collector buffer (traces, metrics, logs)get_latest_refinery_output- Get latest outputs from Refinery bufferforward_otelcol_output_to_refinery- Forward Collector output directly to local Refineryforward_output_to_target- Forward output from otelcol or refinery to any target URLclear_output_buffer- Clear the output buffer (otelcol, refinery, or both)
get_otelcol_console_output- Get latest console output (stdout/stderr) from Collector (tail)get_refinery_console_output- Get latest console output (stdout/stderr) from Refinery (tail)get_console_output_paginated- Get console output with pagination supportsearch_console_output- Search console output for patterns (errors, warnings, etc.)clear_console_buffer- Clear the console output buffer (otelcol, refinery, or both)
get_otelcol_modules- Get available Collector modules
Many operations (installations, process starts, output collection) are asynchronous. These operations return a taskId and taskUri that can be polled to check status and retrieve results.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "start_otelcol",
"arguments": {}
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "task_1_1234567890",
"pid": 12345,
"message": "otelcol started successfully",
"taskUri": "/mcp/tasks/task_1_1234567890"
}
}Polling Task Status:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tasks/get",
"params": {
"taskId": "task_1_1234567890"
}
}Task Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"id": "task_1_1234567890",
"type": "start_otelcol",
"status": "running",
"createdAt": "2024-01-15T10:30:00Z",
"data": {
"pid": 12345
},
"output": [
{
"type": "stdout",
"data": "Collector started..."
}
],
"error": null
}
}running- Task is in progresscompleted- Task finished successfullyfailed- Task encountered an error
The get_otelcol_output and get_refinery_output tools create tasks that collect output for a specified duration. Output includes:
- Process stdout/stderr
- OTLP traces/metrics/logs received
- Batch data (for refinery)
Output is collected in real-time and can be polled via the task status endpoint.
Errors are returned in the standard JSON-RPC error format:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "Error description",
"data": "Additional error details"
}
}- Get available versions:
{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "get_otelcol_versions", "arguments": {}}}- Install Collector:
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "install_otelcol", "arguments": {"version": "0.118.0"}}}- Poll installation status:
{"jsonrpc": "2.0", "id": 3, "method": "tasks/get", "params": {"taskId": "task_2_..."}}- Get configuration:
{"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "get_config", "arguments": {}}}- Save configuration:
{"jsonrpc": "2.0", "id": 5, "method": "tools/call", "params": {"name": "save_yaml", "arguments": {"path": "...", "content": "..."}}}- Start Collector:
{"jsonrpc": "2.0", "id": 6, "method": "tools/call", "params": {"name": "start_otelcol", "arguments": {}}}- Send test data:
{"jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": {"name": "send_otel_json", "arguments": {"url": "http://localhost:8080", "json": {...}}}}AI agents can retrieve outputs from OTEL Collector and Refinery buffers, and forward them to targets for further testing.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_latest_otelcol_output",
"arguments": {
"count": 10
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"outputs": [
{
"type": "traces",
"data": { "resourceSpans": [...] },
"timestamp": "2024-01-15T10:30:00Z"
}
],
"count": 1
}
}Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "forward_otelcol_output_to_refinery",
"arguments": {
"outputIndex": 0
}
}
}Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "forward_output_to_target",
"arguments": {
"source": "otelcol",
"targetUrl": "https://api.honeycomb.io",
"outputIndex": 0,
"headers": {
"x-honeycomb-team": "your-api-key"
}
}
}
}AI agents can monitor and check the console output (stdout/stderr) from otelcol and refinery processes to understand what's happening and detect errors.
Get the latest N lines from the console output buffer:
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_otelcol_console_output",
"arguments": {
"lines": 50
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"source": "otelcol",
"lines": [
{
"line": "2024-01-15T10:30:00.000-0500\tinfo\tservice/service.go:161\tStarting otelcol-contrib...",
"timestamp": "2024-01-15T15:30:00Z"
}
],
"total": 150,
"returned": 50,
"output": "[2024-01-15T15:30:00Z] 2024-01-15T10:30:00.000-0500\tinfo\tservice/service.go:161\tStarting otelcol-contrib..."
}
}Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_console_output_paginated",
"arguments": {
"source": "otelcol",
"page": 1,
"pageSize": 50
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"source": "otelcol",
"page": 1,
"pageSize": 50,
"totalLines": 500,
"totalPages": 10,
"hasMore": true,
"lines": [...],
"output": "..."
}
}Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_console_output",
"arguments": {
"source": "otelcol",
"pattern": "error|failed|warn",
"caseSensitive": false
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"source": "otelcol",
"pattern": "error|failed|warn",
"matchCount": 15,
"totalLines": 500,
"matches": [
{
"index": 42,
"line": "2024-01-15T10:30:00.000-0500\twarn\tottl@v0.142.0/parser.go:410\tfailed to execute statement...",
"timestamp": "2024-01-15T15:30:00Z"
}
],
"matchedLines": "[2024-01-15T15:30:00Z] Line 42: 2024-01-15T10:30:00.000-0500\twarn\t..."
}
}Request:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "clear_console_buffer",
"arguments": {
"source": "both"
}
}
}When AI agents perform actions via MCP (configuration changes, data submission, output forwarding), these actions are automatically broadcast to connected browser UIs via WebSocket. The UI displays notifications for:
- Config Saved - When configuration files are saved
- OTEL Data Submission - When data is submitted via MCP
- Process Started/Stopped - When processes are started or stopped
- Output Forwarding - When outputs are forwarded to targets
- Buffer Cleared - When output/console buffers are cleared
This allows users to monitor AI agent activity in real-time through the browser interface.
- Authentication is not currently implemented (local use only)
- Tasks are automatically cleaned up after 1 hour
- WebSocket connections are used internally for real-time output
- All file paths should be relative to the working directory or absolute paths
- Console output buffers store up to 500 lines per process
- Output buffers store up to 50 outputs per source (otelcol/refinery)