Skip to main content

mcpr_core/proxy/pipeline/
context.rs

1//! Per-request context threaded through the pipeline.
2//!
3//! [`RequestContext`] is a one-pass parse of the incoming HTTP request
4//! that every downstream stage reads from instead of re-parsing.
5//! Handlers update a small set of mutable fields (session id after
6//! upstream assigns one, client name/version after session lookup)
7//! before handing off to [`super::emit::emit_request_event`].
8//!
9//! Response-side state now lives as local variables inside each handler
10//! in [`super::handlers`] — there's no shared `ResponseContext` blob
11//! passed between stages anymore.
12
13use std::time::Instant;
14
15use crate::protocol::session::ClientInfo;
16use crate::protocol::{McpMethod, ParsedBody};
17use axum::http::Method;
18
19pub struct RequestContext {
20    pub start: Instant,
21
22    // ── HTTP ──
23    pub http_method: Method,
24    pub path: String,
25    pub request_size: usize,
26    pub wants_sse: bool,
27
28    // ── Session (set from header; overwritten when upstream assigns one) ──
29    pub session_id: Option<String>,
30
31    // ── JSON-RPC / MCP (None when the body is not JSON-RPC) ──
32    pub jsonrpc: Option<ParsedBody>,
33    pub mcp_method: Option<McpMethod>,
34    /// String form for event output. Set to the protocol method for MCP POSTs
35    /// and overwritten by specific handlers where appropriate (e.g. "SSE").
36    pub mcp_method_str: Option<String>,
37    /// `tools/call` tool name; `None` for other methods.
38    pub tool: Option<String>,
39    pub is_batch: bool,
40
41    // ── Client info ──
42    /// Parsed from `initialize` params. The Initialize success path stores
43    /// this into the session store.
44    pub client_info_from_init: Option<ClientInfo>,
45    /// Resolved from the session store by the handler before emit.
46    pub client_name: Option<String>,
47    pub client_version: Option<String>,
48
49    /// Transform tags pushed by handlers. The emit stage joins them
50    /// with `+` to build the `RequestEvent.note` field
51    /// (e.g. `["rewritten", "sse"]` → `"rewritten+sse"`).
52    pub tags: Vec<&'static str>,
53}