[package] name = "rmcp" license = { workspace = true } version = { workspace = true } edition = { workspace = true } repository = { workspace = true } homepage = { workspace = true } readme = { workspace = true } description = "Rust SDK for Model Context Protocol" documentation = "https://docs.rs/rmcp" [lints.clippy] exhaustive_structs = "warn" exhaustive_enums = "warn" [package.metadata.docs.rs] features = [ "auth", "auth-client-credentials-jwt", "base64", "client", "client-side-sse", "elicitation", "macros", "reqwest", "reqwest-native-tls", "reqwest-tls-no-provider", "schemars", "server", "server-side-http", "tower", "transport-async-rw", "transport-child-process", "transport-io", "transport-streamable-http-client", "transport-streamable-http-client-reqwest", "transport-streamable-http-client-unix-socket", "transport-streamable-http-server", "transport-streamable-http-server-session", "transport-worker", "uuid", ] rustdoc-args = ["--cfg", "docsrs"] [dependencies] async-trait = "0.1.89" serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" thiserror = "2" tokio = { version = "1", features = ["sync", "macros", "rt", "time"] } futures = "0.3" tracing = { version = "0.1" } tokio-util = { version = "0.7" } pin-project-lite = "0.2" pastey = { version = "0.2.0", optional = true } # oauth2 support oauth2 = { version = "5.0", optional = true, default-features = false } # JWT signing for client credentials (private_key_jwt) jsonwebtoken = { version = "10", optional = true } # for auto generate schema schemars = { version = "1.0", optional = true, features = ["chrono04"] } # for image encoding base64 = { version = "0.22", optional = true } # for HTTP client reqwest = { version = "0.13.2", default-features = false, features = [ "json", "stream", ], optional = true } sse-stream = { version = "0.2", optional = true } http = { version = "1", optional = true } url = { version = "2.4", optional = true } # For tower compatibility tower-service = { version = "0.3", optional = true } # for child process transport process-wrap = { version = "9.0", features = ["tokio1"], optional = true } # for cross-platform executable path resolution which = { version = "8", optional = true } # for ws transport # tokio-tungstenite ={ version = "0.26", optional = true } # for http-server transport rand = { version = "0.10", optional = true } tokio-stream = { version = "0.1", optional = true } uuid = { version = "1", features = ["v4"], optional = true } http-body = { version = "1", optional = true } http-body-util = { version = "0.1", optional = true } bytes = { version = "1", optional = true } # for unix socket transport hyper = { version = "1", features = ["client", "http1"], optional = true } hyper-util = { version = "0.1", features = ["tokio"], optional = true } # macro rmcp-macros = { workspace = true, optional = true } [target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dependencies] chrono = { version = "0.4.38", default-features = false, features = ["serde", "now"] } [target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] chrono = { version = "0.4.38", default-features = false, features = [ "serde", "clock", "std", "oldtime", ] } [features] default = ["base64", "macros", "server"] local = ["rmcp-macros?/local"] client = ["dep:tokio-stream"] server = ["transport-async-rw", "dep:schemars", "dep:pastey"] macros = ["dep:rmcp-macros", "dep:pastey"] elicitation = ["dep:url"] # reqwest http client __reqwest = ["dep:reqwest"] reqwest = ["__reqwest", "reqwest?/rustls"] reqwest-tls-no-provider = ["__reqwest", "reqwest?/rustls-no-provider"] reqwest-native-tls = ["__reqwest", "reqwest?/native-tls"] server-side-http = [ "uuid", "dep:rand", "dep:tokio-stream", "dep:http", "dep:http-body", "dep:http-body-util", "dep:bytes", "dep:sse-stream", "tower", ] transport-worker = ["dep:tokio-stream"] # SSE stream parsing utilities (used by streamable HTTP client for SSE-formatted responses) client-side-sse = ["dep:sse-stream", "dep:http"] # Streamable HTTP client transport-streamable-http-client = ["client-side-sse", "transport-worker"] transport-streamable-http-client-reqwest = ["transport-streamable-http-client", "__reqwest"] transport-streamable-http-client-unix-socket = [ "transport-streamable-http-client", "dep:hyper", "dep:hyper-util", "dep:http-body-util", "dep:http", "dep:bytes", "tokio/net", ] transport-async-rw = ["tokio/io-util", "tokio-util/codec"] transport-io = ["transport-async-rw", "tokio/io-std"] transport-child-process = [ "transport-async-rw", "tokio/process", "dep:process-wrap", ] which-command = [ "transport-child-process", "dep:which", ] transport-streamable-http-server = [ "transport-streamable-http-server-session", "server-side-http", "transport-worker", ] transport-streamable-http-server-session = [ "transport-async-rw", "dep:tokio-stream", ] # transport-ws = ["transport-io", "dep:tokio-tungstenite"] tower = ["dep:tower-service"] auth = ["dep:oauth2", "__reqwest", "dep:url"] auth-client-credentials-jwt = ["auth", "dep:jsonwebtoken", "uuid"] schemars = ["dep:schemars"] [dev-dependencies] tokio = { version = "1", features = ["full"] } schemars = { version = "1.1.0", features = ["chrono04"] } axum = { version = "0.8", default-features = false, features = ["http1", "tokio"] } hyper = { version = "1", features = ["server", "http1"] } hyper-util = { version = "0.1", features = ["tokio"] } tower-service = "0.3" url = "2.4" anyhow = "1.0" tracing-subscriber = { version = "0.3", features = [ "env-filter", "std", "fmt", ] } async-trait = "0.1" rstest = "0.26.1" [[test]] name = "test_tool_macros" required-features = ["server", "client"] path = "tests/test_tool_macros.rs" [[test]] name = "test_with_python" required-features = [ "reqwest", "server", "client", "transport-child-process", ] path = "tests/test_with_python.rs" [[test]] name = "test_with_js" required-features = [ "server", "client", "transport-child-process", "transport-streamable-http-server", "transport-streamable-http-client", "__reqwest", ] path = "tests/test_with_js.rs" [[test]] name = "test_notification" required-features = ["server", "client"] path = "tests/test_notification.rs" [[test]] name = "test_logging" required-features = ["server", "client"] path = "tests/test_logging.rs" [[test]] name = "test_message_protocol" required-features = ["client"] path = "tests/test_message_protocol.rs" [[test]] name = "test_message_schema" required-features = ["server", "client", "schemars"] path = "tests/test_message_schema.rs" [[test]] name = "test_progress_subscriber" required-features = ["server", "client", "macros"] path = "tests/test_progress_subscriber.rs" [[test]] name = "test_request_timeout_progress" required-features = ["server", "client", "macros"] path = "tests/test_request_timeout_progress.rs" [[test]] name = "test_elicitation" required-features = ["elicitation", "client", "server"] path = "tests/test_elicitation.rs" [[test]] name = "test_task" required-features = ["server", "client", "macros"] path = "tests/test_task.rs" [[test]] name = "test_streamable_http_priming" required-features = ["server", "client", "transport-streamable-http-server", "reqwest"] path = "tests/test_streamable_http_priming.rs" [[test]] name = "test_streamable_http_json_response" required-features = ["server", "client", "transport-streamable-http-server", "reqwest"] path = "tests/test_streamable_http_json_response.rs" [[test]] name = "test_streamable_http_protocol_version" required-features = ["server", "client", "transport-streamable-http-server", "reqwest"] path = "tests/test_streamable_http_protocol_version.rs" [[test]] name = "test_stateless_protocol_version" required-features = ["server", "transport-streamable-http-server", "reqwest"] path = "tests/test_stateless_protocol_version.rs" [[test]] name = "test_protocol_version_negotiation" required-features = ["server", "client"] path = "tests/test_protocol_version_negotiation.rs" [[test]] name = "test_streamable_http_4xx_error_body" required-features = ["transport-streamable-http-client", "transport-streamable-http-client-reqwest"] path = "tests/test_streamable_http_4xx_error_body.rs" [[test]] name = "test_custom_request" required-features = ["server", "client"] path = "tests/test_custom_request.rs" [[test]] name = "test_trace_context" required-features = ["server", "client"] path = "tests/test_trace_context.rs" [[test]] name = "test_prompt_macros" required-features = ["server", "client"] path = "tests/test_prompt_macros.rs" [[test]] name = "test_sampling" required-features = ["server", "client"] path = "tests/test_sampling.rs" [[test]] name = "test_close_connection" required-features = ["server", "client"] path = "tests/test_close_connection.rs" [[test]] name = "test_custom_headers" required-features = [ "client", "server", "transport-streamable-http-client-reqwest", "transport-streamable-http-server", ] path = "tests/test_custom_headers.rs" [[test]] name = "test_sse_concurrent_streams" required-features = ["server", "client", "transport-streamable-http-server", "transport-streamable-http-client", "reqwest"] path = "tests/test_sse_concurrent_streams.rs" [[test]] name = "test_client_credentials" required-features = ["auth"] path = "tests/test_client_credentials.rs" [[test]] name = "test_unix_socket_transport" required-features = [ "client", "server", "transport-streamable-http-client-unix-socket", ] path = "tests/test_unix_socket_transport.rs" [[test]] name = "test_streamable_http_stale_session" required-features = [ "server", "client", "transport-streamable-http-server", "transport-streamable-http-client", "transport-streamable-http-client-reqwest" ] path = "tests/test_streamable_http_stale_session.rs" [[test]] name = "test_streamable_http_session_store" required-features = [ "client", "server", "transport-streamable-http-client-reqwest", "transport-streamable-http-server", ] path = "tests/test_streamable_http_session_store.rs" [[test]] name = "test_streamable_http_connection_reuse" required-features = [ "server", "client", "macros", "schemars", "transport-streamable-http-server", "transport-streamable-http-client", "transport-streamable-http-client-reqwest", ] path = "tests/test_streamable_http_connection_reuse.rs"