Skip to content

Commit b9d59e8

Browse files
committed
Model Context Protocol (MCP) implementation ; increase coverage
1 parent 033a12e commit b9d59e8

30 files changed

Lines changed: 5709 additions & 24 deletions

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ repos:
6666

6767
- id: update-coverage
6868
name: Update Coverage Badges
69-
entry: python scripts/update_coverage.py
70-
language: python
69+
entry: python3 scripts/update_coverage.py
70+
language: system
7171
pass_filenames: false
7272
always_run: true

README.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ cdd-rust
33
[![License](https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg)](https://opensource.org/licenses/Apache-2.0)
44
[![interactive WASM web demo](https://img.shields.io/badge/interactive-WASM_web_demo-blue.svg)](https://offscale.io/wasm_web_demo)
55
[![CI](https://github.com/offscale/cdd-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/offscale/cdd-rust/actions)
6-
[![Test Coverage](https://img.shields.io/badge/test_coverage-77.24%25-yellow.svg)](#)
6+
[![Test Coverage](https://img.shields.io/badge/test_coverage-100.00%25-brightgreen.svg)](#)
77
[![Doc Coverage](https://img.shields.io/badge/doc_coverage-100.00%25-brightgreen.svg)](#)
88

99
----
@@ -83,34 +83,42 @@ The `cdd-rust` compiler leverages a unified architecture to support various face
8383

8484
`cdd-rust` supports extensive backwards compatibility features:
8585
- **Legacy Swagger 2.0 Support:** Natively parses and processes legacy `swagger: "2.0"` specifications in addition to OpenAPI 3.x, ensuring seamless backwards compatibility and bridging older APIs into the modern Rust ecosystem.
86+
- **Model Context Protocol (MCP):** Exposes CLI commands as an MCP server over STDIO, allowing seamless integration with AI agents and other MCP clients.
8687

8788
## CLI Options
8889

8990
```text
9091
CDD Toolchain CLI
9192
93+
Language-Specific Commands:
94+
sync Synchronize DB schema to Rust models and OpenAPI-ready structs.
95+
test-gen Generates integration tests based on OpenAPI contracts.
96+
scaffold Scaffolds handler functions from OpenAPI Routes.
97+
schema-gen Generates a JSON Schema from a Rust struct or enum.
98+
9299
Usage: cdd-rust [OPTIONS] <COMMAND>
93100
94101
Commands:
95102
sync Synchronize DB schema to Rust models and OpenAPI-ready structs
96103
test-gen Generates integration tests based on OpenAPI contracts
97104
scaffold Scaffolds handler functions from OpenAPI Routes
98105
schema-gen Generates a JSON Schema from a Rust struct or enum
99-
to_docs_json Generate JSON documentation with code snippets for an OpenAPI specification.
100-
from_openapi Generate code from an OpenAPI specification.
101-
to_openapi Generate an OpenAPI specification from source code.
102-
serve_json_rpc Expose CLI interface as a JSON-RPC server.
106+
to_docs_json Generate JSON documentation with code snippets for an OpenAPI specification
107+
from_openapi Generate code from an OpenAPI specification
108+
to_openapi Generate an OpenAPI specification from source code
109+
serve_json_rpc Expose CLI interface as a JSON-RPC server
110+
mcp Expose CLI interface as an MCP server over STDIO
103111
help Print this message or the help of the given subcommand(s)
104112
105113
Options:
106114
-t, --target <TARGET>
107115
Target mode (server or client)
108116
109117
Possible values:
110-
- server-actix: Generate Actix Web server scaffolding
111-
- server-axum: Generate Axum server scaffolding
112-
- client: Generate Reqwest client scaffolding
113-
- cli: Generate Clap CLI scaffolding
118+
- server-actix: Actix Web Server
119+
- server-axum: Axum Server
120+
- client-reqwest: Reqwest Client
121+
- client-internal: Internal
114122
115123
[env: CDD_TARGET=]
116124
[default: server-actix]

cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cdd-cli"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
edition = "2021"
55

66
[[bin]]

cli/src/from_openapi.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub enum FromOpenApiCommands {
3636
/// Generate a Client SDK
3737
#[clap(name = "to_sdk")]
3838
Sdk(GenerateArgs),
39+
/// Generate an MCP Programmatic Tool Adapter SDK
40+
#[clap(name = "to_sdk_mcp")]
41+
SdkMcp(GenerateArgs),
3942
/// Generate Server scaffolding
4043
#[clap(name = "to_server")]
4144
Server {
@@ -121,6 +124,10 @@ pub fn execute(args: &FromOpenApiArgs) -> AppResult<()> {
121124
println!("Generating SDK...");
122125
run_generation(gen_args, &ReqwestStrategy)?;
123126
}
127+
FromOpenApiCommands::SdkMcp(gen_args) => {
128+
println!("Generating MCP SDK...");
129+
run_generation(gen_args, &cdd_core::strategies::McpClientStrategy)?;
130+
}
124131
FromOpenApiCommands::Server {
125132
args: gen_args,
126133
framework,
@@ -432,6 +439,19 @@ components:
432439
};
433440
assert!(execute(&args).is_ok());
434441

442+
// Test SdkMcp
443+
let args = FromOpenApiArgs {
444+
command: FromOpenApiCommands::SdkMcp(GenerateArgs {
445+
input: Some(input_file.clone()),
446+
input_dir: None,
447+
output_dir: Some(dir.path().join("out_mcp")),
448+
no_github_actions: false,
449+
no_installable_package: false,
450+
tests: false,
451+
}),
452+
};
453+
assert!(execute(&args).is_ok());
454+
435455
// Test Server with ActixWeb
436456
let args = FromOpenApiArgs {
437457
command: FromOpenApiCommands::Server {
@@ -512,6 +532,15 @@ components:
512532
let _ = run_generation(&args, &cdd_core::strategies::ActixStrategy);
513533
Ok(())
514534
}
535+
#[test]
536+
fn test_generate_from_openapi_unknown_subcommand() {
537+
let config = FromOpenApiConfig {
538+
subcommand: "unknown_cmd".to_string(),
539+
..Default::default()
540+
};
541+
let result = generate_from_openapi(&config);
542+
assert!(result.is_err());
543+
}
515544
}
516545

517546
/// Configuration for `from_openapi` programmatic API
@@ -541,6 +570,7 @@ pub fn generate_from_openapi(config: &FromOpenApiConfig) -> AppResult<()> {
541570
match config.subcommand.as_str() {
542571
"to_sdk_cli" => run_generation(&gen_args, &ClapCliStrategy),
543572
"to_sdk" => run_generation(&gen_args, &ReqwestStrategy),
573+
"to_sdk_mcp" => run_generation(&gen_args, &cdd_core::strategies::McpClientStrategy),
544574
"to_server" => match config.framework {
545575
ServerFramework::ActixWeb => {
546576
run_generation(&gen_args, &cdd_core::strategies::ActixStrategy)

cli/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
pub mod from_openapi;
55
pub mod generator;
6+
pub mod mcp;
67
pub mod scaffold;
78
pub mod schema_gen;
89
#[cfg(all(feature = "server", not(target_os = "wasi")))]

cli/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ enum Commands {
9393
/// Fallback for missing server feature
9494
#[cfg(any(not(feature = "server"), target_os = "wasi"))]
9595
ServeJsonRpc,
96+
/// Expose CLI interface as an MCP server over STDIO.
97+
#[clap(name = "mcp")]
98+
Mcp(cdd_cli::mcp::McpArgs),
9699
}
97100

98101
/// The main entry point of the CLI application.
@@ -146,6 +149,9 @@ fn main() -> AppResult<()> {
146149
"Server feature is not compiled or not supported on this platform".to_string(),
147150
));
148151
}
152+
Commands::Mcp(args) => {
153+
cdd_cli::mcp::serve_mcp(args)?;
154+
}
149155
}
150156

151157
Ok(())

0 commit comments

Comments
 (0)