From c0b6f205c88578ad0feafcf03ad040e21b32abec Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:06:45 -0300 Subject: [PATCH 1/9] tests: add new tests for client runtime --- crates/rust-mcp-sdk/tests/common/common.rs | 24 +++++++++ .../rust-mcp-sdk/tests/test_client_runtime.rs | 52 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 crates/rust-mcp-sdk/tests/common/common.rs create mode 100644 crates/rust-mcp-sdk/tests/test_client_runtime.rs diff --git a/crates/rust-mcp-sdk/tests/common/common.rs b/crates/rust-mcp-sdk/tests/common/common.rs new file mode 100644 index 0000000..7945ca3 --- /dev/null +++ b/crates/rust-mcp-sdk/tests/common/common.rs @@ -0,0 +1,24 @@ +use async_trait::async_trait; +use rust_mcp_schema::{ + ClientCapabilities, Implementation, InitializeRequestParams, JSONRPC_VERSION, +}; +use rust_mcp_sdk::mcp_client::ClientHandler; + +pub const NPX_SERVER_EVERYTHING: &str = "@modelcontextprotocol/server-everything"; +pub const UVX_SERVER_GIT: &str = "mcp-server-git"; + +pub fn test_client_info() -> InitializeRequestParams { + InitializeRequestParams { + capabilities: ClientCapabilities::default(), + client_info: Implementation { + name: "test-rust-mcp-client".into(), + version: "0.1.0".into(), + }, + protocol_version: JSONRPC_VERSION.into(), + } +} + +pub struct TestClientHandler; + +#[async_trait] +impl ClientHandler for TestClientHandler {} diff --git a/crates/rust-mcp-sdk/tests/test_client_runtime.rs b/crates/rust-mcp-sdk/tests/test_client_runtime.rs new file mode 100644 index 0000000..b9c4123 --- /dev/null +++ b/crates/rust-mcp-sdk/tests/test_client_runtime.rs @@ -0,0 +1,52 @@ +use common::{test_client_info, TestClientHandler, NPX_SERVER_EVERYTHING, UVX_SERVER_GIT}; +use rust_mcp_sdk::{mcp_client::client_runtime, McpClient, StdioTransport, TransportOptions}; + +#[path = "common/common.rs"] +pub mod common; + +#[tokio::test] +async fn tets_client_launch_npx_server() { + // NPM based MCP servers should launch successfully using `npx` + let transport = StdioTransport::create_with_server_launch( + "npx", + vec!["-y".into(), NPX_SERVER_EVERYTHING.into()], + None, + TransportOptions::default(), + ) + .unwrap(); + + let client = client_runtime::create_client(test_client_info(), transport, TestClientHandler {}); + + client.clone().start().await.unwrap(); + + let server_capabilities = client.server_capabilities().unwrap(); + let server_info = client.server_info().unwrap(); + + assert!(server_info.server_info.name.len() > 0); + assert!(server_info.server_info.version.len() > 0); + assert!(server_capabilities.tools.is_some()); +} + +#[tokio::test] +async fn tets_client_launch_uvx_server() { + // The Python-based MCP server should launch successfully + // provided that `uvx` is installed and accessible in the system's PATH + let transport = StdioTransport::create_with_server_launch( + "uvx", + vec![UVX_SERVER_GIT.into()], + None, + TransportOptions::default(), + ) + .unwrap(); + + let client = client_runtime::create_client(test_client_info(), transport, TestClientHandler {}); + + client.clone().start().await.unwrap(); + + let server_capabilities = client.server_capabilities().unwrap(); + let server_info = client.server_info().unwrap(); + + assert!(server_info.server_info.name.len() > 0); + assert!(server_info.server_info.version.len() > 0); + assert!(server_capabilities.tools.is_some()); +} From 9d285c18de85fb85a74d1689bd46feebdf673291 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:07:10 -0300 Subject: [PATCH 2/9] test: update workflow to test on both linux and windows --- .github/workflows/ci.yml | 87 +++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 882dd90..c48404b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,24 +3,23 @@ on: push: branches: - main + # pull_request: + # branches: + # - "**" workflow_call: -# on: -# push: -# branches: -# - main -# pull_request: -# branches: -# - "**" -# - jobs: rust_check: - name: Rust check - runs-on: ubuntu-latest + name: Rust Checks (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + fail-fast: false # Continue testing other OSes even if one fails steps: - name: Checkout uses: actions/checkout@v4 + - name: Cache Rust uses: actions/cache@v4 with: @@ -29,42 +28,76 @@ jobs: ~/.cargo/registry ~/.cargo/git target - key: ${{ runner.os }}-rust-${{ steps.toolchain.outputs.cachekey }} - restore-keys: ${{ runner.os }}-rust- + key: ${{ matrix.os }}-rust-${{ hashFiles('Cargo.lock') }} + restore-keys: ${{ matrix.os }}-rust- - name: Install Rust Toolchain uses: dtolnay/rust-toolchain@master with: toolchain: stable - components: rustfmt + components: rustfmt, clippy + + - name: Install cargo-make + uses: davidB/rust-cargo-make@v1 + + - name: Install nextest + uses: taiki-e/install-action@nextest + + # install nodejs that is required for tests + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" # Stable Node.js version + cache: "npm" # Cache npm dependencies + # Verify npx is available + - name: Verify npx + run: npx --version + shell: bash + + # install Python and uvx that is required for tests + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" # Stable Python version + cache: "pip" # Cache pip dependencies + + - name: Install uv + run: pip install uv + shell: bash - - uses: davidB/rust-cargo-make@v1 - - uses: taiki-e/install-action@nextest + - name: Verify uvx + run: uvx --version + shell: bash - name: Run Clippy - run: | - cargo make clippy + run: cargo make clippy + continue-on-error: false + if: matrix.os == 'ubuntu-latest' # Run Clippy only on Linux to save time - name: Run Rustfmt - run: | - cargo make fmt + run: cargo make fmt -- --check + if: matrix.os == 'ubuntu-latest' # Run fmt only on Linux - name: Run cargo doc + env: + RUSTDOCFLAGS: "-Dwarnings" run: cargo doc --no-deps + if: matrix.os == 'ubuntu-latest' # Run doc only on Linux - name: Spell Check - env: - RUSTDOCFLAGS: "-Dwarnings" uses: crate-ci/typos@master + if: matrix.os == 'ubuntu-latest' # Run typos only on Linux - - name: Audit + - name: Audit Dependencies uses: actions-rust-lang/audit@v1 with: token: ${{ secrets.GITHUB_TOKEN }} + if: matrix.os == 'ubuntu-latest' # Run audit only on Linux - name: Run Tests - run: | - cargo make test + run: cargo make test + shell: bash # Ensure consistent shell + - name: Run Doc Tests - run: | - cargo make doc-test + run: cargo make doc-test + shell: bash # Ensure consistent shell From 37771fe8e8e735998ba59918801869074a250339 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:20:20 -0300 Subject: [PATCH 3/9] chore: disable node cache --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c48404b..87548fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" # Stable Node.js version - cache: "npm" # Cache npm dependencies # Verify npx is available - name: Verify npx run: npx --version From 3ea9d2b3427a66242a2f608f4fba17bea7d785d8 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:21:40 -0300 Subject: [PATCH 4/9] chore: disable python cache --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87548fb..6296214 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.11" # Stable Python version - cache: "pip" # Cache pip dependencies - name: Install uv run: pip install uv From 21742ae7d03432723d01dd521885f9ab3028beef Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:29:31 -0300 Subject: [PATCH 5/9] chore: update ci workflow --- .github/workflows/ci.yml | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6296214..d7d9a0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,30 +43,6 @@ jobs: - name: Install nextest uses: taiki-e/install-action@nextest - # install nodejs that is required for tests - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" # Stable Node.js version - # Verify npx is available - - name: Verify npx - run: npx --version - shell: bash - - # install Python and uvx that is required for tests - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" # Stable Python version - - - name: Install uv - run: pip install uv - shell: bash - - - name: Verify uvx - run: uvx --version - shell: bash - - name: Run Clippy run: cargo make clippy continue-on-error: false @@ -92,6 +68,30 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} if: matrix.os == 'ubuntu-latest' # Run audit only on Linux + # install nodejs that is required for tests + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" # Stable Node.js version + # Verify npx is available + - name: Verify npx + run: npx --version + shell: bash + + # install Python and uvx that is required for tests + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" # Stable Python version + + - name: Install uv + run: pip install uv + shell: bash + + - name: Verify uvx + run: uvx --version + shell: bash + - name: Run Tests run: cargo make test shell: bash # Ensure consistent shell From 0f6a6bbbab9f3f268e248fd68e172db7969a1ad5 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:40:25 -0300 Subject: [PATCH 6/9] chore: disable unnecessary test on windows --- crates/rust-mcp-sdk/tests/test_client_runtime.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rust-mcp-sdk/tests/test_client_runtime.rs b/crates/rust-mcp-sdk/tests/test_client_runtime.rs index b9c4123..837d25e 100644 --- a/crates/rust-mcp-sdk/tests/test_client_runtime.rs +++ b/crates/rust-mcp-sdk/tests/test_client_runtime.rs @@ -27,6 +27,7 @@ async fn tets_client_launch_npx_server() { assert!(server_capabilities.tools.is_some()); } +#[cfg(unix)] #[tokio::test] async fn tets_client_launch_uvx_server() { // The Python-based MCP server should launch successfully From 66446f44016fb03c57e7371f084831141a85b68c Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:46:40 -0300 Subject: [PATCH 7/9] chore: update ci workflow --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7d9a0b..354932d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,6 +78,10 @@ jobs: run: npx --version shell: bash + - name: Install server-everything globally + run: npm install -g @modelcontextprotocol/server-everything + shell: bash + # install Python and uvx that is required for tests - name: Setup Python uses: actions/setup-python@v5 From da7830460a4a0fb585d3c8d4c2fee9a1033f7095 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:51:18 -0300 Subject: [PATCH 8/9] chore: run clippy on both windows and linux --- .github/workflows/ci.yml | 1 - crates/rust-mcp-sdk/tests/common/common.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 354932d..e24ad6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,6 @@ jobs: - name: Run Clippy run: cargo make clippy continue-on-error: false - if: matrix.os == 'ubuntu-latest' # Run Clippy only on Linux to save time - name: Run Rustfmt run: cargo make fmt -- --check diff --git a/crates/rust-mcp-sdk/tests/common/common.rs b/crates/rust-mcp-sdk/tests/common/common.rs index 7945ca3..d896a56 100644 --- a/crates/rust-mcp-sdk/tests/common/common.rs +++ b/crates/rust-mcp-sdk/tests/common/common.rs @@ -5,6 +5,8 @@ use rust_mcp_schema::{ use rust_mcp_sdk::mcp_client::ClientHandler; pub const NPX_SERVER_EVERYTHING: &str = "@modelcontextprotocol/server-everything"; + +#[cfg(unix)] pub const UVX_SERVER_GIT: &str = "mcp-server-git"; pub fn test_client_info() -> InitializeRequestParams { From 01f1228ba4cb6087335b46a8b588efd5e1bd66c8 Mon Sep 17 00:00:00 2001 From: Ali Hashemi Date: Fri, 9 May 2025 18:59:15 -0300 Subject: [PATCH 9/9] chore: fix build issue --- crates/rust-mcp-sdk/tests/test_client_runtime.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/rust-mcp-sdk/tests/test_client_runtime.rs b/crates/rust-mcp-sdk/tests/test_client_runtime.rs index 837d25e..dfe40bf 100644 --- a/crates/rust-mcp-sdk/tests/test_client_runtime.rs +++ b/crates/rust-mcp-sdk/tests/test_client_runtime.rs @@ -1,6 +1,9 @@ -use common::{test_client_info, TestClientHandler, NPX_SERVER_EVERYTHING, UVX_SERVER_GIT}; +use common::{test_client_info, TestClientHandler, NPX_SERVER_EVERYTHING}; use rust_mcp_sdk::{mcp_client::client_runtime, McpClient, StdioTransport, TransportOptions}; +#[cfg(unix)] +use common::UVX_SERVER_GIT; + #[path = "common/common.rs"] pub mod common;