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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! §2 module 15 `mcp.client`: CLI-level proof of exactly when
//! `[capabilities.mcp.servers.*]` is consulted — spawns the real built
//! `supercode` binary, same idiom as `mcp_import_cli.rs`/`mcp_oauth_cli.rs`.
//!
//! BP-1 moved the gate: `capabilities.mcp.enabled = true` in the USER
//! config layer is now the WHOLE answer (`mcp_security.rs` already proves a
//! PROJECT layer can't set it at all). It used to also require
//! `[experimental] module_registry = true`, so the config a user would
//! reasonably write — just `[capabilities.mcp] enabled = true` — silently
//! did nothing. `[experimental] module_registry = false` is the explicit
//! opt-out and still shuts the whole module off.
//!
//! Uses `command = "false"` (a real binary every POSIX system has, that
//! exits immediately doing nothing) as the "MCP server" — not a real MCP
//! server, just a process whose CONNECTION ATTEMPT is externally observable
//! via the `mcp: `probe` connect failed` stderr line, which is exactly the
//! signal these tests check for (present = attempted the entry at all;
//! absent = the module gate correctly skipped it).
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
fn bin() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_supercode"))
}
fn fresh_dir(tag: &str) -> PathBuf {
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let dir = std::env::temp_dir().join(format!(
"supercode-mcpgate-{tag}-{}-{nanos}",
std::process::id()
));
std::fs::create_dir_all(&dir).unwrap();
dir
}
fn run(supercode_home: &Path, project_dir: &Path) -> Output {
Command::new(bin())
.current_dir(project_dir)
.env("SUPERCODE_HOME", supercode_home)
.env("HOME", supercode_home)
// A deliberately bogus key: attach_mcp runs BEFORE the (doomed)
// model call, so the mcp: connect-attempt stderr line is already
// written by the time the run fails on auth — never a real
// network call to a real provider succeeding/spending anything.
.env("OPENROUTER_API_KEY", "dummy-key-never-valid")
.args(["run", "hi", "--dangerous"])
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.output()
.expect("failed to spawn the supercode binary")
}
fn stderr(out: &Output) -> String {
String::from_utf8_lossy(&out.stderr).into_owned()
}
const PROBE_SERVER_TOML: &str = r#"
[capabilities.mcp.servers.probe]
command = "false"
args = []
"#;
/// The module's own bit is off (a `[capabilities.mcp.servers.*]` table
/// alone never sets `enabled`), so the entry is never attempted.
#[test]
fn module_off_by_default_never_attempts_a_capabilities_mcp_servers_entry() {
let home = fresh_dir("off");
let project = fresh_dir("off-project");
std::fs::write(
home.join("config.toml"),
format!("schema_version = 1\n{PROBE_SERVER_TOML}"),
)
.unwrap();
let out = run(&home, &project);
let err = stderr(&out);
assert!(
!err.contains("probe"),
"capabilities.mcp.servers.probe must never be attempted with the mcp module off: {err}"
);
std::fs::remove_dir_all(&home).ok();
std::fs::remove_dir_all(&project).ok();
}
/// BP-1: `capabilities.mcp.enabled = true` ALONE — no `[experimental]`
/// table anywhere — is the config a user would reasonably write expecting
/// it to just work, and it now does.
#[test]
fn mcp_enabled_true_alone_attempts_the_capabilities_mcp_servers_entry() {
let home = fresh_dir("on");
let project = fresh_dir("on-project");
std::fs::write(
home.join("config.toml"),
format!("schema_version = 1\n[capabilities.mcp]\nenabled = true\n{PROBE_SERVER_TOML}"),
)
.unwrap();
let out = run(&home, &project);
let err = stderr(&out);
assert!(
err.contains("probe"),
"with capabilities.mcp.enabled on, the capabilities.mcp.servers entry \
must be attempted: {err}"
);
std::fs::remove_dir_all(&home).ok();
std::fs::remove_dir_all(&project).ok();
}
/// The explicit opt-out is load-bearing: `[experimental] module_registry =
/// false` puts the whole module resolution back on the legacy path, so even
/// `capabilities.mcp.enabled = true` is not consulted.
#[test]
fn module_registry_false_opts_out_of_the_capabilities_mcp_servers_entry() {
let home = fresh_dir("optout");
let project = fresh_dir("optout-project");
std::fs::write(
home.join("config.toml"),
format!(
"schema_version = 1\n[experimental]\nmodule_registry = false\n\
[capabilities.mcp]\nenabled = true\n{PROBE_SERVER_TOML}"
),
)
.unwrap();
let out = run(&home, &project);
let err = stderr(&out);
assert!(
!err.contains("probe"),
"module_registry = false must skip the capabilities.mcp.servers entry: {err}"
);
std::fs::remove_dir_all(&home).ok();
std::fs::remove_dir_all(&project).ok();
}