Skip to content

feat(mcp): in-process invocation, OpenAPI→MCP CLI, stdio transport + v0.1.504#197

Merged
Tuntii merged 3 commits into
mainfrom
release/v0.1.504-mcp-features
Jun 19, 2026
Merged

feat(mcp): in-process invocation, OpenAPI→MCP CLI, stdio transport + v0.1.504#197
Tuntii merged 3 commits into
mainfrom
release/v0.1.504-mcp-features

Conversation

@Tuntii

@Tuntii Tuntii commented Jun 19, 2026

Copy link
Copy Markdown
Owner

This PR delivers the two main growth items for MCP:

In-Process Invocation

  • InvocationMode::InProcess / Auto
  • RustApi::request_dispatcher() + RequestInvoker
  • Direct dispatch through Router/LayerStack (no TCP)
  • ~28µs per call vs ~1.3ms proxy (live server benchmark, ~48x)

OpenAPI → MCP CLI

  • cargo rustapi mcp generate --spec|--url|--api ...
  • Works with any OpenAPI 3.x (FastAPI, Express, etc.)
  • --stdio for desktop clients

Other

  • New cookbook recipes (in-process, CLI, stdio)
  • README + CHANGELOG updates
  • OpenAPI parser tolerance improvements

Benchmark (1000 calls):
In-process: 28ms total (28µs avg)
Proxy (live): 1.34s total (1.3ms avg)

Ready for release v0.1.504.

- Add InvocationMode and RequestInvoker for zero-overhead in-process tool calls (~28µs vs ~1.3ms proxy).
- Add 'rustapi mcp generate' CLI to turn any OpenAPI spec into MCP server.
- Add --stdio support.
- Live server benchmark (~48x speedup).
- Cookbook recipes, README, CHANGELOG updates.
- OpenAPI deserializer improvements for external specs.

v0.1.504 release prep.
Copilot AI review requested due to automatic review settings June 19, 2026 13:39
@github-actions github-actions Bot added the feat label Jun 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands RustAPI’s MCP capabilities by adding an in-process invocation path (bypassing HTTP proxy overhead), introducing an OpenAPI→MCP generator subcommand in cargo-rustapi (including stdio mode), and updating docs/changelog/versioning for the v0.1.504 release.

Changes:

  • Added InvocationMode + in-process dispatch plumbing (RustApi::request_dispatcher, MCP RequestInvoker) and updated MCP server execution strategy.
  • Added cargo rustapi mcp generate to spin up an MCP server from any OpenAPI 3.x spec (file/URL/api), including stdio transport.
  • Improved OpenAPI spec deserialization tolerance and updated cookbook/README/CHANGELOG + workspace version bump to 0.1.504.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Updates MCP feature summary to reflect in-process, CLI generator, stdio.
docs/cookbook/src/SUMMARY.md Adds new MCP recipe entries to cookbook navigation.
docs/cookbook/src/recipes/mcp_stdio.md Documents stdio transport usage and limitations.
docs/cookbook/src/recipes/mcp_openapi_cli.md Documents OpenAPI→MCP CLI generator usage and flags.
docs/cookbook/src/recipes/mcp_in_process.md Documents in-process invocation, modes, and benchmark reference.
crates/rustapi-openapi/src/spec.rs Adds serde defaults + Default derives to accept partial/real-world specs.
crates/rustapi-mcp/tests/mcp_e2e.rs Adds a proxy-vs-in-process benchmark-style test.
crates/rustapi-mcp/src/server.rs Adds optional in-process execution path and core request/response conversion.
crates/rustapi-mcp/src/lib.rs Re-exports InvocationMode and wires up invocation module.
crates/rustapi-mcp/src/invocation.rs Implements RequestInvoker for in-process dispatch via RequestDispatcher.
crates/rustapi-mcp/src/config.rs Adds InvocationMode and config setter invocation_mode(...).
crates/rustapi-core/src/server.rs Exposes routing helpers to support in-process dispatch.
crates/rustapi-core/src/router.rs Derives Clone for Router to enable safe sharing.
crates/rustapi-core/src/lib.rs Re-exports RequestDispatcher from the core crate.
crates/rustapi-core/src/app.rs Adds RequestDispatcher and RustApi::request_dispatcher(); exposes router accessor.
crates/cargo-rustapi/src/commands/mod.rs Registers MCP command module behind the mcp feature.
crates/cargo-rustapi/src/commands/mcp.rs Implements rustapi mcp generate + stdio loop and spec loading.
crates/cargo-rustapi/src/cli.rs Adds mcp subcommand wiring behind the mcp feature.
crates/cargo-rustapi/README.md Documents new cargo rustapi mcp generate command in CLI table.
crates/cargo-rustapi/Cargo.toml Adds MCP deps/features and enables mcp by default; updates Tokio features.
CHANGELOG.md Adds v0.1.504 release notes describing MCP growth items and OpenAPI tolerance.
Cargo.toml Bumps workspace version to 0.1.504.
Cargo.lock Updates lockfile versions and adds new deps for MCP CLI support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/rustapi-mcp/src/server.rs Outdated
Comment on lines +330 to +334
let state = Arc::new(Extensions::new());
let path_params = PathParams::new();

let core_req =
CoreRequest::new(parts, BodyVariant::Buffered(body_bytes), state, path_params);
Comment on lines +110 to +133
let addr = format!("0.0.0.0:{}", args.port);

println!(" ✓ Spec loaded");
println!(" → Proxying tool calls to: {}", target);
println!(" → MCP server listening on: http://{}", addr);
println!();
println!("Useful test commands:");
println!(
" curl -X POST http://127.0.0.1:{} -H 'content-type: application/json' \\",
args.port
);
println!(" -d '{{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}}'");
println!();
println!(
" curl -X POST http://127.0.0.1:{} -H 'content-type: application/json' \\",
args.port
);
println!(" -d '{{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}}'");
println!();
if args.stdio {
println!("🧠 MCP stdio transport active. Waiting for JSON-RPC on stdin...");
run_stdio(mcp).await?;
return Ok(());
}
Comment on lines +194 to +209
"tools/list" => match mcp.list_tools().await {
Ok(tools) => {
let tool_defs: Vec<_> = tools
.into_iter()
.map(|t| {
serde_json::json!({
"name": t.name,
"description": t.description,
"inputSchema": t.input_schema
})
})
.collect();
serde_json::json!({ "tools": tool_defs })
}
Err(e) => serde_json::json!({ "error": e.to_string() }),
},
Comment thread crates/rustapi-mcp/tests/mcp_e2e.rs
Comment thread crates/rustapi-mcp/src/server.rs Outdated
Comment on lines +80 to +83
// Capture in-process dispatcher when the mode calls for it.
// We always capture it here; `call_tool` decides at runtime based on mode.
let dispatcher = app.request_dispatcher();
server.invoker = Some(RequestInvoker::new(dispatcher, server.config.clone()));
Tuntii added 2 commits June 19, 2026 16:47
- Use router.state_ref() for in-process CoreRequest construction (preserves State<T>)
- Conditional invoker capture in from_rustapi based on mode (no unnecessary work for Proxy)
- Fix stdio: no misleading HTTP/curl output, default to 127.0.0.1
- Proper JSON-RPC error object for tools/list failures in stdio
- Mark benchmark test #[ignore] to avoid flaky CI timing asserts
…cipes README

- Escape State<T> in doc comment to fix rustdoc warning
- Expose RequestDispatcher in rustapi-rs facade (core + prelude)
- Sync recipes/README.md with new MCP recipes (in-process, CLI, stdio)
@Tuntii Tuntii merged commit ab00b1c into main Jun 19, 2026
7 checks passed
github-actions Bot pushed a commit that referenced this pull request Jun 19, 2026
…0.1.504-mcp-features

feat(mcp): in-process invocation, OpenAPI→MCP CLI, stdio transport + v0.1.504 ab00b1c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants