Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/core/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub const UNENCRYPTED_KINDS: &[u16] = &[
PROMPTS_LIST_KIND,
];

/// Return the latest MCP protocol version string
#[cfg(feature = "rmcp")]
pub fn mcp_protocol_version() -> &'static str {
use std::sync::OnceLock;
Expand All @@ -115,6 +116,7 @@ pub fn mcp_protocol_version() -> &'static str {
.as_str()
}

/// Return the latest MCP protocol version string
#[cfg(not(feature = "rmcp"))]
pub const fn mcp_protocol_version() -> &'static str {
"2025-11-25"
Expand Down
9 changes: 4 additions & 5 deletions src/core/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ pub enum EncryptionMode {
Disabled,
}

// Gift-wrap mode (CEP-19)

// Gift-wrap policy for encrypted transport communication (CEP-19).
// Controls whether encrypted messages use persistent gift wraps (kind `1059`),
// ephemeral gift wraps (kind `21059`), or adapt based on peer support.
/// Gift-wrap policy for encrypted transport communication (CEP-19)
///
/// Controls whether encrypted messages use persistent gift wraps (kind `1059`),
/// ephemeral gift wraps (kind `21059`), or adapt based on peer support.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum GiftWrapMode {
Expand Down
6 changes: 2 additions & 4 deletions src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ where
.map_err(|e| Error::Decryption(e.to_string()))
}

// Decrypt a single-layer NIP-44 gift wrap (kind 1059).

/// Decrypt a single-layer NIP-44 gift wrap (kind 1059)
pub async fn decrypt_gift_wrap_single_layer<T>(signer: &T, event: &Event) -> Result<String>
where
T: NostrSigner,
Expand All @@ -47,8 +46,7 @@ where
decrypt_nip44(signer, &sender_pubkey, &event.content).await
}

// Create a single-layer NIP-44 gift wrap (kind 1059).

/// Create a single-layer NIP-44 gift wrap (kind 1059)
pub async fn gift_wrap_single_layer<T>(
_signer: &T,
recipient: &PublicKey,
Expand Down
23 changes: 22 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![warn(missing_docs)]
//! # ContextVM SDK for Rust
//!
//! A complete Rust implementation of the [ContextVM protocol](https://contextvm.org),
Expand Down Expand Up @@ -36,36 +37,56 @@
//! use contextvm_sdk::signer;
//! ```

/// Core types, constants, serializers, and validation
pub mod core;
/// Server and capability discovery on the Nostr network
pub mod discovery;
/// NIP-44 encryption and NIP-59 gift wrapping
pub mod encryption;
/// Gateway bridging a local MCP server to Nostr
pub mod gateway;
/// Proxy connecting to a remote MCP server via Nostr
pub mod proxy;
/// Nostr relay pool management
pub mod relay;
/// Nostr signer utilities and key management
pub mod signer;
/// Client and server MCP-over-Nostr transports
pub mod transport;

/// rmcp Worker integration for ContextVM transports
#[cfg(feature = "rmcp")]
pub mod rmcp_transport;
// Re-export commonly used types
// ── Core types and error handling ────────────────────────────────────
pub use core::error::{Error, Result};
pub use core::types::{
CapabilityExclusion, ClientSession, EncryptionMode, GiftWrapMode, JsonRpcError,
JsonRpcErrorResponse, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse,
ServerInfo,
};

// ── Discovery ────────────────────────────────────────────────────────
pub use discovery::ServerAnnouncement;

// ── Relay pool ───────────────────────────────────────────────────────
#[cfg(any(test, feature = "test-utils"))]
pub use relay::mock::MockRelayPool;
pub use relay::{RelayPool, RelayPoolTrait};

// ── Transport (client) ──────────────────────────────────────────────
pub use transport::client::{
ClientCorrelationStore, NostrClientTransport, NostrClientTransportConfig,
};

// ── Transport (discovery tags) ──────────────────────────────────────
pub use transport::discovery_tags::{DiscoveredPeerCapabilities, PeerCapabilities};

// ── Transport (server) ──────────────────────────────────────────────
pub use transport::server::{
IncomingRequest, NostrServerTransport, NostrServerTransportConfig, RouteEntry,
ServerEventRouteStore, SessionSnapshot, SessionStore,
};

// ── rmcp re-export ──────────────────────────────────────────────────
#[cfg(feature = "rmcp")]
pub use rmcp;
3 changes: 3 additions & 0 deletions src/transport/client/correlation_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl Default for ClientCorrelationStore {
}

impl ClientCorrelationStore {
/// Create a new store with the default capacity
pub fn new() -> Self {
Self::with_max_pending(DEFAULT_LRU_SIZE)
}
Expand Down Expand Up @@ -76,6 +77,7 @@ impl ClientCorrelationStore {
.is_some_and(|r| r.is_initialize)
}

/// Check whether a pending request exists for the given event ID
pub async fn contains(&self, event_id: &str) -> bool {
self.pending_requests.read().await.contains(event_id)
}
Expand Down Expand Up @@ -118,6 +120,7 @@ impl ClientCorrelationStore {
count
}

/// Remove all pending requests from the store
pub async fn clear(&self) {
self.pending_requests.write().await.clear();
}
Expand Down
2 changes: 2 additions & 0 deletions src/transport/server/correlation_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl Default for ServerEventRouteStore {
}

impl ServerEventRouteStore {
/// Create a new store with the default capacity
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(Inner::new(DEFAULT_LRU_SIZE))),
Expand Down Expand Up @@ -246,6 +247,7 @@ impl ServerEventRouteStore {
expired_keys
}

/// Remove all route entries and secondary indexes
pub async fn clear(&self) {
let mut inner = self.inner.write().await;
inner.routes.clear();
Expand Down
4 changes: 4 additions & 0 deletions src/transport/server/session_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,13 @@ impl SessionStore {
/// through the async API boundary).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SessionSnapshot {
/// Whether the MCP `initialize` handshake has completed
pub is_initialized: bool,
/// Whether the session is using NIP-44 encrypted transport
pub is_encrypted: bool,
/// Whether common discovery tags have been sent for this session
pub has_sent_common_tags: bool,
/// Whether the peer advertised support for ephemeral gift wraps (CEP-19)
pub supports_ephemeral_gift_wrap: bool,
}

Expand Down
Loading