Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.getmuster.io/llms.txt

Use this file to discover all available pages before exploring further.

How it works

OpenTelemetry (OTel) ingestion is built directly into the Muster backend. There is no sidecar connector to deploy — your agents export traces straight to your Muster instance over HTTPS. This gives full coverage across:
  • Any language (Python, Go, Java, Node.js, Rust)
  • Any framework with OTel support (LangChain, CrewAI, LlamaIndex, custom agents)
  • Agents that don’t have a dedicated Muster connector

What your developers do

Set three environment variables on your agent. That’s it.
OTEL_EXPORTER_OTLP_ENDPOINT=https://backend.YOUR-INSTANCE.getmuster.io/api/v1/otel
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <muster-jwt-token>
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
Get the JWT by calling POST /auth/login with a service account user, or copy it from your Muster dashboard → Settings → API Access. No code changes are required if your agent already emits OTel spans.

Adding OTel to a Python agent

If your agent doesn’t yet emit OTel spans, add instrumentation once at startup:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
import os

# Configure once at startup
provider = TracerProvider()
provider.add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(
        endpoint=os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] + "/v1/traces",
        headers={"Authorization": f"Bearer {os.environ['MUSTER_JWT']}"},
    ))
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-agent", service_name="invoice-processor")

# Instrument your agent runs
def run_agent(input: str) -> str:
    with tracer.start_as_current_span("agent.run") as span:
        span.set_attribute("service.name", "invoice-processor")
        result = llm.invoke(input)
        span.set_attribute("gen_ai.usage.input_tokens", result.usage.prompt_tokens)
        span.set_attribute("gen_ai.usage.output_tokens", result.usage.completion_tokens)
        span.set_attribute("gen_ai.response.model", "gpt-4o")
        return result.content
The service.name attribute becomes the agent name in Muster. New service names are auto-added to your Discovery queue for review.

LangChain — zero-code instrumentation

If you use LangChain, one line enables automatic tracing of all chains and agents:
from opentelemetry.instrumentation.langchain import LangchainInstrumentor
LangchainInstrumentor().instrument()
# All chains, agents, and LLM calls now emit OTel spans automatically
Then set the three env vars above and Muster receives full trace data immediately.

Check connection status

GET /api/v1/otel/status
Authorization: Bearer <token>
Returns current connector status, executions received in the last 24 hours, and the exact env vars to use for your instance.

What Muster does automatically

Once traces arrive:
ActionDetails
Agent discoveryNew service.name values appear in Discovery as UNREVIEWED
Execution recordingEach agent span stored as a connector execution
Cost trackingToken usage attributes → cost events (for approved agents)
Quality inferenceCheck inference runs server-side on each execution

Supported semantic conventions

AttributeDescription
service.nameAgent name (required)
gen_ai.usage.input_tokensPrompt token count (GenAI convention)
gen_ai.usage.output_tokensCompletion token count (GenAI convention)
gen_ai.response.modelModel name
gen_ai.request.modelRequested model name
llm.usage.prompt_tokensPrompt tokens (LangChain format)
llm.usage.completion_tokensCompletion tokens (LangChain format)
llm.model_nameModel name (LangChain format)

Supported agent span names

Muster identifies root agent executions from these span names (partial match): agent.run, agent.execute, agent.invoke, langchain.chain, langchain.agent, crewai.task, crewai.agent, openai.chat, anthropic.messages, bedrock.invoke, llm.completion, chain.run, tool.run To add custom span names, contact Elitery.

Why OTel instead of a platform connector?

OTelPlatform connector
Code changes3 env varsNone
Framework coverageUniversalPer-platform only
Data richnessFull traces + spansAPI metadata only
LatencyReal-timePolling (minutes)
Works on no-code tools (n8n, Flowise)NoYes
Use OTel for custom-coded agents. Use platform connectors for no-code/low-code tools where you can’t set env vars.