Skip to main content

mcpkit_core/
lib.rs

1//! # mcp-core
2//!
3//! Core types and traits for the Model Context Protocol (MCP) SDK.
4//!
5//! This crate provides the foundational building blocks for the MCP SDK:
6//!
7//! - **Protocol types**: JSON-RPC 2.0 request/response/notification types
8//! - **MCP types**: Tools, resources, prompts, tasks, content, sampling, elicitation
9//! - **Capability negotiation**: Client and server capabilities
10//! - **Error handling**: Unified `McpError` type with rich diagnostics
11//! - **Typestate connection**: Compile-time enforced connection lifecycle
12//!
13//! This crate is runtime-agnostic and does not depend on any async runtime.
14//! It can be used with Tokio, smol, or any other executor.
15//!
16//! # Protocol Version
17//!
18//! This crate implements MCP protocol version **2025-11-25**.
19//!
20//! # Example
21//!
22//! ```rust
23//! use mcpkit_core::{
24//!     types::{Tool, ToolOutput, Content},
25//!     capability::{ServerCapabilities, ServerInfo},
26//!     state::Connection,
27//! };
28//!
29//! // Create a tool definition
30//! let tool = Tool::new("search")
31//!     .description("Search the database")
32//!     .input_schema(serde_json::json!({
33//!         "type": "object",
34//!         "properties": {
35//!             "query": { "type": "string" }
36//!         },
37//!         "required": ["query"]
38//!     }));
39//!
40//! // Create server capabilities
41//! let caps = ServerCapabilities::new()
42//!     .with_tools()
43//!     .with_resources()
44//!     .with_tasks();
45//!
46//! // Create server info
47//! let info = ServerInfo::new("my-server", "1.0.0");
48//! ```
49//!
50//! # Feature Flags
51//!
52//! - **`fancy-errors`**: Enable miette's fancy error reporting with terminal
53//!   colors and formatting.
54//!
55//! - **`jwt`**: Enable JWT validation helpers with JWKS fetching. This adds
56//!   the `auth::jwt` module with functions for validating JWT access tokens
57//!   and fetching JSON Web Key Sets from authorization servers.
58
59#![deny(missing_docs)]
60
61pub mod auth;
62pub mod capability;
63pub mod debug;
64pub mod error;
65pub mod extension;
66pub mod protocol;
67pub mod protocol_version;
68pub mod schema;
69pub mod state;
70pub mod types;
71
72// Re-export commonly used types at the crate root
73pub use capability::{
74    ClientCapabilities, ClientInfo, InitializeRequest, InitializeResult, PROTOCOL_VERSION,
75    SUPPORTED_PROTOCOL_VERSIONS, ServerCapabilities, ServerInfo, VersionNegotiationResult,
76    is_version_supported, negotiate_version, negotiate_version_detailed,
77};
78pub use error::{JsonRpcError, McpError, McpResultExt};
79pub use protocol::{Message, Notification, ProgressToken, Request, RequestId, Response};
80pub use protocol_version::ProtocolVersion;
81pub use state::{Closing, Connected, Connection, Disconnected, Initializing, Ready};
82
83/// Prelude module for convenient imports.
84///
85/// # Example
86///
87/// ```rust
88/// use mcpkit_core::prelude::*;
89/// ```
90pub mod prelude {
91    // Re-export common serde types for convenience
92    pub use serde::{Deserialize, Serialize};
93    pub use serde_json::json;
94
95    pub use crate::capability::{
96        ClientCapabilities, ClientInfo, InitializeRequest, InitializeResult, PROTOCOL_VERSION,
97        SUPPORTED_PROTOCOL_VERSIONS, ServerCapabilities, ServerInfo, VersionNegotiationResult,
98        is_version_supported, negotiate_version, negotiate_version_detailed,
99    };
100    pub use crate::error::{McpError, McpResultExt};
101    pub use crate::protocol::{Message, Notification, ProgressToken, Request, RequestId, Response};
102    pub use crate::protocol_version::ProtocolVersion;
103    pub use crate::schema::{Schema, SchemaBuilder, SchemaType};
104    pub use crate::state::{Closing, Connected, Connection, Disconnected, Initializing, Ready};
105    pub use crate::types::{
106        // Tool types
107        CallToolResult,
108        // Content types
109        Content,
110        ContentAnnotations,
111        // Sampling types
112        CreateMessageRequest,
113        CreateMessageResult,
114        // Elicitation types
115        ElicitAction,
116        ElicitRequest,
117        ElicitResult,
118        ElicitationSchema,
119        // Prompt types
120        GetPromptResult,
121        ModelPreferences,
122        Prompt,
123        PromptArgument,
124        PromptMessage,
125        PromptOutput,
126        PropertySchema,
127        // Resource types
128        Resource,
129        ResourceContents,
130        ResourceTemplate,
131        Role,
132        SamplingMessage,
133        StopReason,
134        // Task types
135        Task,
136        TaskError,
137        TaskId,
138        TaskProgress,
139        TaskStatus,
140        TaskSummary,
141        Tool,
142        ToolAnnotations,
143        ToolOutput,
144    };
145}
146
147#[cfg(test)]
148mod tests {
149    use super::*;
150
151    #[test]
152    fn test_prelude_imports() {
153        use crate::prelude::*;
154
155        // Just verify that all the types are accessible
156        let _tool = Tool::new("test");
157        let _caps = ServerCapabilities::new().with_tools();
158        let _conn: Connection<Disconnected> = Connection::new();
159    }
160
161    #[test]
162    fn test_protocol_version() {
163        assert_eq!(PROTOCOL_VERSION, "2025-11-25");
164    }
165
166    #[test]
167    fn test_error_context() {
168        use crate::error::McpResultExt;
169
170        fn might_fail() -> Result<(), McpError> {
171            Err(McpError::InternalMessage {
172                message: "something went wrong".to_string(),
173            })
174        }
175
176        let result = might_fail().context("while doing something important");
177        assert!(result.is_err());
178
179        let err = result.unwrap_err();
180        assert!(err.to_string().contains("while doing something important"));
181    }
182}