adk-mcp-sdk 0.2.0

Enterprise SDK traits for ADK-Rust MCP servers — health checks, tool metadata, risk classes, credential binding, and registry compatibility
Documentation

ADK MCP SDK

Crates.io Docs.rs License ADK-Rust Enterprise

The shared contract between MCP servers and the ADK-Rust Enterprise registry. Every server in the ecosystem implements these traits to enable automatic onboarding, health monitoring, tool governance, and risk classification.

Architecture

What This Crate Provides

Export Type Purpose
ServerManifest Struct TOML-loadable server identity, capabilities, and tool declarations
ServerManifest::validate() Method Validates manifest fields, returns list of errors
HealthCheck Trait Async health probe for registry monitoring
HealthStatus Struct Health response with status, message, and latency
ToolMeta Struct Per-tool metadata with risk class and credential bindings
RiskClass Enum Tool-level risk classification (8 levels)
mcp_2026_server! Macro Stateless identity, Tasks, sealed MRTR approvals, and cache hints
RiskLevel Enum Server-level risk designation (4 levels)
Transport Enum Supported transport protocols (stdio, SSE, HTTP)
WritesAllowed Enum Write permission level (none, gated, approved)
ManifestError Error Typed errors for manifest loading

Installation

[dependencies]
adk-mcp-sdk = "0.2"

Quick Start

1. Implement HealthCheck

use adk_mcp_sdk::{HealthCheck, HealthStatus};

#[derive(Clone)]
struct MyServer;

#[async_trait::async_trait]
impl HealthCheck for MyServer {
    async fn check_health(&self) -> HealthStatus {
        // Check your backend connectivity, auth, schema, etc.
        HealthStatus {
            healthy: true,
            message: Some("All systems operational".into()),
            latency_ms: Some(5),
        }
    }
}

2. Create mcp-server.toml

server_id = "mcp_my_server"
display_name = "My MCP Server"
version = "0.2.0"
domain = "platform"
sdk_version = "0.2.0"
risk_level = "medium"
writes_allowed = "gated"
transports = ["stdio"]
credentials = ["vault://my-api-key"]
governance_gates = []
environments = ["development", "staging", "production"]

[[tools]]
name = "list_items"
description = "List items with optional filters"
risk_class = "read_only"
requires_approval = false
credential_bindings = []

[[tools]]
name = "create_item"
description = "Create a new item (gated write)"
risk_class = "internal_write"
requires_approval = true
credential_bindings = ["vault://my-api-key"]

3. Load and Validate Manifest

use adk_mcp_sdk::ServerManifest;
use std::path::Path;

// Load and validate on startup
let manifest = ServerManifest::from_file(Path::new("mcp-server.toml"))?;
let errors = manifest.validate();
if !errors.is_empty() {
    for e in &errors {
        eprintln!("manifest error: {e}");
    }
    std::process::exit(1);
}

// From string
let manifest = ServerManifest::from_toml(include_str!("../mcp-server.toml"))?;

// Programmatic
let manifest = ServerManifest {
    server_id: "mcp_my_server".into(),
    display_name: "My MCP Server".into(),
    version: env!("CARGO_PKG_VERSION").into(),
    domain: "platform".into(),
    transports: vec![adk_mcp_sdk::manifest::Transport::Stdio],
    risk_level: adk_mcp_sdk::risk::RiskLevel::Medium,
    writes_allowed: adk_mcp_sdk::manifest::WritesAllowed::Gated,
    sdk_version: "0.2.0".into(),
    tools: vec![],
    credentials: vec![],
    governance_gates: vec![],
    environments: vec!["development".into(), "production".into()],
};

4. Declare Tool Metadata

use adk_mcp_sdk::{RiskClass, ToolMeta};

let tools = vec![
    ToolMeta {
        name: "search_items".into(),
        description: "Search items by query".into(),
        risk_class: RiskClass::ReadOnly,
        requires_approval: false,
        credential_bindings: vec![],
    },
    ToolMeta {
        name: "delete_item".into(),
        description: "Delete an item permanently".into(),
        risk_class: RiskClass::ExternalWrite,
        requires_approval: true,
        credential_bindings: vec!["vault://admin-key".into()],
    },
];

Risk Classes

The governance engine uses risk classes to determine approval requirements, audit depth, and environment restrictions.

Class Enum Variant Examples Default Policy
Read-only ReadOnly search, get, list, inspect Allowed if scoped
Generated draft GeneratedWriteDraft create draft, proposal Allowed in staging
Internal write InternalWrite add note, update ticket, assign Gated by owner policy
External write ExternalWrite send email, post Slack, create PR Approval required
Financial FinancialAction capture payment, refund, payout Intent + approval
Identity/Security IdentitySecurityAction reset password, revoke access Identity verification + approver
Production deploy ProductionDeployment promote, deploy, rollback Release governance required
File/Code write FileCodeWrite write file, create branch Workspace trust + repo policy

Risk Levels (Server-Level)

Level When to Use Registry Behavior
Low Read-only servers, search, analytics Auto-approved onboarding
Medium Servers with gated writes Standard review
High Servers with external writes or sensitive data Security review required
Critical Credential vaults, identity, financial Full governance audit

Server Manifest Reference

Field Type Required Description
server_id String ✅ Unique identifier (snake_case)
display_name String ✅ Human-readable name
version String ✅ SemVer version
domain String ✅ Domain category (platform, security, devops, etc.)
sdk_version String ✅ Minimum SDK version
risk_level Enum ✅ low, medium, high, critical
writes_allowed Enum ✅ none, gated, approved
transports Array ✅ stdio, sse, streamable_http
credentials Array ❌ Vault credential URIs needed
governance_gates Array ❌ Required governance checks
environments Array ❌ Target deployment environments
tools Array ❌ Tool declarations (see ToolMeta)

Complete Example: Building an MCP Server

use adk_mcp_sdk::{HealthCheck, HealthStatus};
use rmcp::{handler::server::wrapper::Parameters, schemars, tool, tool_router, ServiceExt, transport::stdio};

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct SearchInput {
    pub query: String,
    #[serde(default = "default_limit")]
    pub limit: u32,
}
fn default_limit() -> u32 { 20 }

#[derive(Clone)]
pub struct MyServer;

#[tool_router]
impl MyServer {
    #[tool(description = "Search items by query")]
    async fn search(&self, Parameters(input): Parameters<SearchInput>) -> String {
        format!("Found results for '{}' (limit {})", input.query, input.limit)
    }
}

adk_mcp_sdk::mcp_2026_server! {
    server: MyServer,
    task_tools: ["search"],
    approval_tools: [],
    cache_ttl_ms: 60_000,
}

#[async_trait::async_trait]
impl HealthCheck for MyServer {
    async fn check_health(&self) -> HealthStatus {
        HealthStatus { healthy: true, message: None, latency_ms: Some(1) }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt().with_env_filter("info").init();
    let service = MyServer.serve(stdio()).await?;
    service.waiting().await?;
    Ok(())
}

MCP 2026-07-28 runtime contract

SDK 0.2 provides a shared handler for the new stateless protocol while retaining legacy initialization for MCP 2025-11-25 clients:

  • Per-request protocol, client identity, and capability metadata are read from _meta by rmcp. Protected calls require a non-empty client identity.
  • Selected operations are returned as SEP-2663 Tasks when the client advertises Tasks. Clients can get, update, and cancel those tasks.
  • Manifest-gated tools use SEP-2322 MRTR elicitation. The approval state is HMAC-protected, bound to the caller, tool, and arguments, and expires after two minutes. Legacy clients fail closed for protected tools.
  • Tool lists carry SEP-2549 ttlMs and public cache scope. rmcp removes these fields automatically for legacy responses.
  • Ordinary legacy tool calls continue to work after the initialize handshake.

Set MCP_REQUEST_STATE_KEY to at least 32 high-entropy bytes on every instance that can receive a retry. All instances in a deployment must share the same key so an MRTR flow can resume on any replica. Task storage is process-local in this release; route task follow-ups to the creating instance or replace the manager with a durable store before scale-to-zero deployment.

The minimum supported Rust version is 1.94.1. CI should test both MCP 2025-11-25 and 2026-07-28 behavior, including an ordinary legacy call, task lifecycle, approval rejection/tamper handling, and cache-hint serialization.

Servers Using This SDK

Server Version Domain Description
mcp-credentials-vault 1.1.0 security Scoped credential access, 5 vault backends
mcp-artifact-store 1.1.0 platform Governed artifact registry with provenance
mcp-session-memory 1.1.0 platform Session and memory persistence
mcp-a2a 1.2.0 agents A2A remote agent protocol
mcp-acp-workspace 1.2.0 agents ACP workspace control plane
mcp-governance-policy 1.1.0 governance Policy evaluation and approvals
mcp-environment 1.2.0 platform Environment registry and deployments
mcp-registry 1.1.0 platform MCP server registration and discovery
mcp-identity 1.1.0 security Identity, access, and entitlements
mcp-device-management 1.5.0 endpoint-security Device posture and remediation
adk-mcp-github 1.3.0 developer-tools GitHub repos, PRs, issues, workflows
mcp-cicd 1.1.0 devops CI/CD pipelines and deployments
mcp-code-search 1.1.0 developer-tools Semantic code search and call graphs
mcp-itsm 1.1.0 operations Tickets, incidents, change requests
mcp-knowledge-base 1.2.0 operations Articles, search, feedback loops
mcp-security-advisory 1.1.0 security CVE/GHSA/OSV advisory search and audit
mcp-package-registry 1.1.0 developer-tools Dependency metadata and upgrade plans
mcp-test-runner 1.1.0 developer-tools Test execution and coverage

Creating a New Server

# Clone the template
git clone https://github.com/zavora-ai/mcp-server-template my-server
cd my-server

# Edit Cargo.toml — rename package, update description
# Edit mcp-server.toml — set server_id, tools, risk level
# Edit src/main.rs — implement your tools

# Build and test
cargo build
cargo test

# Publish
cargo publish

The template includes a working #[tool_router(server_handler)] example with HealthCheck, tracing, and stdio transport.

Integration with rmcp

This SDK provides metadata and governance — it does not replace rmcp which provides the MCP protocol transport. A typical server uses both:

[dependencies]
adk-mcp-sdk = "0.2"                    # Registry and MCP 2026 runtime contract
rmcp = { version = "1.7", features = ["server", "transport-io", "macros"] }  # MCP protocol
  • rmcp handles: tool routing, JSON-RPC, stdio/HTTP transport, schema generation
  • adk-mcp-sdk handles: health monitoring, manifest declaration, risk classification, credential binding

Documentation

Document Description
Rust Docs Generated API documentation
mcp-server.example.toml Annotated manifest example
CHANGELOG.md Version history
LICENSE Apache-2.0 license

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/my-feature)
  3. Implement with tests
  4. Submit a pull request

Contributors

James Karanja Maina

License

Apache-2.0 — see LICENSE for details.


Part of the ADK-Rust Enterprise MCP server ecosystem.

Built with ❤️ by Zavora AI