fix: propagate trace context and baggage to MCP servers by ENCHIGO · Pull Request #473 · vllm-project/agentic-api · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/agentic-server-core/src/tool/mcp/bounded_http.rs
19 changes: 19 additions & 0 deletions crates/agentic-server-core/src/tool/mcp/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::process::Command;

use super::bounded_http::BoundedMcpHttpClient;
use super::propagation::W3cPropagation;

const CONNECTION_TIMEOUT: Duration = Duration::from_secs(30);
const TOOL_TIMEOUT: Duration = Duration::from_secs(60);
Expand Down Expand Up @@ -106,6 +107,8 @@ impl ClientHandler for AgenticMcpClientHandler {
pub struct McpClient {
inner: Arc<RunningService<RoleClient, AgenticMcpClientHandler>>,
tool_timeout: Duration,
/// Whether `tools/call` carries the caller's trace context and baggage.
propagate_trace_context: bool,
}

impl McpClient {
Expand Down Expand Up @@ -148,6 +151,7 @@ impl McpClient {
Ok(Self {
inner: Arc::new(service),
tool_timeout: TOOL_TIMEOUT,
propagate_trace_context: false,
})
}

Expand Down Expand Up @@ -216,9 +220,21 @@ impl McpClient {
Ok(Self {
inner: Arc::new(service),
tool_timeout: TOOL_TIMEOUT,
propagate_trace_context: false,
})
}

/// Send the caller's trace context and baggage with every `tools/call`.
///
/// Off by default. Baggage can hold values an operator's edge added to the
/// inbound request, so only servers the operator configured are trusted with
/// it; a server URL supplied in a request may belong to anyone.
#[must_use]
pub fn with_trace_context_propagation(mut self) -> Self {
self.propagate_trace_context = true;
self
}

/// Lists all tools exposed by the connected MCP server, following cursor-based pagination.
///
/// # Errors
Expand Down Expand Up @@ -292,6 +308,9 @@ impl McpClient {

let mut params = CallToolRequestParams::new(name.to_owned());
params.arguments = arguments;
if self.propagate_trace_context {
params.meta = W3cPropagation::capture().into_meta();
}

let result = tokio::time::timeout(self.tool_timeout, async {
self.inner
Expand Down
1 change: 1 addition & 0 deletions crates/agentic-server-core/src/tool/mcp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod bounded_http;
pub mod client;
pub mod handler;
pub mod pool;
mod propagation;
pub mod registry;

pub use client::{McpClient, McpError, McpOperation};
Expand Down
16 changes: 15 additions & 1 deletion crates/agentic-server-core/src/tool/mcp/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,17 @@ impl McpClientPool {
.iter()
.filter_map(|param| server_entry_from_param(param, allowed_hosts))
.collect();
Self::from_config(servers).await
// Request-declared servers are third parties: no trace context or baggage.
Self::connect_all(servers, false).await
}

/// Connect the servers an operator configured. They are trusted with the
/// caller's trace context and baggage.
pub async fn from_config(servers: HashMap<String, McpServerEntry>) -> Self {
Self::connect_all(servers, true).await
}

async fn connect_all(servers: HashMap<String, McpServerEntry>, propagate_trace_context: bool) -> Self {
let mut clients = HashMap::with_capacity(servers.len());
let mut connection_errors = HashMap::new();

Expand All @@ -90,6 +97,13 @@ impl McpClientPool {
} => McpClient::connect_stdio(&command, &args, env.as_ref(), cwd.as_deref()).await,
};

let result = result.map(|client| {
if propagate_trace_context {
client.with_trace_context_propagation()
} else {
client
}
});
match result {
Ok(client) => {
clients.insert(server_label, Arc::new(client));
Expand Down
227 changes: 227 additions & 0 deletions crates/agentic-server-core/src/tool/mcp/propagation.rs
Loading
Loading