# Core Concepts FastRMCP primitives you will touch in every server. See [Tools/Resources/Prompts](Tools-Resources-Prompts.md) for macro details. ## Context - Injected via `Context` parameter (optional) into tools/resources/prompts. - Carries `server_info`, optional `client_info`, `request_id`, metadata map, and a notification sender. - Progress + logs: `ctx.report_progress(progress, total, Some("msg"))` and `ctx.log_info(...)` emit MCP notifications; falls back to `tracing` if no transport hook. - Metadata: `ctx.set_metadata("key", json!(value)).await` and `ctx.get_metadata("key").await` for middleware/handler sharing. Avoid blocking on metadata inside tight loops. - ID helper: `Context::generate_id()` for unique tokens. ## State - Type-safe shared container (`fastrmcp::state::State`) stored on `FastMCP` and clonable. - Insert at startup: `.with_state(|state| state.insert(DatabasePool::new()).unwrap())`. - Access inside handlers by adding `State` param and `state.get::()?` returning `Arc`. - Lifetime nuance: `get()` returns `Arc` clones that remain valid even after `remove()`/`clear()`—plan for that if you hot-swap state. ## Registries - Auto-registration via inventory for `#[tool]`, `#[resource]`, `#[prompt]`. - Tool/Prompt registries validate uniqueness; Resource registry also validates URI template collisions. - Required order: FastMCP sets `server_info` before `register_from_inventory` so `#[resource]` fallback contexts have server metadata—don’t bypass `FastMCP::new(...).run()` with manual registration unless you call `resource_registry.set_server_info(...)` first; otherwise resources will error with “Server info not set before resource registration.” - Lookup helpers: `server.tool_registry().list()`, `.get(name)`, same for resources/prompts. ## Lifecycle Hooks - `#[on_startup]` and `#[on_shutdown]` macros register async hooks run before the main loop and during graceful shutdown. - Best for initializing stateful services, warming caches, or flushing telemetry. - Hooks run sequentially; return `Result<()>` to fail fast on critical setup errors. ## Subscriptions - Built-in `SubscriptionManager` exposed from the handler; resources are subscribable out of the box when using `#[resource]`. - Protocol methods: `resources/subscribe`, `resources/unsubscribe`, `resources/list_subscriptions`. - Notifications flow through transports; see [Subscriptions & Notifications](Subscriptions.md) and [Transports Guide](Transports-Guide.md) for connectionId handling. ## Error Model - Primary error: `fastrmcp_core::error::MCPError` with JSON-RPC-friendly codes. - Common variants: `InvalidParams`, `MethodNotFound`, `ResourceNotFound`, `PromptNotFound`, `TransportError`, `Custom { code, message, data }`. - Return `Result` (alias to `Result`) from handlers; convert IO/serde errors via `?` (From implementations map to `TransportError`/`ParseError`/`SerializationError`). - For validation, prefer `InvalidParams` so clients get actionable feedback; use `ServerError` with specific codes (-32099..-32000) for server-specific faults. Related: [Tools/Resources/Prompts](Tools-Resources-Prompts.md) • [Middleware Cookbook](Middleware-Cookbook.md) • [Observability](Observability.md) [Back to Home](Home.md)