Skip to content

Conversation

DaleSeo
Copy link
Contributor

@DaleSeo DaleSeo commented Sep 24, 2025

🚀 Features

Prototype OpenTelemetry Traces in MCP Server - @swcollard PR #274

Pulls in new crates and SDKs for prototyping instrumenting the Apollo MCP Server with Open Telemetry Traces.

  • Adds new rust crates to support OTel
  • Annotates excecute and call_tool functions with trace macro
  • Adds Axum and Tower middleware's for OTel tracing
  • Refactors Logging so that all the tracing_subscribers are set together in a single module.

Add CORS support - @DaleSeo PR #362

This PR implements comprehensive CORS support for Apollo MCP Server to enable web-based MCP clients to connect without CORS errors. The implementation and configuration draw heavily from the Router's approach. Similar to other features like health checks and telemetry, CORS is supported only for the StreamableHttp transport, making it a top-level configuration.

Enhance tool descriptions - @DaleSeo PR #350

This PR enhances the descriptions of the introspect and search tools to offer clearer guidance for AI models on efficient GraphQL schema exploration patterns.

Telemetry: Trace operations and auth - @swcollard PR #375

  • Adds traces for the MCP server generating Tools from Operations and performing authorization
  • Includes the HTTP status code to the top level HTTP trace

Implement metrics for mcp tool and operation counts and durations - @swcollard PR #297

This PR adds metrics to count and measure request duration to events throughout the MCP server

  • apollo.mcp.operation.duration
  • apollo.mcp.operation.count
  • apollo.mcp.tool.duration
  • apollo.mcp.tool.count
  • apollo.mcp.initialize.count
  • apollo.mcp.list_tools.count
  • apollo.mcp.get_info.count

Adding ability to omit attributes for traces and metrics - @alocay PR #358

Adding ability to configure which attributes are omitted from telemetry traces and metrics.

  1. Using a Rust build script (build.rs) to auto-generate telemetry attribute code based on the data found in telemetry.toml.
  2. Utilizing an enum for attributes so typos in the config file raise an error.
  3. Omitting trace attributes by filtering it out in a custom exporter.
  4. Omitting metric attributes by indicating which attributes are allowed via a view.
  5. Created telemetry_attributes.rs to map TelemetryAttribute enum to a OTEL Key.

The telemetry.toml file includes attributes (both for metrics and traces) as well as list of metrics gathered. An example would look like the following:

[attributes.apollo.mcp]
my_attribute = "Some attribute info"

[metrics.apollo.mcp]
some.count = "Some metric count info"

This would generate a file that looks like the following:

/// All TelemetryAttribute values
pub const ALL_ATTRS: &[TelemetryAttribute; 1usize] = &[
    TelemetryAttribute::MyAttribute
];
#[derive(Debug, ::serde::Deserialize, ::schemars::JsonSchema,, Clone, Eq, PartialEq, Hash, Copy)]
pub enum TelemetryAttribute {
    ///Some attribute info
    #[serde(alias = "my_attribute")]
    MyAttribute,
}
impl TelemetryAttribute {
    /// Supported telemetry attribute (tags) values
    pub const fn as_str(&self) -> &'static str {
        match self {
            TelemetryAttribute::MyAttribute => "apollo.mcp.my_attribute",
        }
    }
}
#[derive(Debug, ::serde::Deserialize, ::schemars::JsonSchema,, Clone, Eq, PartialEq, Hash, Copy)]
pub enum TelemetryMetric {
    ///Some metric count info
    #[serde(alias = "some.count")]
    SomeCount,
}
impl TelemetryMetric {
    /// Converts TelemetryMetric to &str
    pub const fn as_str(&self) -> &'static str {
        match self {
            TelemetryMetric::SomeCount => "apollo.mcp.some.count",
        }
    }
}

An example configuration that omits tool_name attribute for metrics and request_id for tracing would look like the following:

telemetry:
  exporters:
    metrics:
      otlp:
        endpoint: "http://localhost:4317"
        protocol: "grpc"
      omitted_attributes:
        - tool_name
    tracing:
      otlp:
        endpoint: "http://localhost:4317"
        protocol: "grpc"
      omitted_attributes:
        - request_id

Adding config option for trace sampling - @alocay PR #366

Adding configuration option to sample traces. Can use the following options:

  1. Ratio based samples (ratio >= 1 is always sample)
  2. Always on
  3. Always off

Defaults to always on if not provided.

🐛 Fixes

Update SDL handling in sdl_to_api_schema function - @lennyburdette PR #365

Loads supergraph schemas using a function that supports various features, including Apollo Connectors. When supergraph loading failed, it would load it as a standard GraphQL schema, which reveals Federation query planning directives in when using the search and introspection tools.

Include the cargo feature and TraceContextPropagator to send otel headers downstream - @swcollard PR #307

Inside the reqwest middleware, if the global text_map_propagator is not set, it will no op and not send the traceparent and tracestate headers to the Router. Adding this is needed to correlate traces from the mcp server to the router or other downstream APIs

Add support for deprecated directive - @esilverm PR #367

Includes any existing @deprecated directives in the schema in the minified output of builtin tools. Now operations generated via these tools should take into account deprecated fields when being generated.

📃 Configuration

Add basic config file options to otel telemetry - @swcollard PR #330

Adds new Configuration options for setting up configuration beyond the standard OTEL environment variables needed before.

  • Renames trace->telemetry
  • Adds OTLP options for metrics and tracing to choose grpc or http upload protocols and setting the endpoints
  • This configuration is all optional, so by default nothing will be logged

Disable statefulness to fix initialize race condition - @swcollard PR #351

We've been seeing errors with state and session handling in the MCP Server. Whether that is requests being sent before the initialized notification is processed. Or running a fleet of MCP Server pods behind a round robin load balancer. A new configuration option under the streamable_http transport stateful_mode, allows disabling session handling which appears to fix the race condition issue.

🛠 Maintenance

Add tests for server event and SupergraphSdlQuery - @DaleSeo PR #347

This PR adds tests for some uncovered parts of the codebase to check the Codecov integration.

Fix version on mcp server tester - @alocay PR #374

Add a specific version when calling the mcp-server-tester for e2e tests. The current latest (1.4.1) as an issue so to avoid problems now and in the future updating the test script to invoke the testing tool via specific version.

@DaleSeo DaleSeo self-assigned this Sep 24, 2025
@DaleSeo DaleSeo added the release Indicates a release related PR label Sep 24, 2025
@apollo-librarian
Copy link

apollo-librarian bot commented Sep 24, 2025

✅ Docs preview ready

The preview is ready to be viewed. View the preview

File Changes

2 new, 3 changed, 0 removed
+ (developer-tools)/apollo-mcp-server/(latest)/cors.mdx
+ (developer-tools)/apollo-mcp-server/(latest)/telemetry.mdx
* (developer-tools)/apollo-mcp-server/(latest)/config-file.mdx
* (developer-tools)/apollo-mcp-server/(latest)/define-tools.mdx
* (developer-tools)/apollo-mcp-server/(latest)/_sidebar.yaml

Build ID: f361a495bad45ff4a657a9b0
Build Logs: View logs

URL: https://www.apollographql.com/docs/deploy-preview/f361a495bad45ff4a657a9b0

@DaleSeo DaleSeo marked this pull request as ready for review September 24, 2025 20:26
@DaleSeo DaleSeo requested review from a team as code owners September 24, 2025 20:26
@DaleSeo DaleSeo force-pushed the release/0.9.0 branch 3 times, most recently from 93810ff to d59e5f7 Compare September 24, 2025 21:32
DaleSeo and others added 20 commits September 29, 2025 14:34
* Allow config for not forwarding Auth tokens to GraphQL API

* use serde default to make new config optional

* Changeset

* Fix default case in main.rs

* Add new config option to documentation
This commit updates the RMCP dependency to the latest version 0.6.4.
Sadly, schemars was also updated with this, so a lot of unrelated
changes were needed to conform with the new stable schemars version.
…#351)

* fix: Disable statefulness to attempt to fix initialize race condition

* Change stateful_mode to being configuratable on the transport

* Use ..Default syntax

* changeset

* Add new flag to docs config reference page
`::new` uses "default" supergraph specs, which does not include Connectors, so all connector supergraph result in an error and are parsed as standard GraphQL. This ends up exposing join directives, which is a huge waste of tokens.
* Redirect /docs/apollo-mcp-server/guides to fix 404

* Fix bullet point formatting

* Add load balancer configuration details for Apollo MCP

Added instructions for configuring load balancers with Apollo MCP Server to ensure session affinity.

* Update docs/source/deploy.mdx

Co-authored-by: Michelle Mabuyo <[email protected]>

* Update deploy.mdx

---------

Co-authored-by: Samuel Collard <[email protected]>
Co-authored-by: Michelle Mabuyo <[email protected]>
Co-authored-by: Alyssa Hursh <[email protected]>
Co-authored-by: Lenny Burdette <[email protected]>
* Redirect /docs/apollo-mcp-server/guides to fix 404

* Fix bullet point formatting

---------

Co-authored-by: Samuel Collard <[email protected]>
Co-authored-by: Michelle Mabuyo <[email protected]>
Co-authored-by: Alyssa Hursh <[email protected]>
DaleSeo and others added 21 commits September 29, 2025 14:35
* Create a prototype of otel emitting traces to local jaegar instance

* Add tracing annotations

* Combine logging and tracing

* copilot feedback

* Add changeset

* Instrument other tools

* Clippy fixes

* PR feedback

* Change default env name to development

Co-authored-by: Dale Seo <[email protected]>

* Remove some extraneous extensions

---------

Co-authored-by: Dale Seo <[email protected]>
* Implement metrics for mcp tool and operation counts and durations

* Changeset

* Unit test attribute setting in graphql.rs

* Add axum_otel_metrics for emitting basic http metrics about requests

* Lazy load singleton Meter for metrics

* Alphabetize

* Simplify result.is_error checking
…l headers downstream (#307)

* Fix sending OTLP trace headers downstream to GQL API

* Changeset
* Add basic config file options to otel telemetry

* Happy path unit test for telemetry config

* Changeset

* Taplo format

* Refactor to add a couple more tests

* Update unit test for clippy after rust upgrade

* Rename unit tests
* feat: adding ability to omit attributes for traces and metrics

* chore: adding changeset

* chore: updating changeset text

* chore: removing unused file

* chore: renaming exporter file

* chore: renaming module

* re-running checks

* chore: auto-gen the as_str function using enums instead of constants

* chore: updating changeset entry and fixing fields in instruemnt attribute

* chore: adding description as a doc string

* chore: updating changeset  entry

* chore: updating operation attribute descriptions

* chore: updating operation_type attribute to operation_source

* chore: skipping request from instrumentation

* chore: fixing clippy issues

* re-running nix build

* updating unit test snapshot

* chore: fixing toml formatting issues

* test: removing asserts on constants

* chore: format issues

* test: adjusting unit test to not use local envar

* revert: undoing accidental commit

* test: removing unnecessary assert
* feat: adding config option for trace sampling

* chore: adding changeset entry
Add status code to the http trace
Changeset

Unit tests for auth.rs

Add raw_operation as a telemetry attribute

Unit test starting a streamable http server

Rename self to operation_source
Add telemetry docs to sidebar

Cleaning up

Fix title on grafana guide

Update the overview

Update configuration section to be more complete

Add a quick start guide and info about prod

Update production section with more useful ino

Apply suggestions from code review

Style edits

Co-authored-by: Joseph Caudle <[email protected]>

Remove custom from 'custom metrics'

Remove Grafana how-to guide

Move configuration reference to the config page

Add a note about cardinality control using sampling and attribute filtering

Fix typo: traaces -> traces
Fix links to external vendors OTLP docs

pr feedback: LazyLock meter, debug and todo removal, comments
@DaleSeo DaleSeo merged commit 3e2fe16 into main Sep 29, 2025
9 of 10 checks passed
@DaleSeo DaleSeo deleted the release/0.9.0 branch September 29, 2025 19:44
Copy link

Opened sync PR main → develop: #393

Merge status: conflicts ❗
Opened from a copy of main so conflicts can be resolved safely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release Indicates a release related PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants