diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0eef42..762d89d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,21 @@ jobs: key: msrv - run: cargo build --all-targets --all-features + no-default-features: + name: build (no-default-features) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + key: no-default-features + # Verifies the runtime-agnostic surface (McpTransport, LoopbackTransport, + # McpTool, cache_tools, replay, result_cache) still compiles without + # tokio and the stdio transport. + - run: cargo build --no-default-features + - run: cargo clippy --no-default-features -- -D warnings + doc: name: rustdoc runs-on: ubuntu-latest diff --git a/AGENTS.md b/AGENTS.md index 127bb74..466eae4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,12 +11,23 @@ SDK. Surfaces: - `McpTransport` — trait abstraction over MCP client transports. - `LoopbackTransport` — in-process round-trip for tests. - `StdioTransport::spawn` / `serve_stdio()` — newline-framed JSON-RPC over - child-process stdio. + child-process stdio. Gated behind the default-on `stdio` Cargo feature. - `McpTool` — adapts a transport into a `rig_compose::Tool`. +- `CachedResultsTransport` + `CachedResultsConfig` and the `cache.page` / + `cache.release` tool builders (`register_cache_tools`) for opt-in + model-boundary paging of oversized array results. +- `RegistrationSnapshot` + `RegistrationReplayPolicy` for adapter-local + replay of discovered MCP tool registrations after reconnects. +- `ResultCache` + `MemoryResultCache` + `CachedResultEnvelope` + + `CachedResultHandle` + `cache_if_large` — transport-neutral cache primitives + shared by the cache tools. ## Rules -- Rust 2024, MSRV 1.88. +- Rust 2024, MSRV 1.88. Library is runtime-agnostic when built with + `--no-default-features`; the `stdio` feature is what pulls `tokio` and the + matching `rmcp` transport features. Do not add unconditional `tokio` to + `[dependencies]`. - Errors: surface `KernelError` from `rig-compose`; do not invent String error variants. - Never `.await` while holding a lock guard. @@ -31,12 +42,18 @@ SDK. Surfaces: ```sh just check -# fmt + clippy --all-features + test --all-features + rustdoc strict +# fmt + clippy --all-features + clippy --no-default-features +# + test --all-features + rustdoc strict ``` +CI additionally builds `--no-default-features` to keep the runtime-agnostic +surface honest. + ## Scope -Do not vendor `rmcp`. Keep the `rmcp` feature surface tight (currently -`client`, `server`, `macros`, `transport-io`, `transport-child-process`). +Do not vendor `rmcp`. Keep the `rmcp` feature surface tight: the base set is +`client`, `server`, `macros`; the `stdio` feature additionally enables +`transport-io` and `transport-child-process`. New transports should follow the +same opt-in feature pattern rather than expanding the default surface. Update [README.md](README.md) and [CHANGELOG.md](CHANGELOG.md) for user-visible changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 85143d5..256622b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,10 +25,6 @@ from [Conventional Commits](https://www.conventionalcommits.org/). ### Added -- Add cached result transport tools - -### Added - - Add `CachedResultsTransport`, `CachedResultsConfig`, and cache page/release tools for opt-in model-boundary caching of oversized MCP array results. @@ -47,10 +43,6 @@ from [Conventional Commits](https://www.conventionalcommits.org/). ### Added -- Add cached result metadata and replay snapshots - -### Added - - Extend `CachedResultEnvelope` with `truncated`, `omitted_items`, and `page_token` metadata so MCP cached array previews align with `rig-compose` result-envelope semantics while preserving page handles. diff --git a/Cargo.toml b/Cargo.toml index 397093d..d1521ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,28 +11,39 @@ readme = "README.md" keywords = ["rig", "mcp", "rmcp", "agent", "ai"] categories = ["asynchronous"] +[features] +default = ["stdio"] +# Enables the production child-process stdio transport (`StdioTransport`, +# `serve_stdio`). Pulls `tokio` and the matching `rmcp` transport features. +# Turn this off to use `rig-mcp` purely through `McpTransport` / +# `LoopbackTransport` / `McpTool` without a hard tokio dependency. +stdio = ["dep:tokio", "rmcp/transport-io", "rmcp/transport-child-process"] + [dependencies] rig-compose = "0.4.1" async-trait = "0.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.40", features = ["rt-multi-thread", "macros", "sync", "process", "io-util", "io-std", "time"] } +tokio = { version = "1.40", features = ["rt-multi-thread", "macros", "sync", "process", "io-util", "io-std", "time"], optional = true } tracing = "0.1" # Official Model Context Protocol SDK. We disable defaults and opt into -# only the client + server + stdio transports we actually use; this -# keeps the dependency surface tight (no HTTP/TLS pulled in). +# only the client + server + macros base; stdio transports are pulled in +# additively via the `stdio` feature so the no-default-features build stays +# tokio-free. rmcp = { version = "1.6", default-features = false, features = [ "client", "server", "macros", - "transport-io", - "transport-child-process", ] } [dev-dependencies] serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.40", features = ["rt-multi-thread", "macros", "sync", "process", "io-util", "io-std", "time"] } +[[bin]] +name = "rig_mcp_stdio_fixture" +required-features = ["stdio"] + [lints.clippy] dbg_macro = "forbid" await_holding_lock = "deny" diff --git a/README.md b/README.md index 748150d..a58b6a0 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,13 @@ It delegates JSON-RPC framing, capability handshakes, and protocol-version negot ## Status -- Crate version: `0.2.1`. +- Crate version: `0.2.3`. - Rust edition: 2024. - MSRV: 1.88. - `rig-compose` dependency: `version = "0.4.1"`. -- `rmcp` dependency: `1.6` with `client`, `server`, `macros`, `transport-io`, and `transport-child-process` features only. -- Current Unreleased work adds opt-in cached-result transport and page/release - tools for oversized MCP array results plus structured `tracing` spans for - MCP spawn/list/call/server lifecycle events. +- `rmcp` dependency: `1.6` with `client`, `server`, and `macros` as the base + surface; the `stdio` feature additionally enables `transport-io` and + `transport-child-process`. The crate-local maturity plan lives in [ROADMAP.md](ROADMAP.md). Cross-crate coordination lives in @@ -37,7 +36,19 @@ coordination lives in ## Feature Flags -`rig-mcp` currently defines no crate features. `just check` runs clippy, tests, and docs with `--all-features` to keep future feature additions covered. +`rig-mcp` exposes one Cargo feature, on by default: + +| Feature | Default | Description | +| --- | :-: | --- | +| `stdio` | yes | Production child-process stdio transport (`StdioTransport::spawn`, `serve_stdio`) backed by `rmcp`'s `transport-io` and `transport-child-process` features. Pulls `tokio`. | + +The runtime-agnostic surface — `McpTransport`, `LoopbackTransport`, `McpTool`, +`CachedResultsTransport`, `RegistrationSnapshot`, and the `result_cache` +primitives — stays available with `default-features = false`, so callers that +embed `rig-mcp` without the stdio bridge do not pay for `tokio` directly. + +CI exercises both `--all-features` and `--no-default-features` to keep the +runtime-agnostic guarantee honest. ## Key Types diff --git a/justfile b/justfile index 8889c0a..d552187 100644 --- a/justfile +++ b/justfile @@ -23,6 +23,7 @@ fmt: # Clippy across release-relevant feature sets. clippy: cargo clippy --all-targets --all-features -- -D warnings + cargo clippy --no-default-features -- -D warnings # Tests across release-relevant feature sets. test: diff --git a/src/lib.rs b/src/lib.rs index 2627408..57c61ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ pub mod cache_tools; pub mod replay; pub mod result_cache; +#[cfg(feature = "stdio")] pub mod stdio; pub mod transport; @@ -35,5 +36,6 @@ pub use replay::{RegistrationReplayPolicy, RegistrationSnapshot}; pub use result_cache::{ CachedResultEnvelope, CachedResultHandle, MemoryResultCache, ResultCache, cache_if_large, }; +#[cfg(feature = "stdio")] pub use stdio::{StdioTransport, serve_stdio}; pub use transport::{LoopbackTransport, McpTool, McpTransport};