# How to Monitor MCP Servers in Production

> Monitor MCP servers in production: tool-call success rate, errors, p95 latency per tool, alerts, multi-client usage, users and outcomes.

Source: https://flowlines.ai/blog/mcp-observability-guide · Updated 2026-10-22 · By Flowlines
Index of all Flowlines pages for AI agents: https://flowlines.ai/llms.txt

To monitor MCP servers in production, track tool calls, errors and latency with OpenTelemetry, then connect that activity to users and outcomes. **Flowlines helps you see who uses your MCP, what they are trying to do, where they get stuck, and which signals deserve your team's attention.** Configure what matters to you and get findings in Slack, email or a webhook after analysis.

A fast MCP server can still be a disappointing product. Monitor both: whether it works technically and whether people can do something useful with it. Each section below answers one question teams ask after launch, from tool-call success rate and p95 latency to alerts, multi-client usage and release comparisons.

## How do people monitor MCP servers in production?

Teams monitor MCP servers in four layers: service health, individual tool calls, user journeys and business signals, each with its own data source and owner. Flowlines covers the last two: who uses your MCP, from which AI client, what they are trying to do, and which findings need a follow-up.

| Layer | Question it answers | Typical source | Usual owner |
|---|---|---|---|
| Service health | Is the server reachable and responsive? | Independent probes and infrastructure metrics | Platform or SRE |
| Tool calls | Which tools run, fail or slow down? | OpenTelemetry spans and metrics per tool | MCP engineering |
| User journeys | Who uses the MCP, for which job, and do they finish? | Session analytics on permitted identity and context | Product |
| Business signals | Which observed behavior deserves a follow-up? | Configured signals, reviewed after analysis | Sales, success and product |

Most teams cover the first two layers in an existing metrics or tracing backend. The last two layers need product analytics, because a tool call does not say who asked for it or whether the job got done.

### Start with the job your MCP should complete

**Tool success is not user success.** A successful search says nothing about whether the requested report was created or the customer came back.

Consider a synthetic sales-research journey. An agent calls an account lookup three times, reads a company's public profile, then stops before creating the requested sales brief. Every call returns successfully. Technical monitoring sees no tool errors. Product analytics sees an incomplete journey and repeated work.

Now suppose the captured request also asks about private deployment. In Flowlines, you can configure a buying-intent signal and send the finding to your sales channel, while engineering investigates the repeated lookups.

> **Example Slack notification · Synthetic data:** Buying signal detected. A user asked about private deployment while researching accounts. Review the session and decide whether to follow up.

One journey can inform three teams: engineering sees a blocker, product sees an unfinished job, and sales sees a potential opportunity. This example assumes request context that you have approved for capture; tool names alone do not establish buying intent.

| What you observe | What it can tell you | What to do next |
|---|---|---|
| Repeated account lookups in one journey | Possible confusion, retries or a legitimate refinement | Compare the inputs you are permitted to inspect and the expected path |
| No sales brief completion event | Completion is unverified | Check whether the event is missing or the workflow stopped |
| A returning account tries several workflows | Evidence of repeat adoption | Review successful use cases and friction for that account |
| An approved request asks about private deployment | Possible buying intent | Notify the appropriate team for a contextual review |

This is what [Flowlines MCP analytics](https://flowlines.ai/blog/mcp-analytics) adds to call counts: users, use cases, journeys and findings your team can act on. Start with one question you want answered, such as “What keeps users from finishing?” or “Who is asking about enterprise deployment?”

## Get notified about user behavior and business signals

**Tell Flowlines what to watch.** Configure signals for buying intent, unmet needs, recurring problems or other observed behavior. Route findings to Slack, email or a webhook, with real-time delivery after analysis or daily and weekly digests.

These are example signals to configure, not customer results:

| Team | Example signal to configure | What the recipient reviews |
|---|---|---|
| Engineering | A journey repeats a lookup without making progress | The observed tool path and possible recovery |
| Product | A request needs an export format the MCP does not support | Available request context and the missing capability |
| Sales | A request shows evaluation intent around private deployment | The permitted account context and actual wording |
| Customer success | A user repeatedly hits a blocker during an important workflow | The affected user and sessions that explain the problem |

Start with the signal that would change what your team does next. Review the first findings, refine the definition, and choose who receives them. [Explore Flowlines signals](https://flowlines.ai/mcp-observability#signals).

## The quickest path to Flowlines monitoring

You do not need to assemble a new observability stack before trying Flowlines.

1. Connect Flowlines to your coding assistant or install the [official Flowlines plugin](https://github.com/flowlines-ai/plugins). Open your MCP server repository.
2. Ask: **Onboard my MCP server to Flowlines.**
3. Review the OpenTelemetry instrumentation plan, including what data leaves your server, and approve the changes.
4. Ask: **Check my Flowlines onboarding and fix anything missing.** Run the proposed tests and verify again after deployment.

The assistant guides workspace and namespace API key setup when needed. Keep credentials in your environment or secret manager. The onboarding check verifies the instrumentation before you rely on its data.

No proprietary Flowlines runtime SDK or additional tracing platform is required. If you already run an OTel pipeline, keep it. The manual details below help you understand and review the plan.

Start with one server, ask a real product question, and review your first findings. The [Free plan](https://flowlines.ai/pricing) includes 100 analyzed MCP sessions per month, no credit card and no teammate limit. The [four-step onboarding guide](https://flowlines.ai/docs) walks through setup and verification. Reaching the free analysis allowance does not throttle your MCP server.

## What should I monitor after launching an MCP server?

After launch, monitor six production signals for every server and tool (availability, traffic, latency, errors, saturation and security), then add user and outcome measurements once the technical data is trustworthy.

### The six production signals

| Signal | What to measure on an MCP server | Example starting threshold | Where it comes from |
|---|---|---|---|
| Availability | Successful independent probes, such as a synthetic `tools/list` request or a read-only tool call, divided by attempted probes | Several consecutive probe failures | Synthetic checks from outside the server |
| Traffic | Tool calls per minute by server, tool and client; distinct users per day | No expected traffic during a known busy window | Tool-call counter and analytics identity |
| Latency | p50, p95 and p99 duration per tool, in seconds | p95 above your objective for 5 minutes | Duration histogram |
| Errors | Error ratio per tool, split into transport, JSON-RPC and tool-result failures | More than 5% over 5 minutes with at least 100 attempts | Classified tool-call counter and spans |
| Saturation | In-flight requests against the concurrency limit, queue time, connection pools and upstream 429 responses | Sustained use above 80% of a known limit | Runtime, dependency and gateway metrics |
| Security | Rejected authentication, denied authorization, unexpected clients and sensitive values found in telemetry | A sustained rise above a reviewed baseline | Auth boundary, gateway and telemetry audits |

These thresholds are example starting points to tune against your own objectives, not MCP industry averages. A scrape target being up does not prove a tool works, so probe the MCP operation itself.

### Product and adoption measurements

Use separate views for service health, individual tool executions and user journeys. Define each denominator before comparing a percentage across releases.

| Measurement | Definition and source | Important limitation |
|---|---|---|
| Availability | Successful independent health probes divided by attempted probes | A scrape target being up does not prove a tool works |
| Calls per tool | Count of observed tool executions, grouped by tool name | Retries are additional attempts, not additional users |
| Tool error rate | Failed classified attempts divided by all classified attempts | Split transport, JSON-RPC and tool-result failures; report unknowns separately |
| Tool latency | Duration distribution for the same tool and server, in seconds | Compare p50, p95 and p99; an average hides the tail |
| Auth and protocol failures | Rejected authentication and failed protocol operations | Count at the boundary where rejection happens, even if no tool span exists |
| Unique users and returning users | Distinct permitted identities and identities active in both comparison windows | Anonymous calls and sampling limit coverage |
| Tools with no observed use | Catalogued tools with zero observed calls in the selected window | Missing instrumentation is not proof of no demand |
| Calls per completed journey | Tool attempts in completed journeys divided by completed journeys | Compare the same use case; keep incomplete journeys visible |
| Outcome coverage | Journeys with an assessable outcome divided by all observed journeys | Unknown outcomes must not become successes |
| Buying-intent incidence | Sessions flagged for buying intent divided by sessions evaluated for that signal | A detector result is not a qualified opportunity or revenue |
| Telemetry coverage | Observed executions compared with an independent execution count | Sampling, dropped exports and duplicate spans distort the comparison |

The user, journey and business measurements are derived analytics, not built-in OTel metrics.

## How do I add health and readiness checks to an MCP server?

Expose a liveness check for the process, a readiness check for the dependencies a tool needs, and run an MCP-level probe from outside that calls the server the way a client would.

| Check | What it answers | Example for a Streamable HTTP server |
|---|---|---|
| Liveness | Is the process running and able to respond? | A lightweight `/healthz` route that does not touch dependencies |
| Readiness | Can it serve tools right now? | A `/readyz` route that checks the database, upstream API credentials and auth provider |
| MCP probe | Does the protocol path work end to end? | A scheduled `tools/list` request and one read-only tool call with a synthetic account |

Keep health routes separate from the MCP endpoint and unauthenticated only if they reveal nothing sensitive. A failing readiness check should take an instance out of rotation, not restart it; restart on repeated liveness failures. Record probe results as their own metric so availability is not inferred from user traffic. A stdio server has no network endpoint: the client starts and stops the process, so health is the success of each session start and the first request, measured on the client side or in opt-in telemetry.

## How do I monitor MCP tool calls and errors?

Record one span and one classified outcome for every tool execution at the server's tool boundary, then track transport, JSON-RPC and tool-result failures as separate categories.

### Classify failures at three layers

| Layer | Synthetic example | How it appears |
|---|---|---|
| Transport | Connection reset, HTTP 5xx or a crashed stdio process | No valid JSON-RPC response reaches the client |
| JSON-RPC | Malformed request or unknown method | A response with an `error` object |
| Tool result | Account not found or an upstream API refused the request | A `result` with `isError: true` |

An HTTP 200 response can contain a JSON-RPC error or a successful JSON-RPC envelope with a failed tool result. Inspect all three layers. This synthetic response is a tool failure, not a transport failure:

```json
{
  "jsonrpc": "2.0",
  "id": "synthetic-check-1",
  "result": {
    "content": [{ "type": "text", "text": "Account not found" }],
    "isError": true
  }
}
```

Keep cancellations separate and define which attempts belong in your success-rate denominator. A timeout means the observer did not receive a result in time; it does not prove a downstream write never happened. A tool error is not always user failure: a failed attempt followed by a successful recovery can still produce a completed user journey.

### Use the MCP semantic conventions

The [OTel MCP conventions](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/mcp.md) are in Development, not stable. Check support in your installed instrumentation before relying on these identifiers:

| Identifier | Use |
|---|---|
| `mcp.method.name` | Operation, such as `tools/call` |
| `gen_ai.tool.name` | Tool being invoked |
| `error.type` | Failure classification; `tool_error` for a tool result with `isError: true` |
| `rpc.response.status_code` | JSON-RPC error code when present |
| `mcp.server.operation.duration` | Server operation histogram in seconds |
| `mcp.client.operation.duration` | Client-observed operation histogram in seconds |

For a JSON-RPC failure, use its error-code string as the error type; transport failures use their own classification. A server span can be named `tools/call find_account` with SERVER kind. Record arguments and results only under an explicit capture policy: the conventions mark them opt-in.

## How do I track the success rate of MCP tool calls?

Divide successful classified attempts by all classified attempts for the same tool, server, environment and time window, and report cancellations and unknown results outside that ratio.

| Count for one tool, one day | Synthetic value | In the denominator? |
|---|---:|---|
| Successful tool results | 1,840 | Yes |
| Tool results with `isError: true` | 96 | Yes |
| JSON-RPC errors | 24 | Yes |
| Transport failures observed at the server | 40 | Yes |
| Cancelled by the client | 30 | No, report separately |
| Unknown result, such as a lost export | 10 | No, report separately |

The success rate is 1,840 out of 2,000 classified attempts, or 92%, with 40 attempts reported beside the ratio rather than hidden in it.

The PromQL examples in this guide use a custom normalized counter, `mcp_tool_calls_total`, with `service_name`, `environment`, `tool` and `outcome` labels. It is described in the alerting section below; map it to the metric names your pipeline actually exports.

```promql
sum by (service_name, environment, tool) (increase(mcp_tool_calls_total{outcome="success"}[1d]))
/
sum by (service_name, environment, tool) (increase(mcp_tool_calls_total{outcome=~"success|error"}[1d]))
```

Tool-call success is not task success. For example, in a synthetic set of 100 journeys, 70 have assessable outcomes and 56 succeed. Report 80% success among assessed journeys **and** 70% outcome coverage, not 80% success across all users.

## How do I find which MCP tools fail most?

Rank tools by failed attempts and by error ratio over the same window, require a minimum volume, then break the top tools down by error class, client and affected users.

```promql
topk(5,
  sum by (service_name, environment, tool) (increase(mcp_tool_calls_total{outcome="error"}[1d]))
)
```

| Ranking | What it shows | Caveat |
|---|---|---|
| Most failed attempts | Where users hit errors most often | High-traffic tools dominate the list |
| Highest error ratio with at least 100 attempts | Fragile tools regardless of traffic | Low-volume tools need event-based review |
| Most affected users or accounts | Customer impact | Needs permitted identity; retries inflate attempts, not users |
| Most failed journeys after the tool fails | Failures that block the job | Needs journey and outcome analysis |

Then group the top tools by `error.type` in your traces. A tool that fails mostly with argument errors may need a clearer input schema or description rather than a backend fix, while repeated upstream timeouts point to a dependency.

## How do I track latency (p50, p95, p99) per MCP tool?

Record a duration histogram in seconds for every tool execution and calculate p50, p95 and p99 per server and tool from aggregated buckets, never by averaging percentiles.

```promql
histogram_quantile(0.95,
  sum by (service_name, environment, tool, le) (rate(mcp_tool_duration_seconds_bucket[5m]))
)
```

Replace 0.95 with 0.5 or 0.99 for the other percentiles. The query uses the custom classic histogram `mcp_tool_duration_seconds_bucket`; in OpenTelemetry the corresponding server histogram is `mcp.server.operation.duration`, and its exported name depends on your pipeline.

| Percentile | What it tells you | Watch out for |
|---|---|---|
| p50 | The typical call; moves when the common path changes | A stable median can hide a slow tail |
| p95 | The slow calls a regular user eventually hits; a good alert candidate | Needs enough calls per window |
| p99 | Rare outliers such as cold starts, large inputs or slow dependencies | Noisy below a few hundred calls per window |

Choose bucket boundaries around your objective, for example from 0.1 to 10 seconds for tools that call external APIs. Compare equivalent work: a search across a large account is not the same workload as a cached lookup. See [Prometheus histogram guidance](https://prometheus.io/docs/practices/histograms/).

## How do I monitor tool response size and token cost?

Record the size of every tool result in bytes per tool, and treat large or growing responses as a cost and quality problem because the client model has to read them.

The server cannot see the client's token bill, but response size is a good proxy: every byte returned goes into the model's context window. Track a histogram of serialized result size per tool and watch p95 and maximum after each release. A rough estimate is about four characters per token for English text; use the client model's tokenizer when you need exact numbers.

| Pattern | Likely cause | What to change |
|---|---|---|
| p95 response size jumps after a release | A tool now returns full records or nested objects | Return the fields the task needs and offer a detail tool |
| One tool dominates total bytes | Unpaginated lists or raw documents | Add pagination, limits and summaries |
| Large responses followed by repeated calls | The model cannot use what it received | Shorten and structure the result; check the description |
| Truncated results reported by clients | Output exceeds client limits | Cap size on the server and say what was omitted |

Name the metric as your own, for example a custom `mcp_tool_response_bytes` histogram with the same `service_name`, `environment` and `tool` labels; response size is not part of the MCP semantic conventions. Measure size without exporting the content itself.

## How do I get alerts when MCP errors spike?

Alert on the error ratio per server, environment and tool over a rolling window, require a minimum number of attempts, and require the condition to persist before notifying an owner with a runbook.

Operational alerts should identify the affected server and tool, link a runbook, and reach someone responsible for the response. Decide thresholds from your workload and service objectives, not an alleged MCP industry average.

| Condition | Example starting rule | First investigation |
|---|---|---|
| Elevated tool errors | More than 5% errors over 5 minutes, at least 100 classified attempts, sustained for 5 minutes | Error classes, recent release and affected users |
| Slow tool calls | p95 above 2 seconds over 5 minutes, sustained for 5 minutes | Downstream dependency and traffic mix |
| Server unavailable | Independent probe fails repeatedly | Deployment, routing and dependency readiness |
| Upstream throttling | A sustained rise in 429 responses for one dependency | Quota, retry behavior and request concurrency |
| Saturation | In-flight requests above 80% of the concurrency limit for 10 minutes | Traffic growth, slow dependencies and scaling limits |
| Authentication failures | Rejected requests well above the reviewed baseline for 10 minutes | Expired credentials, client changes or probing |
| Unexpected silence | No expected traffic, checked against a known schedule | Scrape/export health before declaring a usage drop |

These are example policies to tune, not default Flowlines rules. Low-volume tools may need event-based alerts instead of a percentage threshold.

### Copyable Prometheus example

The following rule uses a **custom normalized counter**, `mcp_tool_calls_total`, with `service_name`, `environment`, `tool` and `outcome` labels. It is not an official OTel metric or a metric Flowlines promises to expose. Adapt your instrumentation or recording pipeline first: count each classified attempt once, with outcome success or error; keep unknown and cancelled attempts separate. Record metrics before trace sampling, or disclose the sampling limitations.

```yaml
groups:
  - name: mcp-production-examples
    rules:
      - alert: MCPToolErrorRateHigh
        expr: |
          (
            sum by (service_name, environment, tool) (rate(mcp_tool_calls_total{outcome="error"}[5m]))
            /
            sum by (service_name, environment, tool) (rate(mcp_tool_calls_total{outcome=~"success|error"}[5m]))
          ) > 0.05
          and
          sum by (service_name, environment, tool) (increase(mcp_tool_calls_total{outcome=~"success|error"}[5m])) >= 100
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Sustained MCP tool errors"
```

The [downloadable rules](https://flowlines.ai/examples/mcp-monitoring/alerts.yml) also include a p95 rule using the custom classic histogram `mcp_tool_duration_seconds_bucket`. Map the actual exported metric and label names, preserve the bucket boundary label for histogram calculations, and choose buckets around your objective. Do not average per-instance percentiles. See [Prometheus alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/).

Rule fixtures cover sustained failures, recovery, low volume, zero traffic, brief spikes and slow calls. Verified with promtool 3.5.0 on October 16, 2026. Download the [synthetic rule tests](https://flowlines.ai/examples/mcp-monitoring/alerts.test.yml) beside alerts.yml and run `promtool test rules alerts.test.yml`. Add your team's owner, runbook and notification routing before use. Missing metrics need a separate availability or telemetry alert; these rules cannot detect them by themselves.

## How do I monitor several MCP servers in one place?

Send every server's telemetry to one backend with a distinct `service.name`, plus `deployment.environment.name` and `service.version`, then compare tools within a server and environment before aggregating across the fleet. Flowlines shows every instrumented server in one inventory, with adoption and returning users per server.

| Resource attribute | Example | Why it matters |
|---|---|---|
| `service.name` | `sales-mcp`, `billing-mcp` | Separates servers that expose tools with the same name |
| `deployment.environment.name` | `production`, `staging` | Keeps test traffic out of production rates |
| `service.version` | `2026.10.16` | Enables release comparisons per server |

Use the same metric names, label names and outcome classification on every server, or fleet dashboards will compare different definitions. Filter by server and environment before comparing tools with the same name, and keep a per-server view of telemetry coverage so one silent exporter does not look like a quiet week. [Server analytics](https://flowlines.ai/mcp-server-analytics) should make the observed inventory and coverage clear.

## How do I monitor the same MCP server across Claude and ChatGPT?

Instrument the server once and segment its activity by the client metadata your integration exposes, with an explicit unknown bucket, rather than running separate monitoring per client. Flowlines shows which users call each tool, from which AI client, and what they were trying to do.

### Which AI clients connect

Under the stateless 2026-07-28 MCP revision there is no initialization handshake, so a client describes itself on each request in `_meta["io.modelcontextprotocol/clientInfo"]`, with a name and version. Servers on earlier revisions receive the same `clientInfo` once, in the `initialize` request. Record the client name and version as low-cardinality attributes on every tool span, and map variants such as desktop and web builds to one client family for reporting.

Where the integration exposes client metadata, segment Claude, ChatGPT and other callers. Client names are self-reported and are not authenticated identity. Different clients may attempt different jobs, so a raw error-rate comparison can be misleading.

| Compare per client | What a difference can mean |
|---|---|
| Tool calls and distinct users | Adoption differs between clients or marketplaces |
| Error ratio per tool | One client sends arguments your schema does not expect |
| Calls per completed journey | One client needs more attempts for the same job |
| Share of unknown clients | Some integrations do not send client metadata |

### Keep users and sessions separate from clients

For [per-user analytics](https://flowlines.ai/users), use a permitted stable application identity or pseudonymous account identifier. Do not use email addresses as metric labels. Keep individual identities and journey IDs in access-controlled traces or analytics records rather than multiplying every time series by user. Analytics identity never replaces authorization.

For [sessions](https://flowlines.ai/mcp-session-analytics), use a validated application-level relationship between calls. Protocol behavior depends on revision and transport; a protocol session is not necessarily a product journey. Do not merge unrelated calls just because they arrive close together. Keep unknown users, uncorrelated calls and unavailable outcomes visible.

## How do I compare MCP usage before and after changing a tool?

Tag every release with `service.version`, then compare the same tool, environment, client mix and window length before and after the change, with telemetry and outcome coverage reported beside every rate. Flowlines compares releases by users, journeys and outcomes, not only by call counts.

| Synthetic measurement for `find_account` | 7 days before | 7 days after |
|---|---:|---:|
| Tool calls | 4,200 | 3,100 |
| Distinct users | 310 | 335 |
| Error ratio | 6.1% | 2.4% |
| p95 latency | 1.8 s | 1.9 s |
| Calls per completed journey | 3.4 | 2.1 |
| Outcome coverage | 72% | 70% |

Fewer calls from more users, with fewer calls per completed journey, suggests a clearer tool description reduced retries rather than demand falling. Review sessions from both windows before concluding: this is an observational comparison, not proof of cause. Renaming a tool or rewriting its description changes how models select it, so watch neighboring tools too.

For [tool adoption](https://flowlines.ai/mcp-tool-analytics), count distinct users, returning users and successful journeys as well as executions. Calling a tool unused requires the tool catalog and sufficient telemetry coverage. No observed calls can mean no demand, poor discovery or a broken export path. To compare releases in Flowlines, see [release comparison](https://flowlines.ai/deploys).

## How do I monitor stdio or locally installed MCP servers?

For servers that run on users' machines, ship opt-in telemetry that records counts, durations and classified errors, sends them over HTTPS to your own endpoint, and never writes to stdout.

A locally installed server has no central endpoint to probe and no infrastructure you own. Everything you know comes from the process on the user's machine, so the consent and data boundary matter more than on a hosted server.

1. **Ask first.** Keep telemetry off until the user enables it, for example with `SALES_MCP_TELEMETRY=1` or a setting in the client configuration, and document exactly what is sent. Honor `DO_NOT_TRACK=1` as an additional opt-out.
2. **Send identifiers, not content.** Tool name, duration, outcome class, client name and version, server version and a random installation ID are enough for usage and reliability. Leave arguments, results and file paths out.
3. **Keep stdout clean.** stdout carries protocol messages on stdio; diagnostics go to stderr and telemetry goes to an OTLP exporter.
4. **Flush on exit.** The client can stop the process at any time. Export in small batches and flush on shutdown, accepting that some data will be lost.
5. **Report coverage honestly.** Only opted-in installations appear, so present results as a sample of consenting users, not total usage.

If you also offer a hosted Streamable HTTP version, monitor it like any other server and compare the two populations separately.

## How do I check that MCP telemetry is complete?

Send a known set of synthetic calls through the real pipeline and confirm each one arrives exactly once, with the right service, environment, classification and trace context.

If you already run an OpenTelemetry setup, extend the provider and export pipeline already installed, avoiding duplicate instrumentation. **Exporter configuration does not create instrumentation or metrics by itself.** The [OTel instrumentation guide](https://flowlines.ai/blog/mcp-server-observability-guide) shows Python and TypeScript examples for adding MCP spans to existing providers, and the guide to [MCP usage analytics on an OpenTelemetry, Grafana or Datadog stack](https://flowlines.ai/blog/mcp-analytics-opentelemetry) shows how to keep your dashboards and add users and use cases on top.

### Configure export without changing the data boundary

For an already-instrumented SDK that supports environment configuration, this example points OTLP/HTTP at a Collector on the **same machine**. It is not a complete Flowlines installation:

```sh
export OTEL_SERVICE_NAME="sales-mcp"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=production,service.version=2026.10.16"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4318"
```

The base OTLP endpoint gets a signal-specific path such as /v1/traces. A signal-specific endpoint variable is used as-is. See the [OTLP exporter specification](https://opentelemetry.io/docs/specs/otel/protocol/exporter/) and the current [deployment attributes](https://opentelemetry.io/docs/specs/semconv/resource/deployment-environment/). Use authenticated HTTPS for remote export, and verify your SDK actually reads these variables.

A Collector is optional. Where you already use one, it can route approved signals to your existing backend and supported traces to Flowlines. Do not assume one traces endpoint also accepts metrics or logs. Use the onboarding plan for the actual destination, authentication and required fields.

### Verify propagation and shutdown

Follow one synthetic operation from client to server to dependency. MCP message context uses `params._meta`; supported propagators carry `traceparent`, `tracestate` and, when needed, approved baggage there. HTTP request context alone is not the same as message context. Verify support on both sides rather than inventing a missing upstream span. [MCP propagation convention](https://modelcontextprotocol.io/seps/414-request-meta).

Test successful calls, JSON-RPC errors, tool errors, timeouts and recovery. Confirm exactly one intended execution record per attempt, flush pending exports on graceful shutdown, and check dropped telemetry. On stdio servers, reserve stdout for protocol messages; use stderr or an exporter for diagnostics. See the [MCP stdio transport specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports).

## Which monitoring tools should you use?

Start with Flowlines if you want to understand who uses your MCP, what they are trying to do, where they get stuck, and which signals deserve your team's attention. Connect your assistant, approve the OpenTelemetry instrumentation plan, and start free. Keep your existing operational tools where they already work well.

Flowlines publishes this comparison. Products have overlapping capabilities; evaluate each against your workflow and the context your integration can capture.

| Tool | Useful starting point | What to evaluate |
|---|---|---|
| **Flowlines** | Understand users, use cases and outcomes; get notified about blockers, unmet needs and buying signals | Start with one MCP and a useful signal. Review the user journey and route findings to Slack, email or a webhook. Insight depends on telemetry coverage and approved context. |
| Grafana Cloud with OpenLIT | MCP operational dashboards alongside traces and metrics | Instrumentation compatibility, label mapping and the user-level analysis you need |
| Datadog Agent Observability | Agent investigation within an existing Datadog stack | Its MCP intent capture, session and insight features as well as tracing; do not assume it only measures latency |
| Sentry | MCP errors and performance investigation | SDK coverage and whether the captured context answers your product questions |

Sources: [Grafana MCP observability](https://grafana.com/docs/grafana-cloud/observe-and-act/monitor-applications/ai-observability/mcp-observability/), [Datadog SDK](https://docs.datadoghq.com/llm_observability/instrument/sdk/), [Datadog Insights](https://docs.datadoghq.com/llm_observability/investigate/insights/), [Sentry MCP monitoring](https://sentry.io/changelog/mcp-monitoring---generally-available/), and [Flowlines MCP observability](https://flowlines.ai/mcp-observability). Reviewed October 16, 2026.

Keep the tools that already answer your operational questions. You do not need to replace Grafana, Datadog or Sentry to add Flowlines, and you do not need to buy them to start with Flowlines. For deeper evaluation, see the [MCP tool comparison](https://flowlines.ai/blog/best-mcp-observability-tools) and [Flowlines versus Datadog](https://flowlines.ai/compare/flowlines-vs-datadog).

## How do I monitor MCP servers without storing sensitive payloads?

Keep argument and result capture off, monitor counts, durations, classified errors and pseudonymous identifiers, and add approved, minimized context only for the questions that need it.

| Works without arguments or results | Needs approved, minimized context |
|---|---|
| Calls, error ratio and latency per tool | Why a request failed in domain terms |
| Distinct and returning pseudonymous users | What the user was trying to do |
| Release and client comparisons | Unmet needs and buying signals |
| Alerts on errors, latency, saturation and silence | Some outcome checks |

### What not to log

- Authorization headers, bearer tokens, OAuth codes and refresh tokens
- API keys, passwords and connection strings, including inside tool arguments or error messages
- Cookies and session secrets
- Full tool arguments and results by default; capture them only under an explicit, opt-in policy
- Raw user prompts or conversation text the server happens to receive
- Email addresses, phone numbers or names as metric labels
- Payment card data and government identifiers
- File contents, source code and database rows returned by tools
- Stack traces or exception messages that include environment values or customer data

Flowlines analyzes the telemetry and approved context you provide, not the assistant's full private conversation or final answer. Keep missing outcomes explicitly unknown. Buying intent is a finding to review, not a confirmed sale.

For business KPI reporting, define the evaluated population. A synthetic 18 buying-intent findings across 240 evaluated sessions means 7.5% incidence in that population, not a 7.5% sales conversion rate. Revenue attribution requires a separate confirmed business event.

Notifications follow analysis. They do not block calls inline, guarantee a fixed delivery latency, or imply support for arbitrary aggregate thresholds such as “page me when revenue falls 10%.” Use your metrics backend for numerical threshold rules and Flowlines for the supported behavioral findings.

Collect only what you need and are permitted to process. Exclude credentials, auth headers, secrets and unrelated personal data. Pseudonymous identifiers still need appropriate access controls and retention limits.

Technical monitoring can work without storing arguments and results. Detailed request patterns and some outcome checks need additional approved context. If you omit that context, describe the resulting limits instead of claiming equivalent insight. Removing two named attributes is not a complete redaction policy: inspect nested payloads, exception messages, span events and logs too.

Test with synthetic secrets and identifiers before production. Inspect what actually arrives in each destination, not just the source code. A Collector can remove fields before downstream export, but source-side minimization avoids sending them to the Collector in the first place.

## Production monitoring checklist

1. Define one useful user job and an observable completion condition.
2. Establish health probes and auth/protocol failure monitoring for your transport and revision.
3. Instrument tool executions once and verify error classification and duration units.
4. Review identity, content capture, redaction and retention with synthetic sensitive values.
5. Check context propagation, export delivery and graceful shutdown; keep stdio stdout clean.
6. Segment by server, environment, release and tool; keep unknown clients and users visible.
7. Test success, tool error, timeout, recovery and repeated-call journeys.
8. Define alert windows, minimum volumes, owners, runbooks and notification destinations.
9. Configure a useful product or business signal and review its false positives.
10. Check telemetry and outcome coverage before comparing adoption or release impact.

[Download the production checklist](https://flowlines.ai/examples/mcp-monitoring/checklist.md). Start with one server and one journey, then verify the same setup after deployment. Expand the analysis when the first findings lead to useful action.

**Key takeaway:** monitor every MCP server and tool for availability, traffic, latency, errors, saturation and security in your metrics backend, then connect those calls to users, journeys and business signals. A green tool call is not a finished user job.


## Related guides

- [Monitor a remote MCP server: health checks, metrics and alerts](https://flowlines.ai/blog/remote-mcp-server-monitoring)
- [MCP server logging: what to log and what never to log](https://flowlines.ai/blog/mcp-server-logging)
- [Catch MCP regressions before and after a release](https://flowlines.ai/blog/mcp-server-evals-and-regressions)

## Sources and verification

Technical references reviewed October 16, 2026. Development-stage conventions can change; check your installed SDK, exporter and protocol revision before copying configuration. The examples demonstrate monitoring contracts, not a universal instrumentation package.

- [OpenTelemetry MCP semantic conventions](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/mcp.md)
- [OTLP exporter configuration](https://opentelemetry.io/docs/specs/otel/protocol/exporter/)
- [OpenTelemetry deployment environment](https://opentelemetry.io/docs/specs/semconv/resource/deployment-environment/)
- [MCP trace-context propagation](https://modelcontextprotocol.io/seps/414-request-meta)
- [MCP transport specification, 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)
- [Prometheus histograms](https://prometheus.io/docs/practices/histograms/)
- [Prometheus alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/)
- [Flowlines guided onboarding](https://flowlines.ai/docs) and [instrumentation details](https://flowlines.ai/blog/mcp-server-observability-guide)
## Frequently asked questions

### How do people monitor MCP servers in production?

Instrument server-side operations, collect availability, errors and duration, and group tool activity by server, client and permitted user identity. Add session analysis to understand attempted jobs, repeat use and outcomes. Infrastructure health and user success need separate measurements.

### What should I monitor after launching an MCP server?

Monitor availability, traffic, latency, errors, saturation and security for each server and tool. Then add distinct and returning users, completed journeys, outcome coverage and the business signals your team acts on. Define each denominator before comparing releases.

### Can I add MCP observability to an existing OpenTelemetry setup?

Yes. Extend your existing instrumentation and export pipeline rather than creating duplicate spans or a second global provider. Verify that your instrumentation emits the MCP attributes and metrics you need; an OTLP exporter alone does not create them.

### How can I monitor several MCP servers in one place?

Give each server a distinct service.name, attach deployment.environment.name and service.version, and use those dimensions in the shared backend. Compare tools within a server and environment before aggregating them across the fleet.

### How can I monitor the same MCP server across Claude and ChatGPT?

Instrument the server once and segment observed activity by the client metadata available in your integration. Client names are self-reported, can be missing, and are not user identities. Compare similar jobs and releases, and keep unknown clients visible.

### How do I track the success rate of MCP tool calls?

Divide successful classified attempts by all classified attempts in the same time window. Count transport failures, JSON-RPC errors and tool results with isError: true as separate failure categories; report cancellations and unknown states separately. A successful call does not prove the user's task completed.

### How do I find which MCP tools fail most often?

Rank tools by failed attempts and by error ratio over the same window, require a minimum volume, then break the top tools down by error class, client and affected users. High-traffic tools dominate raw counts, and low-volume tools need event-based review.

### How can I get alerts when errors spike on my MCP server?

Evaluate the error ratio per server, environment and tool over a rolling window, require enough traffic, and require the condition to persist. Give the alert an owner and runbook. Monitor missing telemetry separately because an empty error graph does not prove health.

### How can I track latency for MCP tool calls?

Record a duration histogram for tool operations and inspect p50, p95 and p99 by server and tool. Keep units consistent, choose buckets around your latency objectives, and compare equivalent traffic. Do not average percentiles across instances.

### How do I compare MCP usage before and after changing a tool?

Tag releases with service.version and compare the same tool, environment, client mix and window length. Read calls, distinct users, error ratio, p95 latency and calls per completed journey together, and report outcome coverage. The comparison is observational, not proof of cause.

### Can I monitor MCP servers without storing tool arguments and results?

Yes, for technical measurements such as call counts, duration and classified errors. Detailed request intent, buying signals and some outcome checks need additional approved context. Redact at the source and report unavailable insights as unknown rather than inferring private conversations.

### Can Flowlines notify me about business signals from my MCP?

Yes. Configure signals for observed buying intent, unmet needs, recurring problems or other behavior, then route notifications to Slack, email or a webhook after analysis. A business signal is not confirmed revenue, and this does not promise arbitrary aggregate KPI threshold alerts or inline blocking.

### Does Flowlines replace Grafana, Datadog or Sentry?

No. Keep the operational monitoring you need. Flowlines focuses on MCP users, use cases, journeys, outcomes and configurable behavior signals. You can also send supported telemetry directly to Flowlines without buying another tracing platform.

### How do I start monitoring my MCP with Flowlines?

Connect Flowlines to your coding assistant or install the official plugin, open your server repository, and ask to onboard your MCP. Approve the OpenTelemetry plan, then ask to check onboarding. The Free plan includes 100 analyzed MCP sessions per month with no credit card; instrumentation is required, but a proprietary Flowlines runtime SDK is not.
