fix(mcp): accept explicit font directories before startup

This commit is contained in:
Seamile committed 2026-10-10 12:05:56 +08:00
1 parent 1f8eb76437
commit 5171717e71
5 files changed
+68

No files matched your search

+1
View File
@@ -535,6 +535,7 @@ Optional flags (both transports):
|------|-------------|
| `--proxy <URL>` | HTTP/SOCKS5 proxy |
| `--user-agent <UA>` | Custom User-Agent string |
| `--font-dir <DIR>` | Load additional fonts before rendering (repeatable; render build) |
| `--stealth` | Enable anti-detection mode |
### Claude Desktop config
+21
View File
@@ -193,6 +193,10 @@ enum Command {
},
Mcp {
/// Recursively load additional font files before the first render.
#[arg(long = "font-dir", value_name = "DIR")]
font_dirs: Vec<std::path::PathBuf>,
#[arg(long)]
http: bool,
@@ -587,12 +591,14 @@ async fn run_cli() -> anyhow::Result<()> {
.await?;
}
Some(Command::Mcp {
font_dirs,
http,
host,
port,
proxy,
user_agent,
}) => {
configure_font_directories(&font_dirs)?;
let mcp_proxy = merge_proxy(global_proxy.clone(), proxy);
if http {
obscura_mcp::http::run(host, port, mcp_proxy, user_agent, stealth).await?;
@@ -2497,6 +2503,21 @@ mod tests {
}
}
#[test]
fn parsed_mcp_accepts_repeated_font_directories() {
let args = Args::try_parse_from([
"obscura", "mcp", "--font-dir", "/fonts/cjk", "--font-dir", "/fonts/brand",
])
.expect("clap should accept MCP font directories");
match args.command {
Some(Command::Mcp { font_dirs, .. }) => assert_eq!(
font_dirs,
[std::path::PathBuf::from("/fonts/cjk"), std::path::PathBuf::from("/fonts/brand")]
),
_ => panic!("expected Mcp command"),
}
}
#[test]
fn no_subcommand_is_not_quiet() {
assert!(!is_quiet_command(&None));
+33
View File
@@ -7,6 +7,39 @@ use std::thread::JoinHandle;
use std::time::Duration;
const OBSCURA: &str = env!("CARGO_BIN_EXE_obscura");
#[test]
fn mcp_font_directory_is_validated_before_either_transport_starts() {
let missing = std::env::temp_dir().join(format!("obscura-missing-fonts-{}", std::process::id()));
assert!(!missing.exists());
for http in [false, true] {
let mut command = Command::new(OBSCURA);
command.args(["mcp", "--font-dir"]).arg(&missing).stdin(Stdio::null());
if http {
command.args(["--http", "--port", "0"]);
}
let output = command.output().expect("start MCP with invalid font directory");
assert!(!output.status.success());
assert!(String::from_utf8_lossy(&output.stderr).contains("Font directory does not exist"));
}
}
#[test]
fn mcp_font_directory_respects_render_feature() {
let output = Command::new(OBSCURA)
.args(["mcp", "--font-dir"])
.arg(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests"))
.stdin(Stdio::null())
.output()
.expect("start MCP with existing font directory");
if cfg!(feature = "render") {
assert!(output.status.success(), "{}", String::from_utf8_lossy(&output.stderr));
} else {
assert!(!output.status.success());
assert!(String::from_utf8_lossy(&output.stderr).contains("--font-dir requires a render-enabled build"));
}
}
const TEST_PAGE: &str = r#"<!doctype html><html><head><title>Example Domain</title></head>
<body><h1>Example Domain</h1><p>Deterministic local MCP fixture.</p>
<a href="/more">More information...</a></body></html>"#;
+1
View File
@@ -112,6 +112,7 @@ Run obscura as an MCP server.
```
--http HTTP transport instead of stdio
--font-dir <DIR> Load additional fonts before rendering (repeatable; render build)
--host <HOST> HTTP bind host (default 127.0.0.1)
--port <PORT> HTTP port (default 3000)
--proxy <URL> HTTP or SOCKS5 proxy
+12
View File
@@ -1,5 +1,17 @@
`obscura mcp` exposes obscura as a Model Context Protocol server so MCP-capable clients (Claude Desktop, Claude Code, etc.) can drive it.
Render-enabled builds can load additional fonts for screenshots and PDF output:
```bash
obscura mcp --font-dir /path/to/fonts
```
Repeat `--font-dir` to load multiple directories. It recursively loads TTF, TTC,
OTF, and OTC files once before rendering, using the same opt-in font database as
`obscura serve`. System fonts are not scanned automatically. Invalid directories
fail at startup, and no-render builds reject a nonempty font directory option.
The option works with both stdio and HTTP transports.
## Run
Stdio (default, for direct client integration):