← FlowlinesCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Flowlines
Snapshot Sep 30, 2026 · 23:10 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "flowlines-mcp-observability",
"description": "Integrate, repair, review, or verify Flowlines observability in an MCP server repository. Use when a server must emit canonical Flowlines MCP tool-call telemetry through AGNTCY Observe or vanilla OpenTelemetry; do not use for Claude Code or Codex CLI telemetry.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 233
},
{
"relative_path": "references/contract.md",
"size_in_bytes": 15127
},
{
"relative_path": "references/python-agntcy.md",
"size_in_bytes": 8520
},
{
"relative_path": "references/vanilla-opentelemetry.md",
"size_in_bytes": 12868
}
],
"skill_md_contents": "---\nname: flowlines-mcp-observability\ndescription: Integrate, repair, review, or verify Flowlines observability in an MCP server repository. Use when a server must emit canonical Flowlines MCP tool-call telemetry through AGNTCY Observe or vanilla OpenTelemetry; do not use for Claude Code or Codex CLI telemetry.\n---\n\n# Flowlines MCP Observability\n\nInstrument an MCP server so complete tool executions arrive in Flowlines as canonical MCP calls. Modify the target server; do not add a Flowlines runtime SDK or assume ownership of unrelated telemetry.\n\n## Consent and secrets\n\nBefore changing code or deployment configuration:\n\n1. Explain that supported MCP spans export validated tool arguments, final client-visible results, and user identity metadata to Flowlines. Identity metadata includes a stable user ID and, when available, name and email; these fields and payloads may contain personal data, customer data, source code, file content, or other sensitive values.\n2. Obtain explicit consent for payload export. Do not infer it from a generic request to \"add telemetry.\"\n3. Confirm the user has a Flowlines namespace API key before touching the deployment. If they do not, tell them to create one in the Flowlines app under Settings, API keys, at `https://app.flowlines.ai/settings` for the namespace that should receive the data, and offer to open that page for them (`open` on macOS, `xdg-open` on Linux). The key is shown once at creation. Ask the user to place it in the target deployment's secret manager. Never request the key in chat, write it into source or examples, interpolate it into a command, or print an existing value.\n4. Treat the integration request as permission to edit and test the target repository, not to deploy it, call production tools, or mutate any production database.\n\nRead [references/contract.md](references/contract.md) before implementing or reviewing an integration.\n\n## Inspect the target first\n\nRead the repository instructions, architecture documentation, and testing strategy. Then identify:\n\n- language, runtime, MCP SDK and transport;\n- package manager, lockfile, dependency policies, and supported runtime versions;\n- the central tool-registration or dispatch boundary;\n- existing MCP-level middleware or interceptors;\n- existing OpenTelemetry provider, exporter, collector, propagation, and shutdown handling;\n- where validated arguments, request ID, request `_meta`, authenticated user ID/profile, final MCP result, and error mapping are available;\n- how deployment secrets and environment variables are declared without values.\n\nPreserve the target's package manager and telemetry ownership. Reuse an existing tracer provider and collector when present; never register a competing global provider or replace unrelated exporters.\n\n## Choose the integration path\n\n- For a compatible Python server using the official `mcp` package, prefer AGNTCY Observe. Read [references/python-agntcy.md](references/python-agntcy.md).\n- For TypeScript or any other language with an OpenTelemetry SDK, use vanilla OpenTelemetry. Read [references/vanilla-opentelemetry.md](references/vanilla-opentelemetry.md).\n- On the vanilla path, prefer the framework's existing MCP-level middleware or interceptor at `tools/call` as the default span boundary. Typical hooks: Go `AddReceivingMiddleware`, FastMCP `on_call_tool`, official Python `server.middleware` filtered to `tools/call`, or the equivalent TypeScript hook. Do not use HTTP, transport, or sending middleware as the Flowlines MCP span boundary; resolve identity from those layers when needed, then emit the span at MCP `tools/call`.\n- If automatic instrumentation or that middleware hook cannot observe the final client-visible result, validated arguments, or request metadata, keep a single wrapper around the central tool execution boundary and capture the missing fields there. Do not scatter nearly identical span code across every handler unless the framework provides no shared boundary. Do not emit Flowlines MCP spans for `initialize`, `tools/list`, or other non-`tools/call` methods. Disable overlapping automatic coverage so each call produces one Flowlines MCP span.\n\nIf the stack has neither supported AGNTCY instrumentation nor a usable OpenTelemetry SDK, explain the gap instead of inventing an unverified exporter or protocol adapter.\n\n## Implement the contract\n\nMake the smallest coherent change that satisfies all of these invariants:\n\n1. Require non-empty `reason` and `user_intent` strings in every ordinary tool input schema. Do not synthesize either value from prompts or tool arguments. Update server instructions, examples, affected callers, and tests because this is an intentional schema change.\n2. Register `report_outcome` exactly as described in the contract and include its unconditional final-call instruction in the server instructions.\n3. Start one server span around each complete, validated `tools/call` execution. Give every invocation a fresh tool-call ID that is independent of the JSON-RPC request ID.\n4. Record the canonical attributes from `contract.md`, the validated tool-argument object, and only the final MCP result returned to the client. When the tool has a published description, emit it as `gen_ai.tool.description` from the registration metadata, trimmed and capped at 10,000 characters. Omit missing descriptions; do not infer them from arguments or reasons. Emit the tool's published input schema as `gen_ai.tool.input_schema`, and its output schema when declared as `gen_ai.tool.output_schema`, serialized whole from the same registration metadata; omit a schema that is missing or would exceed 50,000 characters.\n5. Put a non-empty, stable user identifier on every emitted MCP span as the exact `user.id` attribute. Prefer a verified authenticated subject; otherwise require client `_meta[\"user.id\"]`. Never substitute email, display name, session ID, trace ID, or OAuth client ID. If neither identity source exists, the integration is incomplete: extend the authentication or client metadata contract rather than inventing an identity.\n6. When verified profile name/email exists, emit it on the same span as exact `user.name` and `user.email` attributes. Otherwise promote non-empty client metadata as untrusted analytics values and document that provenance. Verified fields always win. Flowlines does not map name or email merely because they remain nested in MCP `_meta`; treat them as PII and never put them in captured tool arguments.\n7. Configure and verify the applicable Flowlines identity mapping with user ID attribute `user.id`, name field ID `name` mapped to `user.name`, and email field ID `email` mapped to `user.email`. Use the caller-agent users mapping when a real caller agent is present, or the equivalent namespace identifier mapping for an agentless MCP session. Never label the MCP server as a caller agent. Sending the attributes alone is not sufficient for name/email profile enrichment when identity fields have not been mapped; if neither mapping surface is available, report that limitation explicitly.\n8. Prefer client-supplied `_meta[\"session.id\"]`. Never derive a conversation from user identity, trace ID, timing, or a reused protocol request ID.\n9. Propagate valid incoming W3C trace context when the transport exposes it. Do not make trace context a prerequisite for a call to be recorded.\n10. Mark every completed call explicitly: set span status to `OK` after a successful final MCP result and `ERROR` for a tool or protocol failure. Do not leave a completed call at the OpenTelemetry default `UNSET`, because Flowlines reports that call's success as unknown. On failure, record only a bounded error type; do not record raw exceptions, stack traces, authorization headers, OAuth claims, request `_meta`, environment variables, or secret-bearing diagnostics.\n11. Keep telemetry fail-open. Export failure must not change the MCP response, and shutdown flushing must be bounded.\n12. Configure OTLP through environment variables or the existing collector. Commit only secret placeholders and variable names.\n\nDo not change sampling for an application-wide provider without explicit approval. A dedicated MCP provider may use always-on sampling because these spans are product facts; with a shared provider, preserve its policy and call out any risk from unsampled remote parents.\n\n## Verify\n\nAdd tests at the middleware or wrapper boundary, using the stack's in-memory exporter when available. At minimum cover:\n\n- a successful call with explicit `OK` span status, required attributes, distinct call/request IDs, session identity, stable `user.id`, arguments, and result;\n- the registered tool description as `gen_ai.tool.description`, with trimming and the 10,000-character bound, plus omission when no description exists;\n- the registered input and output schemas as `gen_ai.tool.input_schema` and `gen_ai.tool.output_schema`, serialized whole and identical to what `tools/list` publishes, plus omission when absent or over the 50,000-character bound;\n- exact `user.name` and `user.email` span attributes for both the verified-profile path and the client-metadata fallback when those values are available;\n- a failed call with explicit `ERROR` span status that exports only the safe client-visible error and a bounded error type;\n- absence of `_meta`, authorization material, raw exception messages, and spoofed identity; verified identity must win over all client-supplied user fields;\n- `report_outcome` schema and server instructions;\n- exporter shutdown or force-flush behavior when the integration owns the provider.\n\nRun the target repository's narrow tests, formatter/linter, type checker, and package-manager checks. Never put a real API key in a test.\n\nOnly perform live verification when the user has authorized network export and configured the key outside chat. Make ten harmless calls sharing a test `session.id` and stable test `user.id`, include a test name/email when those fields are supported, then make one final `report_outcome` call. Confirm Flowlines shows eleven accepted calls, reports successful calls as successful rather than unknown, maps all calls to the expected user ID, displays the mapped name/email, and shows the session intent, outcome, captured evidence, client attribution when supplied, and no persistent ingestion-quality issues. Behavioral clustering and tool-loop signals have separate volume and timing thresholds, so do not treat their immediate absence as exporter failure.\n\nVerifying receipt and the identity mapping needs the Flowlines MCP server signed in, or the Flowlines app. If the MCP server is connected but not authorised, ask the user to sign in first (`/mcp` in Claude Code, `codex mcp login flowlines` in Codex) rather than reporting the mapping as unverified. If neither is available, name the exact mapping to configure (`user.id` as the user ID, `name` to `user.name`, `email` to `user.email`) and where in the app to do it, and say that receipt was not verified.\n\n## Hand off\n\nReport:\n\n- files and dependencies changed;\n- where deployment must set the endpoint, API-key header, and service name;\n- the source of `user.id`, availability of name/email, and the exact Flowlines user mappings verified;\n- schema or client compatibility changes caused by `reason`, `user_intent`, or `report_outcome`;\n- checks run and whether live Flowlines receipt was verified;\n- any identity, propagation, sampling, payload, or shutdown limitation that remains.\n"
}SHA-256: 533eced9642544a3c92826cbdfe43e1c5c005b64796b102924d8a82874264cba