Skip to content

Commit fa7e6bf

Browse files
authored
Merge pull request #453 from apollographql/release/1.1.0
Releasing 1.1.0
2 parents d01fab0 + 7e0fc14 commit fa7e6bf

35 files changed

+825
-207
lines changed

CHANGELOG.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,82 @@ All notable changes to this project will be documented in this file.
44

55
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
# [1.1.0] - 2025-10-16
8+
9+
## ❗ BREAKING ❗
10+
11+
### Change default port from 5000 to 8000 - @DaleSeo PR #417
12+
13+
The default server port has been changed from `5000` to `8000` to avoid conflicts with common development tools and services that typically use port 5000 (such as macOS AirPlay, Flask development servers, and other local services).
14+
15+
**Migration**: If you were relying on the default port 5000, you can continue using it by explicitly setting the port in your configuration file or command line arguments.
16+
17+
- Before
18+
19+
```yaml
20+
transport:
21+
type: streamable_http
22+
```
23+
24+
- After
25+
26+
```yaml
27+
transport:
28+
type: streamable_http
29+
port: 5000
30+
```
31+
32+
## 🚀 Features
33+
34+
### feat: Add configuration option for metric temporality - @swcollard PR #413
35+
36+
Creates a new configuration option for telemetry to set the Metric temporality to either Cumulative (default) or Delta.
37+
38+
* Cumulative - The metric value will be the overall value since the start of the measurement.
39+
* Delta - The metric will be the difference in the measurement since the last time it was reported.
40+
41+
Some observability vendors require that one is used over the other so we want to support the configuration in the MCP Server.
42+
43+
### Add support for forwarding headers from MCP clients to GraphQL APIs - @DaleSeo PR #428
44+
45+
Adds opt-in support for dynamic header forwarding, which enables metadata for A/B testing, feature flagging, geo information from CDNs, or internal instrumentation to be sent from MCP clients to downstream GraphQL APIs. It automatically blocks hop-by-hop headers according to the guidelines in [RFC 7230, section 6.1](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1), and it only works with the Streamable HTTP transport.
46+
47+
You can configure using the `forward_headers` setting:
48+
49+
```yaml
50+
forward_headers:
51+
- x-tenant-id
52+
- x-experiment-id
53+
- x-geo-country
54+
```
55+
56+
Please note that this feature is not intended for passing through credentials as documented in the best practices page.
57+
58+
### feat: Add mcp-session-id header to HTTP request trace attributes - @swcollard PR #421
59+
60+
Includes the value of the [Mcp-Session-Id](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management) HTTP header as an attribute of the trace for HTTP requests to the MCP Server
61+
62+
## 🐛 Fixes
63+
64+
### Fix compatibility issue with VSCode/Copilot - @DaleSeo PR #447
65+
66+
This updates Apollo MCP Server’s tool schemas from [Draft 2020-12](https://json-schema.org/draft/2020-12) to [Draft‑07](https://json-schema.org/draft-07) which is more widely supported across different validators. VSCode/Copilot still validate against Draft‑07, so rejects Apollo MCP Server’s tools. Our JSON schemas don’t rely on newer features, so downgrading improves compatibility across MCP clients with no practical impact.
67+
68+
## 🛠 Maintenance
69+
70+
### Update rmcp sdk to version 0.8.x - @swcollard PR #433
71+
72+
Bumping the Rust MCP SDK version used in this server up to 0.8.x
73+
74+
### chore: Only initialize a single HTTP client for graphql requests - @swcollard PR #412
75+
76+
Currently the MCP Server spins up a new HTTP client every time it wants to make a request to the downstream graphql endpoint. This change creates a static reqwest client that gets initialized using LazyLock and reused on each graphql request.
77+
78+
This change is based on the suggestion from the reqwest [documentation](https://docs.rs/reqwest/latest/reqwest/struct.Client.html)
79+
> "The Client holds a connection pool internally, so it is advised that you create one and reuse it."
80+
81+
82+
783
# [1.0.0] - 2025-10-01
884

985
# Apollo MCP Server 1.0 Release Notes

CHANGELOG_SECTION.md

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,74 @@
1-
# [1.0.0] - 2025-10-01
1+
# [1.1.0] - 2025-10-16
22

3-
## 🐛 Fixes
3+
## ❗ BREAKING ❗
4+
5+
### Change default port from 5000 to 8000 - @DaleSeo PR #417
6+
7+
The default server port has been changed from `5000` to `8000` to avoid conflicts with common development tools and services that typically use port 5000 (such as macOS AirPlay, Flask development servers, and other local services).
8+
9+
**Migration**: If you were relying on the default port 5000, you can continue using it by explicitly setting the port in your configuration file or command line arguments.
10+
11+
- Before
12+
13+
```yaml
14+
transport:
15+
type: streamable_http
16+
```
17+
18+
- After
19+
20+
```yaml
21+
transport:
22+
type: streamable_http
23+
port: 5000
24+
```
25+
26+
## 🚀 Features
27+
28+
### feat: Add configuration option for metric temporality - @swcollard PR #413
29+
30+
Creates a new configuration option for telemetry to set the Metric temporality to either Cumulative (default) or Delta.
31+
32+
* Cumulative - The metric value will be the overall value since the start of the measurement.
33+
* Delta - The metric will be the difference in the measurement since the last time it was reported.
434
5-
### fix: remove verbose logging - @swcollard PR #401
35+
Some observability vendors require that one is used over the other so we want to support the configuration in the MCP Server.
636
7-
The tracing-subscriber crate we are using to create logs does not have a configuration to exclude the span name and attributes from the log line. This led to rather verbose logs on app startup which would dump the full operation object into the logs before the actual log line.
37+
### Add support for forwarding headers from MCP clients to GraphQL APIs - @DaleSeo PR #428
838
9-
This change strips the attributes from the top level spans so that we still have telemetry and tracing during this important work the server is doing, but they don't make it into the logs. The relevant details are provided in child spans after the operation has been parsed so we aren't losing any information other than a large json blob in the top level trace of generating Tools from GraphQL Operations.
39+
Adds opt-in support for dynamic header forwarding, which enables metadata for A/B testing, feature flagging, geo information from CDNs, or internal instrumentation to be sent from MCP clients to downstream GraphQL APIs. It automatically blocks hop-by-hop headers according to the guidelines in [RFC 7230, section 6.1](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1), and it only works with the Streamable HTTP transport.
40+
41+
You can configure using the `forward_headers` setting:
42+
43+
```yaml
44+
forward_headers:
45+
- x-tenant-id
46+
- x-experiment-id
47+
- x-geo-country
48+
```
49+
50+
Please note that this feature is not intended for passing through credentials as documented in the best practices page.
51+
52+
### feat: Add mcp-session-id header to HTTP request trace attributes - @swcollard PR #421
53+
54+
Includes the value of the [Mcp-Session-Id](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management) HTTP header as an attribute of the trace for HTTP requests to the MCP Server
55+
56+
## 🐛 Fixes
57+
58+
### Fix compatibility issue with VSCode/Copilot - @DaleSeo PR #447
59+
60+
This updates Apollo MCP Server’s tool schemas from [Draft 2020-12](https://json-schema.org/draft/2020-12) to [Draft‑07](https://json-schema.org/draft-07) which is more widely supported across different validators. VSCode/Copilot still validate against Draft‑07, so rejects Apollo MCP Server’s tools. Our JSON schemas don’t rely on newer features, so downgrading improves compatibility across MCP clients with no practical impact.
1061

1162
## 🛠 Maintenance
1263

13-
### deps: update rust to v1.90.0 - @DaleSeo PR #387
64+
### Update rmcp sdk to version 0.8.x - @swcollard PR #433
65+
66+
Bumping the Rust MCP SDK version used in this server up to 0.8.x
67+
68+
### chore: Only initialize a single HTTP client for graphql requests - @swcollard PR #412
69+
70+
Currently the MCP Server spins up a new HTTP client every time it wants to make a request to the downstream graphql endpoint. This change creates a static reqwest client that gets initialized using LazyLock and reused on each graphql request.
1471

15-
Updates the Rust version to v1.90.0
72+
This change is based on the suggestion from the reqwest [documentation](https://docs.rs/reqwest/latest/reqwest/struct.Client.html)
73+
> "The Client holds a connection pool internally, so it is advised that you create one and reuse it."
1674

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ edition = "2024"
1212
license-file = "LICENSE"
1313
repository = "https://github.com/apollographql/apollo-mcp-server"
1414
rust-version = "1.89.0"
15-
version = "1.0.0"
15+
version = "1.1.0-rc.1"
1616

1717
[workspace.dependencies]
1818
apollo-compiler = "1.27.0"

crates/apollo-mcp-server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ regex = "1.11.1"
5050
reqwest-middleware = "0.4.2"
5151
reqwest-tracing = { version = "0.5.8", features = ["opentelemetry_0_30"] }
5252
reqwest.workspace = true
53-
rmcp = { version = "0.6", features = [
53+
rmcp = { version = "0.8", features = [
5454
"server",
5555
"transport-io",
5656
"transport-sse-server",

crates/apollo-mcp-server/src/auth/valid_token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use url::Url;
1212
/// Note: This is used as a marker to ensure that we have validated this
1313
/// separately from just reading the header itself.
1414
#[derive(Clone, Debug, PartialEq)]
15-
pub(crate) struct ValidToken(pub(super) Authorization<Bearer>);
15+
pub(crate) struct ValidToken(pub(crate) Authorization<Bearer>);
1616

1717
impl Deref for ValidToken {
1818
type Target = Authorization<Bearer>;

crates/apollo-mcp-server/src/graphql.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
//! Execute GraphQL operations from an MCP tool
22
3+
use std::sync::LazyLock;
4+
35
use crate::errors::McpError;
46
use crate::generated::telemetry::{TelemetryAttribute, TelemetryMetric};
57
use crate::meter;
68
use opentelemetry::KeyValue;
79
use reqwest::header::{HeaderMap, HeaderValue};
8-
use reqwest_middleware::{ClientBuilder, Extension};
10+
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware, Extension};
911
use reqwest_tracing::{OtelName, TracingMiddleware};
1012
use rmcp::model::{CallToolResult, Content, ErrorCode};
1113
use serde_json::{Map, Value};
@@ -24,6 +26,13 @@ pub struct OperationDetails {
2426
pub operation_name: Option<String>,
2527
}
2628

29+
static GRAPHQL_CLIENT: LazyLock<ClientWithMiddleware> = LazyLock::new(|| {
30+
ClientBuilder::new(reqwest::Client::new())
31+
.with_init(Extension(OtelName("mcp-graphql-client".into())))
32+
.with(TracingMiddleware::default())
33+
.build()
34+
});
35+
2736
/// Able to be executed as a GraphQL operation
2837
pub trait Executable {
2938
/// Get the persisted query ID to be executed, if any
@@ -86,12 +95,7 @@ pub trait Executable {
8695
}
8796
}
8897

89-
let client = ClientBuilder::new(reqwest::Client::new())
90-
.with_init(Extension(OtelName("mcp-graphql-client".into())))
91-
.with(TracingMiddleware::default())
92-
.build();
93-
94-
let result = client
98+
let result = GRAPHQL_CLIENT
9599
.post(request.endpoint.as_str())
96100
.headers(self.headers(&request.headers))
97101
.body(Value::Object(request_body).to_string())

0 commit comments

Comments
 (0)