Chapter 1: Getting Started and Crate Setup
April 13, 2026 ยท View on GitHub
Welcome to Chapter 1: Getting Started and Crate Setup. In this part of MCP Rust SDK Tutorial: Building High-Performance MCP Services with RMCP, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
This chapter defines a clean onboarding baseline for rmcp projects.
Learning Goals
- choose the right crate and feature set for your first implementation
- align runtime dependencies (
tokio,serde,schemars) to SDK expectations - bootstrap minimal client/server flows quickly
- avoid over-enabling transport/auth features before needed
Baseline Setup
rmcp = { version = "0.15", features = ["server"] }
Start with one transport path and one capability surface, then add features incrementally.
Source References
Summary
You now have a dependency baseline that keeps early integrations predictable.
Next: Chapter 2: Service Model and Macro-Based Tooling
Source Code Walkthrough
crates/rmcp/src/service.rs
The serve_directly function in crates/rmcp/src/service.rs handles a key part of this chapter's functionality:
/// Use this function to skip initialization process
pub fn serve_directly<R, S, T, E, A>(
service: S,
transport: T,
peer_info: Option<R::PeerInfo>,
) -> RunningService<R, S>
where
R: ServiceRole,
S: Service<R>,
T: IntoTransport<R, E, A>,
E: std::error::Error + Send + Sync + 'static,
{
serve_directly_with_ct(service, transport, peer_info, Default::default())
}
/// Use this function to skip initialization process
pub fn serve_directly_with_ct<R, S, T, E, A>(
service: S,
transport: T,
peer_info: Option<R::PeerInfo>,
ct: CancellationToken,
) -> RunningService<R, S>
where
R: ServiceRole,
S: Service<R>,
T: IntoTransport<R, E, A>,
E: std::error::Error + Send + Sync + 'static,
{
let (peer, peer_rx) = Peer::new(Arc::new(AtomicU32RequestIdProvider::default()), peer_info);
serve_inner(service, transport.into_transport(), peer, peer_rx, ct)
}
This function is important because it defines how MCP Rust SDK Tutorial: Building High-Performance MCP Services with RMCP implements the patterns covered in this chapter.
crates/rmcp/src/service.rs
The serve_directly_with_ct function in crates/rmcp/src/service.rs handles a key part of this chapter's functionality:
E: std::error::Error + Send + Sync + 'static,
{
serve_directly_with_ct(service, transport, peer_info, Default::default())
}
/// Use this function to skip initialization process
pub fn serve_directly_with_ct<R, S, T, E, A>(
service: S,
transport: T,
peer_info: Option<R::PeerInfo>,
ct: CancellationToken,
) -> RunningService<R, S>
where
R: ServiceRole,
S: Service<R>,
T: IntoTransport<R, E, A>,
E: std::error::Error + Send + Sync + 'static,
{
let (peer, peer_rx) = Peer::new(Arc::new(AtomicU32RequestIdProvider::default()), peer_info);
serve_inner(service, transport.into_transport(), peer, peer_rx, ct)
}
/// Spawn a task that may hold `!Send` state when the `local` feature is active.
///
/// Without the `local` feature this is `tokio::spawn` (requires `Future: Send + 'static`).
/// With `local` it uses `tokio::task::spawn_local` (requires only `Future: 'static`).
#[cfg(not(feature = "local"))]
fn spawn_service_task<F>(future: F) -> tokio::task::JoinHandle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
This function is important because it defines how MCP Rust SDK Tutorial: Building High-Performance MCP Services with RMCP implements the patterns covered in this chapter.
crates/rmcp/src/service.rs
The to interface in crates/rmcp/src/service.rs handles a key part of this chapter's functionality:
NumberOrString, ProgressToken, RequestId,
},
transport::{DynamicTransportError, IntoTransport, Transport},
};
#[cfg(feature = "client")]
mod client;
#[cfg(feature = "client")]
pub use client::*;
#[cfg(feature = "server")]
mod server;
#[cfg(feature = "server")]
pub use server::*;
#[cfg(feature = "tower")]
mod tower;
use tokio_util::sync::{CancellationToken, DropGuard};
#[cfg(feature = "tower")]
pub use tower::*;
use tracing::{Instrument as _, instrument};
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum ServiceError {
#[error("Mcp error: {0}")]
McpError(McpError),
#[error("Transport send error: {0}")]
TransportSend(DynamicTransportError),
#[error("Transport closed")]
TransportClosed,
#[error("Unexpected response type")]
UnexpectedResponse,
#[error("task cancelled for reason {}", reason.as_deref().unwrap_or("<unknown>"))]
Cancelled { reason: Option<String> },
#[error("request timeout after {}", chrono::Duration::from_std(*timeout).unwrap_or_default())]
This interface is important because it defines how MCP Rust SDK Tutorial: Building High-Performance MCP Services with RMCP implements the patterns covered in this chapter.
crates/rmcp/src/service.rs
The to interface in crates/rmcp/src/service.rs handles a key part of this chapter's functionality:
NumberOrString, ProgressToken, RequestId,
},
transport::{DynamicTransportError, IntoTransport, Transport},
};
#[cfg(feature = "client")]
mod client;
#[cfg(feature = "client")]
pub use client::*;
#[cfg(feature = "server")]
mod server;
#[cfg(feature = "server")]
pub use server::*;
#[cfg(feature = "tower")]
mod tower;
use tokio_util::sync::{CancellationToken, DropGuard};
#[cfg(feature = "tower")]
pub use tower::*;
use tracing::{Instrument as _, instrument};
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum ServiceError {
#[error("Mcp error: {0}")]
McpError(McpError),
#[error("Transport send error: {0}")]
TransportSend(DynamicTransportError),
#[error("Transport closed")]
TransportClosed,
#[error("Unexpected response type")]
UnexpectedResponse,
#[error("task cancelled for reason {}", reason.as_deref().unwrap_or("<unknown>"))]
Cancelled { reason: Option<String> },
#[error("request timeout after {}", chrono::Duration::from_std(*timeout).unwrap_or_default())]
This interface is important because it defines how MCP Rust SDK Tutorial: Building High-Performance MCP Services with RMCP implements the patterns covered in this chapter.
How These Components Connect
flowchart TD
A[serve_directly]
B[serve_directly_with_ct]
C[to]
D[to]
E[to]
A --> B
B --> C
C --> D
D --> E