Skip to content

Commit 477d0e4

Browse files
authored
Merge pull request #643 from apollographql/clean-up-sse
refactor: clean up SSE transport variant
2 parents 498f231 + f3c1d0c commit 477d0e4

File tree

6 files changed

+72
-94
lines changed

6 files changed

+72
-94
lines changed

AGENTS.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ cargo doc --no-deps
3636
cargo llvm-cov --all-features --workspace --codecov --output-path codecov.json
3737
```
3838

39+
## Runtime Quick Reference
40+
41+
- Start with config file: `cargo run -p apollo-mcp-server -- path/to/config.yaml`
42+
- Start from env only: `cargo run -p apollo-mcp-server`
43+
- Config precedence: `APOLLO_MCP_*` env overrides YAML values.
44+
- Supported transports: `stdio` (default) and `streamable_http`; `sse` is not supported.
45+
- YAML env expansion supports `${env.VAR}` and `${env.VAR:-default}`.
46+
47+
### Common Config Keys
48+
49+
- Top-level keys: `endpoint`, `transport`, `operations`, `schema`, `introspection`, `graphos`, `overrides`, `headers`, `forward_headers`, `health_check`, `cors`, `telemetry`, `logging`, `server_info`, `custom_scalars`.
50+
- `auth` must be nested under `transport` (not top-level).
51+
- `operations.source`: `infer` (default), `local`, `manifest`, `collection`, `introspect`, `uplink`.
52+
- `schema.source`: `local` or `uplink`.
53+
54+
### Useful Env Vars
55+
56+
- GraphOS mapping:
57+
- `APOLLO_GRAPH_REF` -> `graphos.apollo_graph_ref`
58+
- `APOLLO_KEY` -> `graphos.apollo_key`
59+
- `APOLLO_UPLINK_ENDPOINTS` -> `graphos.apollo_uplink_endpoints`
60+
- Nested config override format: `APOLLO_MCP_<SECTION>__<NESTED_KEY>=...`
61+
- Example: `APOLLO_MCP_INTROSPECTION__EXECUTE__ENABLED=true`
62+
3963
## Workspace Structure
4064

4165
The project is a Rust workspace with three crates:

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@ pub enum ServerError {
109109

110110
#[error("TLS configuration error: {0}")]
111111
Tls(#[from] crate::auth::TlsConfigError),
112-
113-
#[error("Unsupported transport: {0}")]
114-
UnsupportedTransport(String),
115112
}
116113

117114
/// An MCP tool error

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,16 @@ async fn main() -> anyhow::Result<()> {
133133
.disable_type_description(config.overrides.disable_type_description)
134134
.disable_schema_description(config.overrides.disable_schema_description)
135135
.enable_output_schema(config.overrides.enable_output_schema)
136-
.disable_auth_token_passthrough(match transport {
137-
apollo_mcp_server::server::Transport::Stdio => false,
138-
apollo_mcp_server::server::Transport::SSE { auth, .. } => auth
139-
.map(|a| a.disable_auth_token_passthrough)
140-
.unwrap_or(false),
141-
apollo_mcp_server::server::Transport::StreamableHttp { auth, .. } => auth
142-
.map(|a| a.disable_auth_token_passthrough)
143-
.unwrap_or(false),
144-
})
136+
.disable_auth_token_passthrough(
137+
if let apollo_mcp_server::server::Transport::StreamableHttp {
138+
auth: Some(auth), ..
139+
} = &transport
140+
{
141+
auth.disable_auth_token_passthrough
142+
} else {
143+
false
144+
},
145+
)
145146
.custom_scalar_map(
146147
config
147148
.custom_scalars

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

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,11 @@ pub enum Transport {
6161
#[default]
6262
Stdio,
6363

64-
/// Host the MCP server on the supplied configuration, using SSE for communication
65-
///
66-
/// Note: This is deprecated in favor of HTTP streams.
67-
#[serde(rename = "sse")]
68-
SSE {
69-
/// Authentication configuration
70-
#[serde(default)]
71-
auth: Option<auth::Config>,
72-
73-
/// The IP address to bind to
74-
#[serde(default = "Transport::default_address")]
75-
address: IpAddr,
76-
77-
/// The port to bind to
78-
#[serde(default = "Transport::default_port")]
79-
port: u16,
80-
},
81-
8264
/// Host the MCP server on the configuration, using streamable HTTP messages.
8365
StreamableHttp {
8466
/// Authentication configuration
8567
#[serde(default)]
86-
auth: Option<auth::Config>,
68+
auth: Option<Box<auth::Config>>,
8769

8870
/// The IP address to bind to
8971
#[serde(default = "Transport::default_address")]
@@ -191,3 +173,32 @@ impl Server {
191173
StateMachine {}.start(self).await
192174
}
193175
}
176+
177+
#[cfg(test)]
178+
mod tests {
179+
use super::Transport;
180+
181+
#[test]
182+
fn sse_transport_is_rejected_at_parse_time() {
183+
let yaml = "type: sse\nport: 8000";
184+
let result = serde_yaml::from_str::<Transport>(yaml);
185+
assert!(result.is_err(), "Expected SSE transport to be rejected");
186+
}
187+
188+
#[test]
189+
fn stdio_transport_parses() {
190+
let yaml = "type: stdio";
191+
let result = serde_yaml::from_str::<Transport>(yaml);
192+
assert!(result.is_ok(), "Expected stdio transport to parse");
193+
}
194+
195+
#[test]
196+
fn streamable_http_transport_parses() {
197+
let yaml = "type: streamable_http\nport: 9000";
198+
let result = serde_yaml::from_str::<Transport>(yaml);
199+
assert!(
200+
result.is_ok(),
201+
"Expected streamable_http transport to parse"
202+
);
203+
}
204+
}

crates/apollo-mcp-server/src/server/states/starting.rs

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ impl Starting {
138138

139139
let cancellation_token = CancellationToken::new();
140140

141-
// Create health check if enabled (only for StreamableHttp transport)
141+
// Create health checks only when StreamableHttp transport is enabled.
142142
let health_check = match (&self.config.transport, self.config.health_check.enabled) {
143143
(Transport::StreamableHttp { .. }, true) => {
144144
Some(HealthCheck::new(self.config.health_check.clone()))
145145
}
146-
_ => None, // No health check for SSE, Stdio, or when disabled
146+
_ => None, // No health checks for Stdio or when disabled.
147147
};
148148

149149
let running = Running {
@@ -261,18 +261,6 @@ impl Starting {
261261
}
262262
});
263263
}
264-
Transport::SSE {
265-
auth: _,
266-
address: _,
267-
port: _,
268-
} => {
269-
// SSE transport has been removed in rmcp 0.11+
270-
// Users should migrate to streamable_http transport
271-
return Err(ServerError::UnsupportedTransport(
272-
"SSE transport is no longer supported. Please use streamable_http transport instead. \
273-
Update your config to use `transport: { type: streamable_http }`.".to_string()
274-
));
275-
}
276264
Transport::Stdio => {
277265
info!("Starting MCP server in stdio mode");
278266
let service = running
@@ -348,53 +336,4 @@ mod tests {
348336
let running = starting.start();
349337
assert!(running.await.is_ok());
350338
}
351-
352-
#[tokio::test]
353-
async fn start_sse_server_returns_unsupported_error() {
354-
let starting = Starting {
355-
config: Config {
356-
transport: Transport::SSE {
357-
auth: None,
358-
address: "127.0.0.1".parse().unwrap(),
359-
port: 7798,
360-
},
361-
endpoint: Url::parse("http://localhost:4000").expect("valid url"),
362-
mutation_mode: MutationMode::All,
363-
execute_introspection: true,
364-
headers: HeaderMap::new(),
365-
forward_headers: vec![],
366-
validate_introspection: true,
367-
introspect_introspection: true,
368-
search_introspection: true,
369-
introspect_minify: false,
370-
search_minify: false,
371-
execute_tool_hint: None,
372-
introspect_tool_hint: None,
373-
search_tool_hint: None,
374-
validate_tool_hint: None,
375-
explorer_graph_ref: None,
376-
custom_scalar_map: None,
377-
disable_type_description: false,
378-
disable_schema_description: false,
379-
enable_output_schema: false,
380-
disable_auth_token_passthrough: false,
381-
search_leaf_depth: 5,
382-
index_memory_bytes: 1024 * 1024 * 1024,
383-
health_check: HealthCheckConfig::default(),
384-
cors: Default::default(),
385-
server_info: Default::default(),
386-
},
387-
schema: Schema::parse_and_validate("type Query { hello: String }", "test.graphql")
388-
.expect("Valid schema"),
389-
operations: vec![],
390-
};
391-
let result = starting.start().await;
392-
match result {
393-
Err(ServerError::UnsupportedTransport(msg)) => {
394-
assert!(msg.contains("SSE transport is no longer supported"));
395-
}
396-
Err(e) => panic!("Expected UnsupportedTransport error, got: {:?}", e),
397-
Ok(_) => panic!("Expected error, got Ok"),
398-
}
399-
}
400339
}

docs/source/config-file.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ The available fields depend on the value of the nested `type` key. The default t
227227
| `"stdio"` | Use standard IO for communication between the server and client |
228228
| `"streamable_http"` | Host the MCP server on the configuration, using streamable HTTP messages |
229229

230+
<Note>
231+
232+
SSE transport is no longer supported by Apollo MCP Server as of v1.5.0. Use `streamable_http` for HTTP-based connections.
233+
234+
</Note>
235+
230236
##### Transport Type Specific options
231237

232238
Some transport types support further configuration. For `streamable_http`, you can set `address`, `port`, `stateful_mode`, and `host_validation`.

0 commit comments

Comments
 (0)