Rust SDK Overview
--- title: "Rust SDK Overview" description: "An overview of the ContextVM Rust SDK architecture and components." --- The Rust SDK implements ContextVM: MCP over Nostr. In practice, it lets you transport MCP JSON-RPC messages through Nostr events, add server discovery through announcement events, and optionally encrypt direct traffic with NIP-44 plus gift wrapping. ## The main mental model For native Rust applications, ContextVM is primarily a transport for `rmcp`. That means the usual shape is: 1. define an `rmcp` server or client 2. create a ContextVM Nostr transport 3. attach the transport with `ServiceExt` This is the same pattern shown by the `rmcp` server and client examples. The only difference is that this SDK replaces stdio, HTTP, or raw sockets with Nostr transports. ## Choose the right API Most users should start with one of these entry points: | Use case | Start with | | ---------------------------------------------------------- | ----------------------------------------------------------------------------- | | Build a native ContextVM server | `NostrServerTransport` + `rmcp` `ServiceExt` | | Build a native ContextVM client | `NostrClientTransport` + `rmcp` `ServiceExt` | | Expose an already-existing MCP server on Nostr | `NostrMCPGateway` | | Connect to a remote ContextVM server with a simpler bridge | `NostrMCPProxy` | | Discover public servers and capabilities | `discover_servers()` and related helpers | | Work directly with the optional bridge layer | `NostrMCPGateway::serve_handler()` or `NostrMCPProxy::serve_client_handler()` | ## Architecture The crate is organized in layers: - `core`: protocol types, validation, serialization, errors - `relay`: relay pool abstraction - `signer`: key generation and signer helpers - `encryption`: NIP-44 and gift-wrap helpers - `transport`: native ContextVM client and server transports - `gateway`: wrapper for exposing an existing MCP server flow on Nostr - `proxy`: wrapper for connecting to a remote server without the full `rmcp` client model - `discovery`: announcement and capability discovery The application-facing `rmcp` layer provides the `ServiceExt` integration point together with the usual server and client startup flow. ## Protocol model ContextVM keeps MCP semantics intact and uses Nostr only as the transport envelope. - MCP payloads are represented by `JsonRpcMessage` - direct plaintext ContextVM traffic uses kind `25910` - encrypted traffic uses gift-wrap kinds `1059` or `21059` - public discovery uses kinds `11316` through `11320` - routing is done with `p` tags and request/response correlation with `e` tags, as reflected in the repository root README ## Core types you should know - `EncryptionMode`: `Optional`, `Required`, `Disabled` - `GiftWrapMode`: `Optional`, `Ephemeral`, `Persistent` - `contextvm_sdk::ServerInfo`: announcement metadata - `CapabilityExclusion`: allowlist bypass rules for specific methods or capabilities ## Typical workflows ### Build a native server 1. generate keys with `signer::generate()` or load an existing private key with `from_sk()` 2. configure `NostrServerTransportConfig` 3. create `NostrServerTransport` 4. attach it to an `rmcp` server with `ServiceExt` 5. optionally publish announcements with `announce()` ### Build a native client 1. generate keys with `signer::generate()` or load an existing private key with `from_sk()` 2. configure `NostrClientTransportConfig` 3. create `NostrClientTransport` 4. attach it to an `rmcp` client with `ServiceExt` ### Bridge an existing server or client If you are not building a native `rmcp` service directly, use the wrapper layer: - `NostrMCPGateway` for server-side bridging - `NostrMCPProxy` for client-side bridging ### Discover servers 1. create a `RelayPool` 2. query `discover_servers()` 3. fetch public tools, resources, and prompts with the discovery helpers ## What is important in this implementation The Rust SDK already implements behavior that users should rely on: - stateless client initialization behavior - announcement publication and deletion - encryption negotiation and response mirroring - rmcp conversion and routing flow Use the task-oriented pages in this directory for those details. Start with the native server and native client guides if you are building ContextVM applications directly. --- _This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/overview.md)._The Rust SDK implements ContextVM: MCP over Nostr.
In practice, it lets you transport MCP JSON-RPC messages through Nostr events, add server discovery through announcement events, and optionally encrypt direct traffic with NIP-44 plus gift wrapping.
The main mental model
Section titled “The main mental model”For native Rust applications, ContextVM is primarily a transport for rmcp.
That means the usual shape is:
- define an
rmcpserver or client - create a ContextVM Nostr transport
- attach the transport with
ServiceExt
This is the same pattern shown by the rmcp server and client examples. The only difference is that this SDK replaces stdio, HTTP, or raw sockets with Nostr transports.
Choose the right API
Section titled “Choose the right API”Most users should start with one of these entry points:
| Use case | Start with |
|---|---|
| Build a native ContextVM server | NostrServerTransport + rmcp ServiceExt |
| Build a native ContextVM client | NostrClientTransport + rmcp ServiceExt |
| Expose an already-existing MCP server on Nostr | NostrMCPGateway |
| Connect to a remote ContextVM server with a simpler bridge | NostrMCPProxy |
| Discover public servers and capabilities | discover_servers() and related helpers |
| Work directly with the optional bridge layer | NostrMCPGateway::serve_handler() or NostrMCPProxy::serve_client_handler() |
Architecture
Section titled “Architecture”The crate is organized in layers:
core: protocol types, validation, serialization, errorsrelay: relay pool abstractionsigner: key generation and signer helpersencryption: NIP-44 and gift-wrap helperstransport: native ContextVM client and server transportsgateway: wrapper for exposing an existing MCP server flow on Nostrproxy: wrapper for connecting to a remote server without the fullrmcpclient modeldiscovery: announcement and capability discovery
The application-facing rmcp layer provides the ServiceExt integration point together with the usual server and client startup flow.
Protocol model
Section titled “Protocol model”ContextVM keeps MCP semantics intact and uses Nostr only as the transport envelope.
- MCP payloads are represented by
JsonRpcMessage - direct plaintext ContextVM traffic uses kind
25910 - encrypted traffic uses gift-wrap kinds
1059or21059 - public discovery uses kinds
11316through11320 - routing is done with
ptags and request/response correlation withetags, as reflected in the repository root README
Core types you should know
Section titled “Core types you should know”EncryptionMode:Optional,Required,DisabledGiftWrapMode:Optional,Ephemeral,Persistentcontextvm_sdk::ServerInfo: announcement metadataCapabilityExclusion: allowlist bypass rules for specific methods or capabilities
Typical workflows
Section titled “Typical workflows”Build a native server
Section titled “Build a native server”- generate keys with
signer::generate()or load an existing private key withfrom_sk() - configure
NostrServerTransportConfig - create
NostrServerTransport - attach it to an
rmcpserver withServiceExt - optionally publish announcements with
announce()
Build a native client
Section titled “Build a native client”- generate keys with
signer::generate()or load an existing private key withfrom_sk() - configure
NostrClientTransportConfig - create
NostrClientTransport - attach it to an
rmcpclient withServiceExt
Bridge an existing server or client
Section titled “Bridge an existing server or client”If you are not building a native rmcp service directly, use the wrapper layer:
NostrMCPGatewayfor server-side bridgingNostrMCPProxyfor client-side bridging
Discover servers
Section titled “Discover servers”- create a
RelayPool - query
discover_servers() - fetch public tools, resources, and prompts with the discovery helpers
What is important in this implementation
Section titled “What is important in this implementation”The Rust SDK already implements behavior that users should rely on:
- stateless client initialization behavior
- announcement publication and deletion
- encryption negotiation and response mirroring
- rmcp conversion and routing flow
Use the task-oriented pages in this directory for those details. Start with the native server and native client guides if you are building ContextVM applications directly.
This page was ported from the ContextVM Rust SDK repository.