Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6eb6edf
feat(mcp): embed MCP server with 6 MVP tools behind feature flag
streamkit-devin Apr 23, 2026
dce3b9a
fix(mcp): assert mcp.endpoint starts with /api/ at startup
streamkit-devin Apr 23, 2026
9ffeb7e
fix(mcp): address PR review findings
streamkit-devin Apr 24, 2026
94e6125
fix(mcp): address security and correctness review findings
streamkit-devin Apr 24, 2026
d6259d0
fix(mcp): reject invalid mode values in validate_pipeline
streamkit-devin Apr 24, 2026
a097a26
Merge branch 'main' into devin/1776979022-mcp-server
streamer45 Apr 24, 2026
a2ca337
Merge branch 'main' into devin/1776979022-mcp-server
streamer45 Apr 24, 2026
949ca95
fix(mcp): pre-flight session checks, better error codes, remove wrapp…
streamkit-devin Apr 24, 2026
fe64578
style: apply rustfmt formatting
streamkit-devin Apr 24, 2026
6c7ddce
feat(mcp): add generate_oneshot_command tool (#366)
staging-devin-ai-integration[bot] Apr 24, 2026
69b04dd
feat(mcp): add design_pipeline and debug_pipeline prompts (#367)
staging-devin-ai-integration[bot] Apr 24, 2026
aa16007
feat(mcp): add validate_batch, apply_batch, and tune_node tools (#368)
staging-devin-ai-integration[bot] Apr 24, 2026
7f89346
refactor(mcp): split mcp.rs into mcp/ directory module
streamkit-devin Apr 24, 2026
160b7b9
refactor(mcp): deduplicate batch validation and expose ValidateRespon…
streamkit-devin Apr 24, 2026
aaf4e3f
chore: update Cargo.lock for schemars dependency
streamkit-devin Apr 24, 2026
76e6bff
refactor(mcp): align prompts to idiomatic rmcp #[prompt_router] macros
streamkit-devin Apr 25, 2026
3c67322
feat(mcp): add skit mcp CLI subcommand for STDIO transport
streamkit-devin Apr 25, 2026
4ddae46
ci(mcp): add MCP feature to lint and test CI steps
streamkit-devin Apr 25, 2026
4ab12c6
fix(mcp): resolve clippy warnings uncovered by MCP lint
streamkit-devin Apr 25, 2026
5531be8
fix(mcp): use writeln! instead of write! with trailing newline
streamkit-devin Apr 25, 2026
ae40458
fix(mcp): use struct init in test to satisfy field_reassign_with_default
streamkit-devin Apr 25, 2026
086fac4
refactor(mcp): extract create_dynamic_session shared helper
streamkit-devin Apr 25, 2026
7a09e5c
fix(mcp): address review findings from final pass
streamkit-devin Apr 25, 2026
a7d651c
fix(server): preserve 403 FORBIDDEN for file-path security violations
streamkit-devin Apr 25, 2026
36e21d5
Merge branch 'main' into devin/1776979022-mcp-server
streamer45 Apr 25, 2026
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
2 changes: 2 additions & 0 deletions .github/workflows/skit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
run: |
cargo clippy --locked --workspace --all-targets -- -D warnings
cargo clippy --locked -p streamkit-server --all-targets --features "moq" -- -D warnings
cargo clippy --locked -p streamkit-server --all-targets --features "mcp" -- -D warnings

- name: Install cargo-deny
run: cargo install --locked cargo-deny
Expand Down Expand Up @@ -111,6 +112,7 @@ jobs:
run: |
cargo test --locked --workspace -- --skip gpu_tests::
cargo test --locked -p streamkit-server --features "moq"
cargo test --locked -p streamkit-server --features "mcp"

test-gpu:
name: Test (GPU)
Expand Down
89 changes: 78 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions apps/skit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ moq-lite = { version = "0.15.13", optional = true }
blake2 = "0.10.6"
async-stream = "0.3.6"

# MCP (Model Context Protocol) server (optional)
rmcp = { version = "1.5", features = [
"server", # ServerHandler trait + service runner
"transport-streamable-http-server", # Streamable HTTP transport (tower service)
"transport-streamable-http-server-session", # Stateful session management (LocalSessionManager)
"transport-io", # STDIO transport (stdin/stdout)
"macros", # #[tool], #[tool_router] proc macros
"schemars", # JSON Schema generation for tool arguments
], optional = true }
# Used by the MCP module to extract HTTP request parts from rmcp's request context.
http = { version = "1", optional = true }

[features]
default = ["script", "compositor", "gpu", "moq"]
tokio-console = ["console-subscriber"]
Expand All @@ -145,6 +157,7 @@ profiling = ["dep:pprof", "dep:tikv-jemallocator", "dep:jemalloc_pprof"]
# Use this to find hot allocation sites. Output is written on graceful shutdown.
dhat-heap = ["dep:dhat"]
moq = ["dep:moq-native", "dep:moq-lite"]
mcp = ["dep:rmcp", "dep:http"]
script = ["streamkit-nodes/script", "streamkit-engine/script"]
compositor = ["streamkit-nodes/compositor", "streamkit-engine/compositor"]
gpu = ["compositor", "streamkit-nodes/gpu", "streamkit-engine/gpu"]
Expand Down
40 changes: 40 additions & 0 deletions apps/skit/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub struct Cli {
pub enum Commands {
/// Starts the skit server
Serve,
/// Run the MCP server over STDIO (for MCP client integration)
#[cfg(feature = "mcp")]
Mcp,
/// Manage configuration
#[command(subcommand)]
Config(ConfigCommands),
Expand Down Expand Up @@ -251,6 +254,39 @@ fn log_startup_info(config: &config::Config) {
);
}

/// Handle the "mcp" command — start the MCP server over STDIO.
/// Exits the process on error with status code 1.
///
/// Uses [`crate::logging::init_logging_stderr`] so that tracing output goes
/// to stderr, keeping stdout clean for the JSON-RPC message stream.
#[cfg(feature = "mcp")]
#[allow(clippy::disallowed_macros)]
async fn handle_mcp_command(config_path: &str, _init_logging: LogInitFn) {
let config_result = match config::load(config_path) {
Ok(result) => result,
Err(e) => {
eprintln!("Failed to load configuration: {e}");
std::process::exit(1);
},
};

let _log_guard = match crate::logging::init_logging_stderr(
&config_result.config.log,
&config_result.config.telemetry,
) {
Ok(guard) => guard,
Err(e) => {
eprintln!("Failed to initialize logging: {e}");
std::process::exit(1);
},
};

if let Err(e) = crate::server::start_mcp_stdio(&config_result.config).await {
error!(error = %e, "Failed to start MCP STDIO server");
std::process::exit(1);
}
}

/// Handle the "serve" command - start the server
/// Exits the process on error with status code 1
// Allow eprintln before logging is initialized (CLI output)
Expand Down Expand Up @@ -724,6 +760,10 @@ pub async fn handle_command(cli: &Cli, init_logging: LogInitFn) {
Commands::Serve => {
handle_serve_command(&cli.config, init_logging).await;
},
#[cfg(feature = "mcp")]
Commands::Mcp => {
handle_mcp_command(&cli.config, init_logging).await;
},
Commands::Config(ConfigCommands::Default) => {
handle_config_default_command();
},
Expand Down
Loading
Loading