1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! `mcp start` runtime: serve [`BrontesServer`] over rmcp's stdio transport.
//!
//! This module wires together:
//!
//! 1. The tracing subscriber (always to stderr — stdout is reserved for
//! MCP protocol frames).
//! 2. The rmcp stdio transport ([`rmcp::transport::stdio`]).
//! 3. A signal listener (SIGINT/SIGTERM on Unix; Ctrl+C on Windows) that
//! cancels the running service for graceful shutdown.
//!
//! Mirrors ophis `config.go::serveStdio` (`config.go:88-95`).
use Command;
use ServiceExt;
use stdio;
use ;
use CancellationToken;
use Level;
use crateResult;
use crateConfig;
use crateBrontesServer;
/// Run the MCP server over stdio until the connected client disconnects,
/// the process receives a termination signal, or the cancellation token
/// fires.
///
/// `cli` is the user's full clap tree (cloned by the caller — clap's
/// `get_matches(self)` consumes the original). `cfg_opt` is the optional
/// user configuration; `None` and `Some(Config::default())` produce
/// identical behavior. `log_level_override` is the value of the
/// `--log-level` CLI flag — when set it wins over [`Config::log_level`].
///
/// stdout is reserved for MCP protocol frames; tracing output is always
/// directed to stderr.
///
/// # Errors
///
/// - [`crate::Error::McpInitialize`] if the rmcp transport fails to
/// negotiate the MCP handshake.
/// - [`crate::Error::Panic`] if the awaited rmcp service task panics
/// (the underlying tokio `JoinError`).
pub async
/// Generic core of [`serve_stdio`]: serve [`BrontesServer`] over the
/// supplied `(reader, writer)` transport pair.
///
/// Production code reaches this via [`serve_stdio`] (which passes
/// [`rmcp::transport::stdio`]'s real-stdin / real-stdout pair); the
/// integration test crate passes an in-memory [`tokio::io::duplex`] pair
/// so the server can be driven by a real client peer over a synthetic
/// transport without touching the process stdio. Mirrors the
/// [`crate::server::http::serve_http`] →
/// [`crate::server::http::serve_http_with`] split.
///
/// `pub` (not `pub(crate)`) so the `__test_internal` re-export in
/// `lib.rs` can carry it out; effective visibility is crate-internal.
///
/// # Errors
///
/// Same as [`serve_stdio`].
pub async
/// Install a `tracing_subscriber` pointed at stderr.
///
/// Precedence: explicit override > `Config::log_level` > `RUST_LOG`
/// environment > `INFO`. The call is idempotent — `try_init` returns an
/// error if a subscriber is already installed (e.g., by a host binary's
/// test harness), which we silently ignore.