From 2c09ed6af4cbc66da35e13d2ba3cc79558d9e4d5 Mon Sep 17 00:00:00 2001
From: th-kim0823
Date: Thu, 7 May 2026 15:25:57 +0900
Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20chore(kebab-mcp):=20sca?=
=?UTF-8?q?ffold=20new=20crate=20(fb-30)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Empty lib + serve_stdio entry that bails until Task 3 wires rmcp. Adds
rmcp 1.6 to workspace dependencies (server + macros + transport-io +
schemars features) + tokio multi-thread/io-util/io-std local extensions.
schemars declared as "1" (resolved to 1.2.1) — matches rmcp 1.6's ^1.0
requirement (verified via crates.io /dependencies; plan literal was 0.9
which would conflict). Path-style refs for kebab-app / kebab-config /
kebab-core follow workspace convention.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
Cargo.lock | 118 +++++++++++++++++++++++++++++++++++-
Cargo.toml | 5 ++
crates/kebab-mcp/Cargo.toml | 27 +++++++++
crates/kebab-mcp/src/lib.rs | 16 +++++
4 files changed, 165 insertions(+), 1 deletion(-)
create mode 100644 crates/kebab-mcp/Cargo.toml
create mode 100644 crates/kebab-mcp/src/lib.rs
diff --git a/Cargo.lock b/Cargo.lock
index c4f8ddb..c520efb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -549,7 +549,7 @@ dependencies = [
"log",
"num-rational",
"num-traits",
- "pastey",
+ "pastey 0.1.1",
"rayon",
"thiserror 2.0.18",
"v_frame",
@@ -1229,6 +1229,16 @@ dependencies = [
"darling_macro 0.21.3",
]
+[[package]]
+name = "darling"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
+dependencies = [
+ "darling_core 0.23.0",
+ "darling_macro 0.23.0",
+]
+
[[package]]
name = "darling_core"
version = "0.20.11"
@@ -1257,6 +1267,19 @@ dependencies = [
"syn 2.0.117",
]
+[[package]]
+name = "darling_core"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
+dependencies = [
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.117",
+]
+
[[package]]
name = "darling_macro"
version = "0.20.11"
@@ -1279,6 +1302,17 @@ dependencies = [
"syn 2.0.117",
]
+[[package]]
+name = "darling_macro"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
+dependencies = [
+ "darling_core 0.23.0",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "dary_heap"
version = "0.3.9"
@@ -3666,6 +3700,23 @@ dependencies = [
"wiremock",
]
+[[package]]
+name = "kebab-mcp"
+version = "0.3.0"
+dependencies = [
+ "anyhow",
+ "kebab-app",
+ "kebab-config",
+ "kebab-core",
+ "rmcp",
+ "schemars 1.2.1",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "tokio",
+ "tracing",
+]
+
[[package]]
name = "kebab-normalize"
version = "0.3.0"
@@ -5457,6 +5508,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
+[[package]]
+name = "pastey"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5a797f0e07bdf071d15742978fc3128ec6c22891c31a3a931513263904c982a"
+
[[package]]
name = "path_abs"
version = "0.5.1"
@@ -6306,6 +6363,40 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "rmcp"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12ca9067b5ebfbd5b3fcdc4acfceb81aa7d5ab2a879dff7cb75d22434276aad"
+dependencies = [
+ "async-trait",
+ "chrono",
+ "futures",
+ "pastey 0.2.2",
+ "pin-project-lite",
+ "rmcp-macros",
+ "schemars 1.2.1",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "rmcp-macros"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7caa6743cc0888e433105fe1bc551a7f607940b126a37bc97b478e86064627eb"
+dependencies = [
+ "darling 0.23.0",
+ "proc-macro2",
+ "quote",
+ "serde_json",
+ "syn 2.0.117",
+]
+
[[package]]
name = "roaring"
version = "0.10.12"
@@ -6512,12 +6603,26 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
dependencies = [
+ "chrono",
"dyn-clone",
"ref-cast",
+ "schemars_derive",
"serde",
"serde_json",
]
+[[package]]
+name = "schemars_derive"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde_derive_internals",
+ "syn 2.0.117",
+]
+
[[package]]
name = "scoped-tls"
version = "1.0.1"
@@ -6606,6 +6711,17 @@ dependencies = [
"syn 2.0.117",
]
+[[package]]
+name = "serde_derive_internals"
+version = "0.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "serde_json"
version = "1.0.149"
diff --git a/Cargo.toml b/Cargo.toml
index 62001d6..b37a610 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ members = [
"crates/kebab-parse-image",
"crates/kebab-parse-pdf",
"crates/kebab-tui",
+ "crates/kebab-mcp",
]
[workspace.package]
@@ -71,6 +72,10 @@ futures = "0.3"
# pass; pulled into the workspace deps so future crates can share the
# same major.
regex = "1"
+# MCP (Model Context Protocol) SDK. server + macros + transport-io provide
+# stdio JSON-RPC transport for `kebab-mcp` (p9-fb-30). schemars feature
+# exposes the derive macro used by tool input schemas.
+rmcp = { version = "1.6", default-features = false, features = ["server", "macros", "transport-io", "schemars"] }
# Dev-only HTTP mock server for kebab-llm-local Ollama adapter tests. Requires
# a tokio runtime to host its mock server (the runtime adapter crate stays
# sync via reqwest::blocking — wiremock is dev-only there).
diff --git a/crates/kebab-mcp/Cargo.toml b/crates/kebab-mcp/Cargo.toml
new file mode 100644
index 0000000..dfd6136
--- /dev/null
+++ b/crates/kebab-mcp/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+name = "kebab-mcp"
+edition = { workspace = true }
+rust-version = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+version = { workspace = true }
+
+[dependencies]
+rmcp = { workspace = true }
+# rt-multi-thread + io-util + io-std extend the workspace tokio entry
+# (which only declares rt + macros) for the blocking stdio MCP transport.
+tokio = { workspace = true, features = ["rt-multi-thread", "macros", "io-util", "io-std"] }
+serde = { workspace = true }
+serde_json = { workspace = true }
+anyhow = { workspace = true }
+tracing = { workspace = true }
+# schemars 1.x matches rmcp 1.6's ^1.0 requirement (verified via crates.io
+# /dependencies endpoint — rmcp declares optional schemars = "^1.0").
+schemars = "1"
+
+kebab-app = { path = "../kebab-app" }
+kebab-config = { path = "../kebab-config" }
+kebab-core = { path = "../kebab-core" }
+
+[dev-dependencies]
+tempfile = { workspace = true }
diff --git a/crates/kebab-mcp/src/lib.rs b/crates/kebab-mcp/src/lib.rs
new file mode 100644
index 0000000..a6ac5a0
--- /dev/null
+++ b/crates/kebab-mcp/src/lib.rs
@@ -0,0 +1,16 @@
+//! MCP (Model Context Protocol) server over stdio. Exposes 4 read-only
+//! tools (`search` / `ask` / `schema` / `doctor`) backed by `kebab-app`
+//! facade methods. Used by `kebab-cli`'s `Cmd::Mcp` arm.
+//!
+//! See spec `docs/superpowers/specs/2026-05-07-p9-fb-30-mcp-server-design.md`.
+
+use anyhow::Result;
+
+use kebab_config::Config;
+
+/// Run the MCP server on stdio JSON-RPC. Blocks until the client closes
+/// the stream (typically when the agent host exits).
+pub fn serve_stdio(_cfg: Config) -> Result<()> {
+ // Skeleton — actual rmcp wiring lands in Task 3.
+ anyhow::bail!("kebab-mcp: serve_stdio not yet implemented")
+}