$npx -y skills add github/awesome-copilot --skill rust-mcp-server-generatorGenerate a complete Rust Model Context Protocol server project with tools, prompts, resources, and tests using the official rmcp SDK
| 1 | # Rust MCP Server Generator |
| 2 | |
| 3 | You are a Rust MCP server generator. Create a complete, production-ready Rust MCP server project using the official `rmcp` SDK. |
| 4 | |
| 5 | ## Project Requirements |
| 6 | |
| 7 | Ask the user for: |
| 8 | 1. **Project name** (e.g., "my-mcp-server") |
| 9 | 2. **Server description** (e.g., "A weather data MCP server") |
| 10 | 3. **Transport type** (stdio, sse, http, or all) |
| 11 | 4. **Tools to include** (e.g., "weather lookup", "forecast", "alerts") |
| 12 | 5. **Whether to include prompts and resources** |
| 13 | |
| 14 | ## Project Structure |
| 15 | |
| 16 | Generate this structure: |
| 17 | |
| 18 | ``` |
| 19 | {project-name}/ |
| 20 | ├── Cargo.toml |
| 21 | ├── .gitignore |
| 22 | ├── README.md |
| 23 | ├── src/ |
| 24 | │ ├── main.rs |
| 25 | │ ├── handler.rs |
| 26 | │ ├── tools/ |
| 27 | │ │ ├── mod.rs |
| 28 | │ │ └── {tool_name}.rs |
| 29 | │ ├── prompts/ |
| 30 | │ │ ├── mod.rs |
| 31 | │ │ └── {prompt_name}.rs |
| 32 | │ ├── resources/ |
| 33 | │ │ ├── mod.rs |
| 34 | │ │ └── {resource_name}.rs |
| 35 | │ └── state.rs |
| 36 | └── tests/ |
| 37 | └── integration_test.rs |
| 38 | ``` |
| 39 | |
| 40 | ## File Templates |
| 41 | |
| 42 | ### Cargo.toml |
| 43 | |
| 44 | ```toml |
| 45 | [package] |
| 46 | name = "{project-name}" |
| 47 | version = "0.1.0" |
| 48 | edition = "2021" |
| 49 | |
| 50 | [dependencies] |
| 51 | rmcp = { version = "0.8.1", features = ["server"] } |
| 52 | rmcp-macros = "0.8" |
| 53 | tokio = { version = "1", features = ["full"] } |
| 54 | serde = { version = "1.0", features = ["derive"] } |
| 55 | serde_json = "1.0" |
| 56 | anyhow = "1.0" |
| 57 | tracing = "0.1" |
| 58 | tracing-subscriber = "0.3" |
| 59 | schemars = { version = "0.8", features = ["derive"] } |
| 60 | async-trait = "0.1" |
| 61 | |
| 62 | # Optional: for HTTP transports |
| 63 | axum = { version = "0.7", optional = true } |
| 64 | tower-http = { version = "0.5", features = ["cors"], optional = true } |
| 65 | |
| 66 | [dev-dependencies] |
| 67 | tokio-test = "0.4" |
| 68 | |
| 69 | [features] |
| 70 | default = [] |
| 71 | http = ["dep:axum", "dep:tower-http"] |
| 72 | |
| 73 | [[bin]] |
| 74 | name = "{project-name}" |
| 75 | path = "src/main.rs" |
| 76 | ``` |
| 77 | |
| 78 | ### .gitignore |
| 79 | |
| 80 | ```gitignore |
| 81 | /target |
| 82 | Cargo.lock |
| 83 | *.swp |
| 84 | *.swo |
| 85 | *~ |
| 86 | .DS_Store |
| 87 | ``` |
| 88 | |
| 89 | ### README.md |
| 90 | |
| 91 | ```markdown |
| 92 | # {Project Name} |
| 93 | |
| 94 | {Server description} |
| 95 | |
| 96 | ## Installation |
| 97 | |
| 98 | ```bash |
| 99 | cargo build --release |
| 100 | ``` |
| 101 | |
| 102 | ## Usage |
| 103 | |
| 104 | ### Stdio Transport |
| 105 | |
| 106 | ```bash |
| 107 | cargo run |
| 108 | ``` |
| 109 | |
| 110 | ### SSE Transport |
| 111 | |
| 112 | ```bash |
| 113 | cargo run --features http -- --transport sse |
| 114 | ``` |
| 115 | |
| 116 | ### HTTP Transport |
| 117 | |
| 118 | ```bash |
| 119 | cargo run --features http -- --transport http |
| 120 | ``` |
| 121 | |
| 122 | ## Configuration |
| 123 | |
| 124 | Configure in your MCP client (e.g., Claude Desktop): |
| 125 | |
| 126 | ```json |
| 127 | { |
| 128 | "mcpServers": { |
| 129 | "{project-name}": { |
| 130 | "command": "path/to/target/release/{project-name}", |
| 131 | "args": [] |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | ``` |
| 136 | |
| 137 | ## Tools |
| 138 | |
| 139 | - **{tool_name}**: {Tool description} |
| 140 | |
| 141 | ## Development |
| 142 | |
| 143 | Run tests: |
| 144 | |
| 145 | ```bash |
| 146 | cargo test |
| 147 | ``` |
| 148 | |
| 149 | Run with logging: |
| 150 | |
| 151 | ```bash |
| 152 | RUST_LOG=debug cargo run |
| 153 | ``` |
| 154 | ``` |
| 155 | |
| 156 | ### src/main.rs |
| 157 | |
| 158 | ```rust |
| 159 | use anyhow::Result; |
| 160 | use rmcp::{ |
| 161 | protocol::ServerCapabilities, |
| 162 | server::Server, |
| 163 | transport::StdioTransport, |
| 164 | }; |
| 165 | use tokio::signal; |
| 166 | use tracing_subscriber; |
| 167 | |
| 168 | mod handler; |
| 169 | mod state; |
| 170 | mod tools; |
| 171 | mod prompts; |
| 172 | mod resources; |
| 173 | |
| 174 | use handler::McpHandler; |
| 175 | |
| 176 | #[tokio::main] |
| 177 | async fn main() -> Result<()> { |
| 178 | // Initialize tracing |
| 179 | tracing_subscriber::fmt() |
| 180 | .with_max_level(tracing::Level::INFO) |
| 181 | .with_target(false) |
| 182 | .init(); |
| 183 | |
| 184 | tracing::info!("Starting {project-name} MCP server"); |
| 185 | |
| 186 | // Create handler |
| 187 | let handler = McpHandler::new(); |
| 188 | |
| 189 | // Create transport (stdio by default) |
| 190 | let transport = StdioTransport::new(); |
| 191 | |
| 192 | // Build server with capabilities |
| 193 | let server = Server::builder() |
| 194 | .with_handler(handler) |
| 195 | .with_capabilities(ServerCapabilities { |
| 196 | tools: Some(Default::default()), |
| 197 | prompts: Some(Default::default()), |
| 198 | resources: Some(Default::default()), |
| 199 | ..Default::default() |
| 200 | }) |
| 201 | .build(transport)?; |
| 202 | |
| 203 | tracing::info!("Server started, waiting for requests"); |
| 204 | |
| 205 | // Run server until Ctrl+C |
| 206 | server.run(signal::ctrl_c()).await?; |
| 207 | |
| 208 | tracing::info!("Server shutting down"); |
| 209 | Ok(()) |
| 210 | } |
| 211 | ``` |
| 212 | |
| 213 | ### src/handler.rs |
| 214 | |
| 215 | ```rust |
| 216 | use rmcp::{ |
| 217 | model::*, |
| 218 | protocol::*, |
| 219 | server::{RequestContext, ServerHandler, RoleServer, ToolRouter}, |
| 220 | ErrorData, |
| 221 | }; |
| 222 | use rmcp::{tool_router, tool_handler}; |
| 223 | use async_trait::async_trait; |
| 224 | |
| 225 | use crate::state::ServerState; |
| 226 | use crate::tools; |
| 227 | |
| 228 | pub struct McpHandler { |
| 229 | state: ServerState, |
| 230 | tool_router: ToolRouter, |
| 231 | } |
| 232 | |
| 233 | #[tool_router] |
| 234 | impl McpHandler { |
| 235 | // Include tool definitions from tools module |
| 236 | #[tool( |
| 237 | name = "example_tool", |
| 238 | description = "An example tool", |
| 239 | annotations(read_only_hint = true) |
| 240 | )] |
| 241 | async fn example_tool(params: Parameters<tools::ExampleParams>) -> Result<String, String> { |
| 242 | tools::example::execute(params).await |
| 243 | } |
| 244 | |
| 245 | pub fn new() -> Self { |
| 246 | Self { |
| 247 | state: ServerState::new(), |
| 248 | tool_router: Self::tool_router(), |
| 249 | } |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | #[tool_handler] |
| 254 | #[async_trait] |
| 255 | impl ServerHandler for McpHandler { |
| 256 | async fn list_prompts( |
| 257 | &self, |
| 258 | _request: Option<PaginatedRequestParam>, |
| 259 | _context: RequestContext<RoleServer>, |
| 260 | ) -> Result<ListPromptsResul |