Skip to content

feat(MCP): Emit session and tool call events#7707

Merged
khvn26 merged 8 commits into
mainfrom
feat/mcp-events
Jun 4, 2026
Merged

feat(MCP): Emit session and tool call events#7707
khvn26 merged 8 commits into
mainfrom
feat/mcp-events

Conversation

@khvn26
Copy link
Copy Markdown
Member

@khvn26 khvn26 commented Jun 4, 2026

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Contributes to Flagsmith/flagsmith-private#152.

Identify MCP clients by their initialize clientInfo (User-Agents proved unreliable; raw values, classification happens downstream) and make the identity visible on all three telemetry surfaces:

  • Events: mcp.session.opened and mcp.tool.called (tool, status, flagsmith.mcp.client.name/version).
  • Spans: a processor annotates FastMCP's server spans with flagsmith.client.name=flagsmith-mcp (this service, as the API's caller) and flagsmith.mcp.client.* (the end client). Spans record even without an OTLP endpoint; export stays gated on it.
  • API propagation: the API httpx client (instance-only instrumentation) emits a CLIENT span per upstream call and carries W3C traceparent, plus all current span attributes as W3C baggage via a request hook — the API's OTel pipeline already copies baggage onto its events.

How did you test this code?

Unit/integration tests at 100% coverage, including the exact baggage header on upstream requests. Verified live against a local capture server, with and without OTEL_EXPORTER_OTLP_ENDPOINT.

@khvn26 khvn26 requested a review from a team as a code owner June 4, 2026 10:37
@khvn26 khvn26 requested review from emyller and removed request for a team June 4, 2026 10:37
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 4, 2026 6:34pm
flagsmith-frontend-preview Ignored Ignored Preview Jun 4, 2026 6:34pm
flagsmith-frontend-staging Ignored Ignored Preview Jun 4, 2026 6:34pm

Request Review

@github-actions github-actions Bot added the feature New feature or request label Jun 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-e2e:pr-7707 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api-test:pr-7707 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api:pr-7707 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7707 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-7707 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7707 Finished ✅ Results

@khvn26 khvn26 force-pushed the feat/mcp-events branch from 552f06d to dcdb069 Compare June 4, 2026 10:39
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.7 seconds
commit  552f06d
info  🔄 Run: #17242 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  39.5 seconds
commit  552f06d
info  🔄 Run: #17242 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  34 seconds
commit  552f06d
info  🔄 Run: #17242 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  52.3 seconds
commit  552f06d
info  🔄 Run: #17242 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.9 seconds
commit  dcdb069
info  🔄 Run: #17243 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.5 seconds
commit  dcdb069
info  🔄 Run: #17243 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  34 seconds
commit  dcdb069
info  🔄 Run: #17243 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 9 seconds
commit  dcdb069
info  🔄 Run: #17243 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  39.7 seconds
commit  0d2517f
info  🔄 Run: #17244 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  33.8 seconds
commit  0d2517f
info  🔄 Run: #17244 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  43.5 seconds
commit  0d2517f
info  🔄 Run: #17244 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  55.7 seconds
commit  0d2517f
info  🔄 Run: #17244 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  19 passed

Details

stats  19 tests across 15 suites
duration  1 minute, 9 seconds
commit  cd926ca
info  🔄 Run: #17245 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.1 seconds
commit  cd926ca
info  🔄 Run: #17245 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.8 seconds
commit  cd926ca
info  🔄 Run: #17245 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  38.8 seconds
commit  cd926ca
info  🔄 Run: #17245 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  41.4 seconds
commit  ab7c0f2
info  🔄 Run: #17246 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.7 seconds
commit  ab7c0f2
info  🔄 Run: #17246 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  56.3 seconds
commit  ab7c0f2
info  🔄 Run: #17246 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  37.5 seconds
commit  ab7c0f2
info  🔄 Run: #17246 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.8 seconds
commit  0ad3a5b
info  🔄 Run: #17249 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.5 seconds
commit  0ad3a5b
info  🔄 Run: #17249 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  37.1 seconds
commit  0ad3a5b
info  🔄 Run: #17249 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  41.9 seconds
commit  0ad3a5b
info  🔄 Run: #17249 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  39.6 seconds
commit  f443e0b
info  🔄 Run: #17253 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  45.1 seconds
commit  f443e0b
info  🔄 Run: #17253 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.9 seconds
commit  f443e0b
info  🔄 Run: #17251 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  42.9 seconds
commit  f443e0b
info  🔄 Run: #17251 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  50.2 seconds
commit  f443e0b
info  🔄 Run: #17253 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  38.2 seconds
commit  f443e0b
info  🔄 Run: #17251 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  54.9 seconds
commit  f443e0b
info  🔄 Run: #17253 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  41 seconds
commit  a484ef9
info  🔄 Run: #17256 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.3 seconds
commit  a484ef9
info  🔄 Run: #17256 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  35.4 seconds
commit  a484ef9
info  🔄 Run: #17256 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 3 seconds
commit  a484ef9
info  🔄 Run: #17256 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  37 seconds
commit  dbbaf4b
info  🔄 Run: #17257 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.4 seconds
commit  dbbaf4b
info  🔄 Run: #17257 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  33.2 seconds
commit  dbbaf4b
info  🔄 Run: #17257 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  38.4 seconds
commit  dbbaf4b
info  🔄 Run: #17257 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.8 seconds
commit  78e8ca6
info  🔄 Run: #17258 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  44.7 seconds
commit  78e8ca6
info  🔄 Run: #17258 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  56.1 seconds
commit  78e8ca6
info  🔄 Run: #17258 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  54 seconds
commit  78e8ca6
info  🔄 Run: #17258 (attempt 1)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Visual Regression

19 screenshots compared. See report for details.
View full report

@khvn26 khvn26 force-pushed the feat/mcp-events branch from dcdb069 to 0d2517f Compare June 4, 2026 13:58
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
@khvn26 khvn26 force-pushed the feat/mcp-events branch from 0d2517f to cd926ca Compare June 4, 2026 14:09
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
@khvn26 khvn26 force-pushed the feat/mcp-events branch from 0ad3a5b to 59468f6 Compare June 4, 2026 17:52
@khvn26 khvn26 requested a review from a team as a code owner June 4, 2026 17:52
@github-actions github-actions Bot added the api Issue related to the REST API label Jun 4, 2026
@khvn26 khvn26 force-pushed the feat/mcp-events branch from 59468f6 to f443e0b Compare June 4, 2026 17:54
@khvn26 khvn26 force-pushed the feat/mcp-structlog branch from b43159c to 7298c54 Compare June 4, 2026 17:54
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
Base automatically changed from feat/mcp-structlog to main June 4, 2026 17:59
khvn26 added 6 commits June 4, 2026 19:00
Contributes to Flagsmith/flagsmith-private#152.

A middleware emits structured events on the mcp domain, identifying
clients by their self-declared clientInfo from the initialize
handshake — User-Agents proved unreliable (most TS SDK clients send
runtime defaults), and raw names beat server-side allow-lists, so
classification happens downstream:

- session.opened on initialize, with flagsmith.client.name/version
- tool.called for every tools/call, with tool, client, status and
  duration

A span processor annotates FastMCP's server spans with the same
flagsmith.client.* attributes. The flagsmith. namespace avoids
squatting on the semconv mcp. and client. namespaces; flagsmith-common
already emits flagsmith.event.

beep boop
Instrument the Flagsmith API httpx client (instance-only, via
opentelemetry-instrumentation-httpx) so every upstream call emits a
client span and carries W3C trace context and baggage. A middleware
sets flagsmith.tool.name and flagsmith.client.name/version as baggage
per tool call; the API's existing OTel pipeline extracts baggage and
copies it onto its own events, giving per-client, per-tool visibility
on both sides of the boundary.

beep boop
Set the client identity and tool name once, as W3C Baggage, and copy
flagsmith.* entries onto spans with a span processor — replacing the
separate clientInfo span annotation. The off-the-shelf
opentelemetry-processor-baggage reads baggage from the span's parent
context, which FastMCP builds from the request _meta without baggage,
so the processor reads the current context instead.

beep boop
Write flagsmith.client.name/version as span attributes directly, and
pass all of the current span's attributes — MCP method, tool, session
and client identity — as W3C Baggage on outbound Flagsmith API
requests via an httpx event hook scoped to the API client only.
Replaces the baggage-attaching middleware: process context is never
touched, and the API receives the full call context whenever tracing
is enabled.

beep boop
@khvn26 khvn26 force-pushed the feat/mcp-events branch from f443e0b to a484ef9 Compare June 4, 2026 18:00
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
emyller
emyller previously approved these changes Jun 4, 2026
Copy link
Copy Markdown
Contributor

@emyller emyller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Send flagsmith.client.name=flagsmith-mcp on every span and API-bound
baggage header — the API's immediate caller — and move the MCP
client's self-declared identity to flagsmith.mcp.client.name/version
across spans, baggage and events. Spans now record without an OTLP
endpoint too (in-process only), so the API receives baggage regardless
of whether telemetry export is enabled.

beep boop
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 4, 2026
@khvn26 khvn26 requested a review from emyller June 4, 2026 18:39
Copy link
Copy Markdown
Contributor

@emyller emyller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks clearer!

@khvn26 khvn26 merged commit 36ef8dd into main Jun 4, 2026
32 checks passed
@khvn26 khvn26 deleted the feat/mcp-events branch June 4, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants