From e23497ba5019f2a05ca006624e5a910d6f354a2e Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:43:30 +0530 Subject: [PATCH 01/11] docs: scaffold new directory structure --- src/content/docs/how-to/cvmi/skills/.gitkeep | 0 src/content/docs/how-to/payments/rails/.gitkeep | 0 src/content/docs/reference/ceps/informational/.gitkeep | 0 src/content/docs/reference/rs-sdk/.gitkeep | 0 src/content/docs/reference/spec/.gitkeep | 0 src/content/docs/reference/ts-sdk/core/.gitkeep | 0 src/content/docs/reference/ts-sdk/gateway/.gitkeep | 0 src/content/docs/reference/ts-sdk/payments/.gitkeep | 0 src/content/docs/reference/ts-sdk/proxy/.gitkeep | 0 src/content/docs/reference/ts-sdk/relay/.gitkeep | 0 src/content/docs/reference/ts-sdk/signer/.gitkeep | 0 src/content/docs/reference/ts-sdk/transports/.gitkeep | 0 src/content/docs/tutorials/.gitkeep | 0 13 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/content/docs/how-to/cvmi/skills/.gitkeep create mode 100644 src/content/docs/how-to/payments/rails/.gitkeep create mode 100644 src/content/docs/reference/ceps/informational/.gitkeep create mode 100644 src/content/docs/reference/rs-sdk/.gitkeep create mode 100644 src/content/docs/reference/spec/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/core/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/gateway/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/payments/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/proxy/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/relay/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/signer/.gitkeep create mode 100644 src/content/docs/reference/ts-sdk/transports/.gitkeep create mode 100644 src/content/docs/tutorials/.gitkeep diff --git a/src/content/docs/how-to/cvmi/skills/.gitkeep b/src/content/docs/how-to/cvmi/skills/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/how-to/payments/rails/.gitkeep b/src/content/docs/how-to/payments/rails/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ceps/informational/.gitkeep b/src/content/docs/reference/ceps/informational/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/rs-sdk/.gitkeep b/src/content/docs/reference/rs-sdk/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/spec/.gitkeep b/src/content/docs/reference/spec/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/core/.gitkeep b/src/content/docs/reference/ts-sdk/core/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/gateway/.gitkeep b/src/content/docs/reference/ts-sdk/gateway/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/payments/.gitkeep b/src/content/docs/reference/ts-sdk/payments/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/proxy/.gitkeep b/src/content/docs/reference/ts-sdk/proxy/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/relay/.gitkeep b/src/content/docs/reference/ts-sdk/relay/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/signer/.gitkeep b/src/content/docs/reference/ts-sdk/signer/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/reference/ts-sdk/transports/.gitkeep b/src/content/docs/reference/ts-sdk/transports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/content/docs/tutorials/.gitkeep b/src/content/docs/tutorials/.gitkeep new file mode 100644 index 0000000..e69de29 From 7485b406313d3f6f47cce4d0e2647446cf162142 Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:44:12 +0530 Subject: [PATCH 02/11] docs: move specification and CEPs to reference/ --- src/content/docs/{spec => reference}/ceps/cep-15.md | 0 src/content/docs/{spec => reference}/ceps/cep-17.md | 0 src/content/docs/{spec => reference}/ceps/cep-19.md | 0 src/content/docs/{spec => reference}/ceps/cep-22.md | 0 src/content/docs/{spec => reference}/ceps/cep-23.md | 0 src/content/docs/{spec => reference}/ceps/cep-24.md | 0 src/content/docs/{spec => reference}/ceps/cep-4.md | 0 src/content/docs/{spec => reference}/ceps/cep-41.md | 0 src/content/docs/{spec => reference}/ceps/cep-6.md | 0 src/content/docs/{spec => reference}/ceps/cep-8.md | 0 src/content/docs/{spec => reference}/ceps/informational/cep-16.md | 0 src/content/docs/{spec => reference}/ceps/informational/cep-21.md | 0 src/content/docs/{spec => reference}/ceps/informational/cep-35.md | 0 src/content/docs/{ => reference}/spec/cep-guidelines.md | 0 src/content/docs/{ => reference}/spec/ctxvm-draft-spec.md | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename src/content/docs/{spec => reference}/ceps/cep-15.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-17.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-19.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-22.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-23.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-24.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-4.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-41.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-6.md (100%) rename src/content/docs/{spec => reference}/ceps/cep-8.md (100%) rename src/content/docs/{spec => reference}/ceps/informational/cep-16.md (100%) rename src/content/docs/{spec => reference}/ceps/informational/cep-21.md (100%) rename src/content/docs/{spec => reference}/ceps/informational/cep-35.md (100%) rename src/content/docs/{ => reference}/spec/cep-guidelines.md (100%) rename src/content/docs/{ => reference}/spec/ctxvm-draft-spec.md (100%) diff --git a/src/content/docs/spec/ceps/cep-15.md b/src/content/docs/reference/ceps/cep-15.md similarity index 100% rename from src/content/docs/spec/ceps/cep-15.md rename to src/content/docs/reference/ceps/cep-15.md diff --git a/src/content/docs/spec/ceps/cep-17.md b/src/content/docs/reference/ceps/cep-17.md similarity index 100% rename from src/content/docs/spec/ceps/cep-17.md rename to src/content/docs/reference/ceps/cep-17.md diff --git a/src/content/docs/spec/ceps/cep-19.md b/src/content/docs/reference/ceps/cep-19.md similarity index 100% rename from src/content/docs/spec/ceps/cep-19.md rename to src/content/docs/reference/ceps/cep-19.md diff --git a/src/content/docs/spec/ceps/cep-22.md b/src/content/docs/reference/ceps/cep-22.md similarity index 100% rename from src/content/docs/spec/ceps/cep-22.md rename to src/content/docs/reference/ceps/cep-22.md diff --git a/src/content/docs/spec/ceps/cep-23.md b/src/content/docs/reference/ceps/cep-23.md similarity index 100% rename from src/content/docs/spec/ceps/cep-23.md rename to src/content/docs/reference/ceps/cep-23.md diff --git a/src/content/docs/spec/ceps/cep-24.md b/src/content/docs/reference/ceps/cep-24.md similarity index 100% rename from src/content/docs/spec/ceps/cep-24.md rename to src/content/docs/reference/ceps/cep-24.md diff --git a/src/content/docs/spec/ceps/cep-4.md b/src/content/docs/reference/ceps/cep-4.md similarity index 100% rename from src/content/docs/spec/ceps/cep-4.md rename to src/content/docs/reference/ceps/cep-4.md diff --git a/src/content/docs/spec/ceps/cep-41.md b/src/content/docs/reference/ceps/cep-41.md similarity index 100% rename from src/content/docs/spec/ceps/cep-41.md rename to src/content/docs/reference/ceps/cep-41.md diff --git a/src/content/docs/spec/ceps/cep-6.md b/src/content/docs/reference/ceps/cep-6.md similarity index 100% rename from src/content/docs/spec/ceps/cep-6.md rename to src/content/docs/reference/ceps/cep-6.md diff --git a/src/content/docs/spec/ceps/cep-8.md b/src/content/docs/reference/ceps/cep-8.md similarity index 100% rename from src/content/docs/spec/ceps/cep-8.md rename to src/content/docs/reference/ceps/cep-8.md diff --git a/src/content/docs/spec/ceps/informational/cep-16.md b/src/content/docs/reference/ceps/informational/cep-16.md similarity index 100% rename from src/content/docs/spec/ceps/informational/cep-16.md rename to src/content/docs/reference/ceps/informational/cep-16.md diff --git a/src/content/docs/spec/ceps/informational/cep-21.md b/src/content/docs/reference/ceps/informational/cep-21.md similarity index 100% rename from src/content/docs/spec/ceps/informational/cep-21.md rename to src/content/docs/reference/ceps/informational/cep-21.md diff --git a/src/content/docs/spec/ceps/informational/cep-35.md b/src/content/docs/reference/ceps/informational/cep-35.md similarity index 100% rename from src/content/docs/spec/ceps/informational/cep-35.md rename to src/content/docs/reference/ceps/informational/cep-35.md diff --git a/src/content/docs/spec/cep-guidelines.md b/src/content/docs/reference/spec/cep-guidelines.md similarity index 100% rename from src/content/docs/spec/cep-guidelines.md rename to src/content/docs/reference/spec/cep-guidelines.md diff --git a/src/content/docs/spec/ctxvm-draft-spec.md b/src/content/docs/reference/spec/ctxvm-draft-spec.md similarity index 100% rename from src/content/docs/spec/ctxvm-draft-spec.md rename to src/content/docs/reference/spec/ctxvm-draft-spec.md From 6265a92055d9bd3112ac1ffd493dc530b99af6be Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:44:12 +0530 Subject: [PATCH 03/11] docs: move TypeScript SDK docs to reference/ts-sdk/ --- .../docs/{ => reference}/ts-sdk/core/common-tool-schemas.md | 0 src/content/docs/{ => reference}/ts-sdk/core/constants.md | 0 src/content/docs/{ => reference}/ts-sdk/core/encryption.md | 0 src/content/docs/{ => reference}/ts-sdk/core/interfaces.md | 0 src/content/docs/{ => reference}/ts-sdk/core/logging.md | 0 src/content/docs/{ => reference}/ts-sdk/gateway/overview.md | 0 src/content/docs/{ => reference}/ts-sdk/payments/overview.md | 0 src/content/docs/{ => reference}/ts-sdk/proxy/overview.md | 0 src/content/docs/{ => reference}/ts-sdk/quick-overview.md | 0 .../docs/{ => reference}/ts-sdk/relay/applesauce-relay-pool.md | 0 .../docs/{ => reference}/ts-sdk/relay/custom-relay-handler.md | 0 .../docs/{ => reference}/ts-sdk/relay/relay-handler-interface.md | 0 .../{ => reference}/ts-sdk/signer/custom-signer-development.md | 0 .../docs/{ => reference}/ts-sdk/signer/nostr-signer-interface.md | 0 .../docs/{ => reference}/ts-sdk/signer/private-key-signer.md | 0 .../{ => reference}/ts-sdk/transports/base-nostr-transport.md | 0 .../{ => reference}/ts-sdk/transports/nostr-client-transport.md | 0 .../{ => reference}/ts-sdk/transports/nostr-server-transport.md | 0 src/content/docs/{ => reference}/ts-sdk/transports/open-stream.md | 0 .../docs/{ => reference}/ts-sdk/transports/oversized-transfer.md | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename src/content/docs/{ => reference}/ts-sdk/core/common-tool-schemas.md (100%) rename src/content/docs/{ => reference}/ts-sdk/core/constants.md (100%) rename src/content/docs/{ => reference}/ts-sdk/core/encryption.md (100%) rename src/content/docs/{ => reference}/ts-sdk/core/interfaces.md (100%) rename src/content/docs/{ => reference}/ts-sdk/core/logging.md (100%) rename src/content/docs/{ => reference}/ts-sdk/gateway/overview.md (100%) rename src/content/docs/{ => reference}/ts-sdk/payments/overview.md (100%) rename src/content/docs/{ => reference}/ts-sdk/proxy/overview.md (100%) rename src/content/docs/{ => reference}/ts-sdk/quick-overview.md (100%) rename src/content/docs/{ => reference}/ts-sdk/relay/applesauce-relay-pool.md (100%) rename src/content/docs/{ => reference}/ts-sdk/relay/custom-relay-handler.md (100%) rename src/content/docs/{ => reference}/ts-sdk/relay/relay-handler-interface.md (100%) rename src/content/docs/{ => reference}/ts-sdk/signer/custom-signer-development.md (100%) rename src/content/docs/{ => reference}/ts-sdk/signer/nostr-signer-interface.md (100%) rename src/content/docs/{ => reference}/ts-sdk/signer/private-key-signer.md (100%) rename src/content/docs/{ => reference}/ts-sdk/transports/base-nostr-transport.md (100%) rename src/content/docs/{ => reference}/ts-sdk/transports/nostr-client-transport.md (100%) rename src/content/docs/{ => reference}/ts-sdk/transports/nostr-server-transport.md (100%) rename src/content/docs/{ => reference}/ts-sdk/transports/open-stream.md (100%) rename src/content/docs/{ => reference}/ts-sdk/transports/oversized-transfer.md (100%) diff --git a/src/content/docs/ts-sdk/core/common-tool-schemas.md b/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md similarity index 100% rename from src/content/docs/ts-sdk/core/common-tool-schemas.md rename to src/content/docs/reference/ts-sdk/core/common-tool-schemas.md diff --git a/src/content/docs/ts-sdk/core/constants.md b/src/content/docs/reference/ts-sdk/core/constants.md similarity index 100% rename from src/content/docs/ts-sdk/core/constants.md rename to src/content/docs/reference/ts-sdk/core/constants.md diff --git a/src/content/docs/ts-sdk/core/encryption.md b/src/content/docs/reference/ts-sdk/core/encryption.md similarity index 100% rename from src/content/docs/ts-sdk/core/encryption.md rename to src/content/docs/reference/ts-sdk/core/encryption.md diff --git a/src/content/docs/ts-sdk/core/interfaces.md b/src/content/docs/reference/ts-sdk/core/interfaces.md similarity index 100% rename from src/content/docs/ts-sdk/core/interfaces.md rename to src/content/docs/reference/ts-sdk/core/interfaces.md diff --git a/src/content/docs/ts-sdk/core/logging.md b/src/content/docs/reference/ts-sdk/core/logging.md similarity index 100% rename from src/content/docs/ts-sdk/core/logging.md rename to src/content/docs/reference/ts-sdk/core/logging.md diff --git a/src/content/docs/ts-sdk/gateway/overview.md b/src/content/docs/reference/ts-sdk/gateway/overview.md similarity index 100% rename from src/content/docs/ts-sdk/gateway/overview.md rename to src/content/docs/reference/ts-sdk/gateway/overview.md diff --git a/src/content/docs/ts-sdk/payments/overview.md b/src/content/docs/reference/ts-sdk/payments/overview.md similarity index 100% rename from src/content/docs/ts-sdk/payments/overview.md rename to src/content/docs/reference/ts-sdk/payments/overview.md diff --git a/src/content/docs/ts-sdk/proxy/overview.md b/src/content/docs/reference/ts-sdk/proxy/overview.md similarity index 100% rename from src/content/docs/ts-sdk/proxy/overview.md rename to src/content/docs/reference/ts-sdk/proxy/overview.md diff --git a/src/content/docs/ts-sdk/quick-overview.md b/src/content/docs/reference/ts-sdk/quick-overview.md similarity index 100% rename from src/content/docs/ts-sdk/quick-overview.md rename to src/content/docs/reference/ts-sdk/quick-overview.md diff --git a/src/content/docs/ts-sdk/relay/applesauce-relay-pool.md b/src/content/docs/reference/ts-sdk/relay/applesauce-relay-pool.md similarity index 100% rename from src/content/docs/ts-sdk/relay/applesauce-relay-pool.md rename to src/content/docs/reference/ts-sdk/relay/applesauce-relay-pool.md diff --git a/src/content/docs/ts-sdk/relay/custom-relay-handler.md b/src/content/docs/reference/ts-sdk/relay/custom-relay-handler.md similarity index 100% rename from src/content/docs/ts-sdk/relay/custom-relay-handler.md rename to src/content/docs/reference/ts-sdk/relay/custom-relay-handler.md diff --git a/src/content/docs/ts-sdk/relay/relay-handler-interface.md b/src/content/docs/reference/ts-sdk/relay/relay-handler-interface.md similarity index 100% rename from src/content/docs/ts-sdk/relay/relay-handler-interface.md rename to src/content/docs/reference/ts-sdk/relay/relay-handler-interface.md diff --git a/src/content/docs/ts-sdk/signer/custom-signer-development.md b/src/content/docs/reference/ts-sdk/signer/custom-signer-development.md similarity index 100% rename from src/content/docs/ts-sdk/signer/custom-signer-development.md rename to src/content/docs/reference/ts-sdk/signer/custom-signer-development.md diff --git a/src/content/docs/ts-sdk/signer/nostr-signer-interface.md b/src/content/docs/reference/ts-sdk/signer/nostr-signer-interface.md similarity index 100% rename from src/content/docs/ts-sdk/signer/nostr-signer-interface.md rename to src/content/docs/reference/ts-sdk/signer/nostr-signer-interface.md diff --git a/src/content/docs/ts-sdk/signer/private-key-signer.md b/src/content/docs/reference/ts-sdk/signer/private-key-signer.md similarity index 100% rename from src/content/docs/ts-sdk/signer/private-key-signer.md rename to src/content/docs/reference/ts-sdk/signer/private-key-signer.md diff --git a/src/content/docs/ts-sdk/transports/base-nostr-transport.md b/src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md similarity index 100% rename from src/content/docs/ts-sdk/transports/base-nostr-transport.md rename to src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md diff --git a/src/content/docs/ts-sdk/transports/nostr-client-transport.md b/src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md similarity index 100% rename from src/content/docs/ts-sdk/transports/nostr-client-transport.md rename to src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md diff --git a/src/content/docs/ts-sdk/transports/nostr-server-transport.md b/src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md similarity index 100% rename from src/content/docs/ts-sdk/transports/nostr-server-transport.md rename to src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md diff --git a/src/content/docs/ts-sdk/transports/open-stream.md b/src/content/docs/reference/ts-sdk/transports/open-stream.md similarity index 100% rename from src/content/docs/ts-sdk/transports/open-stream.md rename to src/content/docs/reference/ts-sdk/transports/open-stream.md diff --git a/src/content/docs/ts-sdk/transports/oversized-transfer.md b/src/content/docs/reference/ts-sdk/transports/oversized-transfer.md similarity index 100% rename from src/content/docs/ts-sdk/transports/oversized-transfer.md rename to src/content/docs/reference/ts-sdk/transports/oversized-transfer.md From 9fd14186dc21fcaf3fed916f5f01737cbc0b0774 Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:44:12 +0530 Subject: [PATCH 04/11] docs: move payment guides to how-to/, tutorials and cvmi --- src/content/docs/{ => how-to}/cvmi/commands.md | 0 src/content/docs/{ => how-to}/cvmi/configuration.md | 0 src/content/docs/{ => how-to}/cvmi/installation.md | 0 src/content/docs/{ => how-to}/cvmi/overview.md | 0 src/content/docs/{ => how-to}/cvmi/skills/overview.md | 0 src/content/docs/{ts-sdk => how-to}/payments/client.md | 0 src/content/docs/{ts-sdk => how-to}/payments/custom-rails.md | 0 src/content/docs/{ts-sdk => how-to}/payments/getting-started.md | 0 .../docs/{ts-sdk => how-to}/payments/rails/lightning-nwc.md | 0 src/content/docs/{ts-sdk => how-to}/payments/server.md | 0 .../docs/{ts-sdk => }/tutorials/client-server-communication.md | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/content/docs/{ => how-to}/cvmi/commands.md (100%) rename src/content/docs/{ => how-to}/cvmi/configuration.md (100%) rename src/content/docs/{ => how-to}/cvmi/installation.md (100%) rename src/content/docs/{ => how-to}/cvmi/overview.md (100%) rename src/content/docs/{ => how-to}/cvmi/skills/overview.md (100%) rename src/content/docs/{ts-sdk => how-to}/payments/client.md (100%) rename src/content/docs/{ts-sdk => how-to}/payments/custom-rails.md (100%) rename src/content/docs/{ts-sdk => how-to}/payments/getting-started.md (100%) rename src/content/docs/{ts-sdk => how-to}/payments/rails/lightning-nwc.md (100%) rename src/content/docs/{ts-sdk => how-to}/payments/server.md (100%) rename src/content/docs/{ts-sdk => }/tutorials/client-server-communication.md (100%) diff --git a/src/content/docs/cvmi/commands.md b/src/content/docs/how-to/cvmi/commands.md similarity index 100% rename from src/content/docs/cvmi/commands.md rename to src/content/docs/how-to/cvmi/commands.md diff --git a/src/content/docs/cvmi/configuration.md b/src/content/docs/how-to/cvmi/configuration.md similarity index 100% rename from src/content/docs/cvmi/configuration.md rename to src/content/docs/how-to/cvmi/configuration.md diff --git a/src/content/docs/cvmi/installation.md b/src/content/docs/how-to/cvmi/installation.md similarity index 100% rename from src/content/docs/cvmi/installation.md rename to src/content/docs/how-to/cvmi/installation.md diff --git a/src/content/docs/cvmi/overview.md b/src/content/docs/how-to/cvmi/overview.md similarity index 100% rename from src/content/docs/cvmi/overview.md rename to src/content/docs/how-to/cvmi/overview.md diff --git a/src/content/docs/cvmi/skills/overview.md b/src/content/docs/how-to/cvmi/skills/overview.md similarity index 100% rename from src/content/docs/cvmi/skills/overview.md rename to src/content/docs/how-to/cvmi/skills/overview.md diff --git a/src/content/docs/ts-sdk/payments/client.md b/src/content/docs/how-to/payments/client.md similarity index 100% rename from src/content/docs/ts-sdk/payments/client.md rename to src/content/docs/how-to/payments/client.md diff --git a/src/content/docs/ts-sdk/payments/custom-rails.md b/src/content/docs/how-to/payments/custom-rails.md similarity index 100% rename from src/content/docs/ts-sdk/payments/custom-rails.md rename to src/content/docs/how-to/payments/custom-rails.md diff --git a/src/content/docs/ts-sdk/payments/getting-started.md b/src/content/docs/how-to/payments/getting-started.md similarity index 100% rename from src/content/docs/ts-sdk/payments/getting-started.md rename to src/content/docs/how-to/payments/getting-started.md diff --git a/src/content/docs/ts-sdk/payments/rails/lightning-nwc.md b/src/content/docs/how-to/payments/rails/lightning-nwc.md similarity index 100% rename from src/content/docs/ts-sdk/payments/rails/lightning-nwc.md rename to src/content/docs/how-to/payments/rails/lightning-nwc.md diff --git a/src/content/docs/ts-sdk/payments/server.md b/src/content/docs/how-to/payments/server.md similarity index 100% rename from src/content/docs/ts-sdk/payments/server.md rename to src/content/docs/how-to/payments/server.md diff --git a/src/content/docs/ts-sdk/tutorials/client-server-communication.md b/src/content/docs/tutorials/client-server-communication.md similarity index 100% rename from src/content/docs/ts-sdk/tutorials/client-server-communication.md rename to src/content/docs/tutorials/client-server-communication.md From e09ffee04dbe25564d849da08177181b59575543 Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:45:23 +0530 Subject: [PATCH 05/11] docs: add Rust SDK documentation --- .../docs/reference/rs-sdk/client-transport.md | 179 +++++++++ src/content/docs/reference/rs-sdk/design.md | 362 ++++++++++++++++++ .../docs/reference/rs-sdk/discovery.md | 94 +++++ .../docs/reference/rs-sdk/encryption.md | 84 ++++ src/content/docs/reference/rs-sdk/gateway.md | 139 +++++++ src/content/docs/reference/rs-sdk/overview.md | 111 ++++++ src/content/docs/reference/rs-sdk/proxy.md | 122 ++++++ src/content/docs/reference/rs-sdk/rmcp.md | 52 +++ .../docs/reference/rs-sdk/server-transport.md | 186 +++++++++ .../docs/reference/rs-sdk/stateless.md | 110 ++++++ .../docs/reference/rs-sdk/transport-modes.md | 124 ++++++ .../docs/reference/rs-sdk/transports.md | 145 +++++++ 12 files changed, 1708 insertions(+) create mode 100644 src/content/docs/reference/rs-sdk/client-transport.md create mode 100644 src/content/docs/reference/rs-sdk/design.md create mode 100644 src/content/docs/reference/rs-sdk/discovery.md create mode 100644 src/content/docs/reference/rs-sdk/encryption.md create mode 100644 src/content/docs/reference/rs-sdk/gateway.md create mode 100644 src/content/docs/reference/rs-sdk/overview.md create mode 100644 src/content/docs/reference/rs-sdk/proxy.md create mode 100644 src/content/docs/reference/rs-sdk/rmcp.md create mode 100644 src/content/docs/reference/rs-sdk/server-transport.md create mode 100644 src/content/docs/reference/rs-sdk/stateless.md create mode 100644 src/content/docs/reference/rs-sdk/transport-modes.md create mode 100644 src/content/docs/reference/rs-sdk/transports.md diff --git a/src/content/docs/reference/rs-sdk/client-transport.md b/src/content/docs/reference/rs-sdk/client-transport.md new file mode 100644 index 0000000..588f9f5 --- /dev/null +++ b/src/content/docs/reference/rs-sdk/client-transport.md @@ -0,0 +1,179 @@ +--- +title: "Native Client Guide" +description: "ContextVM Rust SDK documentation for Native Client Guide" +--- + + +Use this path when you are building a native ContextVM client in Rust. + +The recommended architecture is: + +- define an `rmcp` client handler or use a lightweight client info object +- create a `NostrClientTransport` +- attach the transport with `rmcp`'s `ServiceExt` + +This follows the same pattern as the standard `rmcp` client examples, except the transport is ContextVM over Nostr instead of HTTP. + +## The high-level shape + +In `rmcp`, a client is typically started with `client_info.serve(transport)`. + +For ContextVM, the transport becomes `NostrClientTransport`. In the current SDK API, you pass that transport directly to `ServiceExt`; there is no extra adapter step in the public workflow. + +## Loading an existing private key + +The signer helper is not limited to ephemeral keys. If you already have a private key, load it with `from_sk()`. + +It accepts either: + +- a 64-character hex secret key +- an `nsec` bech32 secret key + +```rust +use contextvm_sdk::signer; + +let signer = signer::from_sk("")?; +println!("client pubkey: {}", signer.public_key().to_hex()); +``` + +Use `generate()` only when you explicitly want a new random identity for a short-lived client or test flow. + +## Example + +```rust +use anyhow::Context; +use contextvm_sdk::transport::client::{ + NostrClientTransport, NostrClientTransportConfig, +}; +use contextvm_sdk::{signer, EncryptionMode, GiftWrapMode}; +use rmcp::{ + model::{CallToolRequestParams, CallToolResult}, + ClientHandler, ServiceExt, +}; + +const RELAY_URL: &str = "wss://relay.contextvm.org"; + +#[derive(Clone, Default)] +struct DemoClient; + +impl ClientHandler for DemoClient {} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let server_pubkey = std::env::args() + .nth(1) + .context("Usage: native_echo_client ")?; + + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::from_default_env() + .add_directive("contextvm_sdk=info".parse()?) + .add_directive("rmcp=warn".parse()?), + ) + .init(); + + let signer = signer::generate(); + + println!("Native ContextVM echo client starting"); + println!("Relay: {RELAY_URL}"); + println!("Client pubkey: {}", signer.public_key().to_hex()); + println!("Target server pubkey: {server_pubkey}"); + + let transport = NostrClientTransport::new( + signer, + NostrClientTransportConfig::default() + .with_relay_urls(vec![RELAY_URL.to_string()]) + .with_server_pubkey(server_pubkey) + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional), + ) + .await?; + + let client = DemoClient.serve(transport).await?; + + let peer_info = client + .peer_info() + .expect("server did not provide peer info after initialize"); + println!("Connected to: {:?}", peer_info.server_info.name); + + let tools = client.list_all_tools().await?; + println!("Discovered {} tool(s):", tools.len()); + for tool in &tools { + println!("- {}", tool.name); + } + + let result = client + .call_tool(CallToolRequestParams { + name: "echo".into(), + arguments: serde_json::from_value(serde_json::json!({ + "message": "hello from native contextvm client" + })) + .ok(), + meta: None, + task: None, + }) + .await?; + + println!("Echo result: {}", first_text(&result)); + client.cancel().await?; + Ok(()) +} + +fn first_text(result: &CallToolResult) -> String { + result + .content + .iter() + .find_map(|content| { + if let rmcp::model::RawContent::Text(text) = &content.raw { + Some(text.text.clone()) + } else { + None + } + }) + .unwrap_or_default() +} +``` + +This is the ContextVM equivalent of the usual `rmcp` client workflow, but using `NostrClientTransport` directly. + +## What the transport adds + +`NostrClientTransport` adds ContextVM-specific client behavior on top of `rmcp` client semantics: + +- relay connection management via `NostrClientTransport::new()` +- target server selection through `server_pubkey` in `NostrClientTransportConfig` +- request and response correlation via `send()` +- server capability learning from discovery tags +- optional stateless behavior via `is_stateless` in `NostrClientTransportConfig` +- encrypted message reception and gift-wrap deduplication during notification handling + +## Configuration fields that matter first + +Start with these fields in `NostrClientTransportConfig`: + +- `relay_urls`: relays the client uses to reach the server (empty = use relay resolution) +- `server_pubkey`: the target server's public key (hex, npub, or nprofile with relay hints) +- `encryption_mode`: whether plaintext is allowed +- `gift_wrap_mode`: whether to use persistent or ephemeral wrapping +- `is_stateless`: whether initialize is emulated locally for stateless workflows +- `timeout`: how long request correlation waits for a response +- `discovery_relay_urls`: bootstrap relays for CEP-17 kind 10002 relay-list discovery (defaults to `DEFAULT_BOOTSTRAP_RELAY_URLS`) +- `fallback_operational_relay_urls`: non-authoritative relays probed in parallel with CEP-17 discovery + +## When to use this instead of the proxy + +Use this page's approach when you are writing a new Rust MCP client that should speak ContextVM natively. + +Use the proxy guide when you want a simpler message-oriented bridge and do not want the full `rmcp` running client model. + +## Behavioral notes + +- The client-side `rmcp` handshake is driven by `ServiceExt::serve()` on the client handler. +- The initialize request is sent automatically as part of the running client startup sequence. +- Stateless initialization behavior is covered by the conformance tests. +- Capability learning and gift-wrap handling happen inside the client transport implementation. +- When `relay_urls` is empty, `start()` runs 6-stage relay resolution before connecting: configured relays > nprofile hints > CEP-17 kind 10002 discovery > fallback probing > bootstrap defaults. Callers can set `server_pubkey` to an nprofile and omit `relay_urls` entirely. + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/client-transport.md).* diff --git a/src/content/docs/reference/rs-sdk/design.md b/src/content/docs/reference/rs-sdk/design.md new file mode 100644 index 0000000..ac2f6bb --- /dev/null +++ b/src/content/docs/reference/rs-sdk/design.md @@ -0,0 +1,362 @@ +--- +title: "Architecture & Design" +description: "ContextVM Rust SDK documentation for Architecture & Design" +--- + + +**Date:** 2026-03-11 +**Status:** Implementation Complete (Phase 1-5) +**Reference:** [ContextVM TS SDK](https://github.com/ContextVM/sdk) · [ContextVM Draft Spec](https://contextvm.org) · [Existing Rust crate](https://github.com/k0sti/clarity/tree/main/crates/cvm) + +## Verification Summary (2026-03-11) + +| Check | Result | +|-------|--------| +| `cargo check` | ✅ Clean (2 unused import warnings) | +| `cargo test` | ✅ 8 unit + 3 doc tests pass | +| `cargo build --examples` | ✅ All 3 examples compile | +| Source LOC | 1,914 across 17 files | +| Tasks complete | 22/22 | + +### Remaining Polish +- Fix 2 unused import warnings (`Error` in base.rs, `Instant` in server.rs) +- Add more unit tests for transport/gateway/proxy (currently only core + encryption tested) +- Integration tests with live relay (requires test relay setup) +- `cargo doc` warnings check + doc completeness audit + +## Goal + +A complete Rust SDK for the ContextVM protocol that matches the TypeScript SDK feature-for-feature, enabling any Rust MCP server or client to communicate over Nostr. + +--- + +## Architecture + +``` +rust-contextvm-sdk/ +├── src/ +│ ├── lib.rs # Re-exports, crate root +│ ├── core/ +│ │ ├── mod.rs +│ │ ├── constants.rs # Event kinds, tags, limits +│ │ ├── types.rs # EncryptionMode, ServerInfo, ClientSession +│ │ ├── error.rs # Error types +│ │ ├── serializers.rs # mcpToNostrEvent, nostrEventToMcpMessage, getTag +│ │ └── validation.rs # validateMessage, validateMessageSize +│ ├── transport/ +│ │ ├── mod.rs +│ │ ├── base.rs # BaseNostrTransport (shared logic) +│ │ ├── client.rs # NostrClientTransport +│ │ └── server.rs # NostrServerTransport +│ ├── gateway/ +│ │ ├── mod.rs # NostrMCPGateway +│ ├── proxy/ +│ │ ├── mod.rs # NostrMCPProxy +│ ├── relay/ +│ │ ├── mod.rs # RelayPool +│ ├── signer/ +│ │ ├── mod.rs # Signer trait + KeysSigner +│ └── encryption/ +│ ├── mod.rs # NIP-44 encrypt/decrypt, NIP-59 gift wrap +├── examples/ +│ ├── gateway.rs # Example: expose a local MCP server via Nostr +│ ├── proxy.rs # Example: connect to remote MCP server via Nostr +│ └── discovery.rs # Example: discover servers on relay +├── tests/ +│ ├── transport_test.rs +│ ├── gateway_test.rs +│ └── encryption_test.rs +├── Cargo.toml +├── README.md +├── DESIGN.md +└── LICENSE +``` + +## Module Mapping: TS SDK → Rust SDK + +| TS SDK Module | TS LOC | Rust Module | Source | Status | +|---------------|--------|-------------|--------|--------| +| `core/constants.ts` | 87 | `core/constants.rs` (64 LOC) | Port from existing Rust | ✅ done | +| `core/interfaces.ts` | 61 | `core/types.rs` (188 LOC) | Port from existing Rust | ✅ done | +| `core/encryption.ts` | 64 | `encryption/mod.rs` (86 LOC) | Port from existing Rust | ✅ done | +| `core/utils/serializers.ts` | ~60 | `core/serializers.rs` (74 LOC) | New | ✅ done | +| `core/utils/utils.ts` | ~30 | `core/validation.rs` (64 LOC) | New | ✅ done | +| `relay/simple-relay-pool.ts` | ~100 | `relay/mod.rs` (108 LOC) | Port from existing Rust | ✅ done | +| `signer/private-key-signer.ts` | ~50 | `signer/mod.rs` (15 LOC) | Port from existing Rust | ✅ done | +| `transport/base-nostr-transport.ts` | 355 | `transport/base.rs` (139 LOC) | New | ✅ done | +| `transport/nostr-client-transport.ts` | 411 | `transport/client.rs` (228 LOC) | Rewrite from existing | ✅ done | +| `transport/nostr-server-transport.ts` | 944 | `transport/server.rs` (583 LOC) | Rewrite from existing | ✅ done | +| `gateway/index.ts` | 151 | `gateway/mod.rs` (82 LOC) | New | ✅ done | +| `proxy/index.ts` | 96 | `proxy/mod.rs` (71 LOC) | New | ✅ done | +| *(n/a — new)* | — | `discovery/mod.rs` (154 LOC) | New | ✅ done | +| *(n/a — new)* | — | `core/error.rs` (40 LOC) | New | ✅ done | + +**TS SDK total:** ~2,169 LOC (non-test) +**Existing Rust (reference):** ~782 LOC +**Actual Rust SDK:** 1,914 LOC (+ tests + examples) + +--- + +## Dependencies + +```toml +[dependencies] +tokio = { version = "1", features = ["full"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +nostr-sdk = { version = "0.43", features = ["nip59"] } +thiserror = "2" +async-trait = "0.1" +tracing = "0.1" + +[dev-dependencies] +tokio-test = "0.4" +tracing-subscriber = "0.3" +``` + +**Note on MCP types:** The TS SDK imports from `@modelcontextprotocol/sdk`. There's no official Rust MCP SDK yet. We define our own JSON-RPC message types that are protocol-compatible. If/when an official Rust MCP SDK exists, we can add it as an optional integration. + +--- + +## Tasks + +### Phase 1: Core Foundation +*Port and enhance existing code. Establish project structure.* + +- **1.1** Initialize Cargo project with workspace structure and dependencies + - **Verify:** `cargo check` passes with empty lib.rs + +- **1.2** Port `core/constants.rs` from existing crate + - All event kinds (25910, 1059, 11316-11320) + - All tag constants (p, e, cap, name, website, picture, about, support_encryption) + - MAX_MESSAGE_SIZE + - **Verify:** Constants match TS SDK `core/constants.ts` values exactly + +- **1.3** Port `core/error.rs` from existing crate + - Error variants: Transport, Encryption, Decryption, Timeout, Validation, Unauthorized, Other + - **Verify:** All error types cover TS SDK error scenarios + +- **1.4** Port and extend `core/types.rs` + - `EncryptionMode` (Optional, Required, Disabled) + - `ServerInfo` (name, version, picture, website, about) + - `ClientSession` (is_initialized, is_encrypted, last_activity, pending_requests, event_to_progress_token) + - Add JSON-RPC types: `JsonRpcMessage`, `JsonRpcRequest`, `JsonRpcResponse`, `JsonRpcNotification`, `JsonRpcError` + - **Verify:** `serde_json::from_str` round-trips for all MCP message types + +- **1.5** Create `core/serializers.rs` + - `mcp_to_nostr_event(message, pubkey, kind, tags) → UnsignedEvent` + - `nostr_event_to_mcp_message(event) → Option` + - `get_tag_value(tags, name) → Option` + - **Verify:** Unit tests: serialize MCP request → Nostr event → deserialize back, content matches + +- **1.6** Create `core/validation.rs` + - `validate_message_size(content) → bool` (≤1MB) + - `validate_message(value) → Option` (check jsonrpc="2.0", has method or result/error) + - **Verify:** Unit tests: valid/invalid messages, oversize content rejected + +- **1.7** Port `encryption/mod.rs` from existing crate + - `encrypt_nip44(signer, pubkey, plaintext) → Result` + - `decrypt_nip44(signer, pubkey, ciphertext) → Result` + - `encrypt_gift_wrap(content, recipient_pubkey) → Event` (NIP-59) + - `decrypt_gift_wrap(event, signer) → Result` (NIP-59) + - **Verify:** Unit test: encrypt → decrypt round-trip for both NIP-44 and gift wrap + +- **1.8** Port `signer/mod.rs` from existing crate + - Re-export `Keys`, `NostrSigner`, `PublicKey` from nostr-sdk + - `from_sk(sk) → Result` + - `generate() → Keys` + - **Verify:** Generate keys, sign event, verify signature + +- **1.9** Port `relay/mod.rs` from existing crate + - `RelayPool::new(signer) → Result` + - `connect(urls) → Result<()>` + - `disconnect() → Result<()>` + - `publish(event) → Result` + - `subscribe(filters) → Result` + - `client() → &Arc` + - **Verify:** Integration test with a local relay (or mock): connect, publish, fetch + +### Phase 2: Transport Layer +*The core of the SDK. Implements MCP Transport trait over Nostr.* + +- **2.1** Define Rust `Transport` trait + - ```rust + #[async_trait] + pub trait Transport: Send + Sync { + async fn start(&mut self) -> Result<()>; + async fn close(&mut self) -> Result<()>; + async fn send(&self, message: JsonRpcMessage) -> Result<()>; + fn set_message_handler(&mut self, handler: Box); + fn set_error_handler(&mut self, handler: Box); + fn set_close_handler(&mut self, handler: Box); + } + ``` + - **Verify:** Trait compiles, can be used as `dyn Transport` + +- **2.2** Implement `BaseNostrTransport` (shared logic) + - Fields: signer, relay_pool, encryption_mode, is_connected + - Methods: + - `connect() / disconnect()` + - `get_public_key() → String` + - `subscribe(filters, on_event)` + - `convert_nostr_event_to_mcp(event) → Option` (validate size + structure) + - `create_signed_nostr_event(message, kind, tags) → Event` + - `publish_event(event)` + - `send_mcp_message(message, recipient, kind, tags, is_encrypted) → String` (encrypt if needed) + - `should_encrypt_message(kind, is_encrypted) → bool` + - `create_subscription_filters(pubkey) → Vec` + - `create_recipient_tags(pubkey) → Vec` + - `create_response_tags(pubkey, event_id) → Vec` + - **Verify:** Unit tests for `should_encrypt_message` with all EncryptionMode variants + +- **2.3** Implement `NostrClientTransport` + - Config: relay_urls, server_pubkey, encryption_mode, is_stateless + - Implements `Transport` trait + - Features: + - Subscribe to events targeting client pubkey + - `send()`: create event with recipient tags, publish (encrypt if needed) + - Response correlation via pending_request_ids set + `e` tag matching + - Stateless mode: emulate initialize response locally + - Process incoming: decrypt gift wrap → verify server pubkey → correlate → dispatch + - Notification handling (no `e` tag → notification) + - **Verify:** + - Unit test: send request, receive correlated response + - Unit test: stateless mode emulates initialize + - Unit test: rejects events from wrong server pubkey + +- **2.4** Implement `NostrServerTransport` + - Config: relay_urls, encryption_mode, server_info, is_announced_server, allowed_public_keys, excluded_capabilities, cleanup_interval_ms, session_timeout_ms + - Implements `Transport` trait + - Features: + - Subscribe to events targeting server pubkey + - Multi-client session management (HashMap) + - Request correlation: replace request.id with event_id, store original → restore on response + - Progress token tracking for streaming responses + - Authorization: allowedPublicKeys whitelist with capability exclusions + - Encryption mode enforcement (reject unencrypted if Required, reject encrypted if Disabled) + - `send()`: route responses back to correct client, route notifications to all/specific clients + - Public server announcements: initialize → fetch tools/resources/prompts → publish as kinds 11316-11320 + - Announcement deletion (NIP-09 kind 5) + - Periodic session cleanup (configurable interval/timeout) + - **Verify:** + - Unit test: request → response correlation with original ID restoration + - Unit test: multi-client sessions don't cross-contaminate + - Unit test: unauthorized pubkey rejected (with error response for public servers) + - Unit test: encryption mode enforcement + - Unit test: session cleanup removes stale sessions + +### Phase 3: Gateway & Proxy +*Higher-level components that compose transports.* + +- **3.1** Implement `NostrMCPGateway` + - Takes: local MCP transport (any `Transport`) + NostrServerTransportConfig + - Creates NostrServerTransport internally + - Bidirectional message forwarding: + - Nostr → local MCP server (via onmessage) + - Local MCP server → Nostr (via onmessage) + - Lifecycle: `start()` starts both transports, `stop()` closes both + - Error propagation from both sides + - `is_active() → bool` + - **Verify:** + - Integration test: mock MCP transport ↔ gateway ↔ mock Nostr transport + - Test: start/stop lifecycle + - Test: error from one side doesn't crash the other + +- **3.2** Implement `NostrMCPProxy` + - Takes: local MCP host transport + NostrClientTransportConfig + - Creates NostrClientTransport internally + - Bidirectional message forwarding: + - Local host → Nostr (forward to remote server) + - Nostr → local host (relay responses back) + - Lifecycle: `start()` starts both, `stop()` closes both + - **Verify:** + - Integration test: mock local host ↔ proxy ↔ mock Nostr transport + - Test: messages flow both directions + +### Phase 4: Discovery & Announcements +*Server discovery features from the ContextVM spec.* + +- **4.1** Implement server announcement publishing + - Publish kind 11316 (server info) with name/about/website/picture/support_encryption tags + - Publish kind 11317 (tools list) from MCP tools/list response + - Publish kind 11318 (resources list) from MCP resources/list response + - Publish kind 11319 (resource templates list) + - Publish kind 11320 (prompts list) from MCP prompts/list response + - **Verify:** Published events have correct kinds, tags, and parseable content + +- **4.2** Implement server discovery client + - `discover_servers(relay_urls) → Vec` — fetch kind 11316 events + - `discover_tools(server_pubkey, relay_urls) → Vec` — fetch kind 11317 + - `discover_resources(server_pubkey, relay_urls) → Vec` — fetch kind 11318 + - `discover_prompts(server_pubkey, relay_urls) → Vec` — fetch kind 11320 + - **Verify:** Integration test: publish announcements → discover them + +- **4.3** Implement announcement deletion + - `delete_announcements(reason) → Vec` — publish NIP-09 kind 5 for all announcement kinds + - **Verify:** After deletion, discovery returns empty + +### Phase 5: Examples & Documentation +*Working examples and API docs.* + +- **5.1** Create `examples/gateway.rs` + - Expose a simple MCP server (echo tool) via Nostr gateway + - **Verify:** Runs without errors, publishes announcement + +- **5.2** Create `examples/proxy.rs` + - Connect to a remote Nostr MCP server and call a tool + - **Verify:** Runs, sends request, receives response + +- **5.3** Create `examples/discovery.rs` + - Discover servers and their tools on a relay + - **Verify:** Finds published servers + +- **5.4** Write API documentation + - Doc comments on all public types and methods + - Crate-level documentation with usage examples + - **Verify:** `cargo doc --open` produces clean docs, no missing docs warnings + +--- + +## Key Differences from Existing Rust Crate + +| Aspect | Existing (clarity/crates/cvm) | New SDK | +|--------|-------------------------------|---------| +| MCP types | Raw JSON strings | Typed `JsonRpcMessage` enum with serde | +| Transport trait | None | `Transport` trait matching MCP SDK pattern | +| Base transport | None | `BaseNostrTransport` with shared logic | +| Server dispatch | `handle_event` logs only | Full request correlation + multi-client routing | +| Gateway | None | `NostrMCPGateway` (bidirectional bridge) | +| Proxy | None | `NostrMCPProxy` (bidirectional bridge) | +| Announcements | `announce` + `publish_tools` | All 5 kinds + deletion + discovery | +| Authorization | None | Pubkey whitelist with capability exclusions | +| Encryption negotiation | Enum defined, not enforced | Full mode enforcement per TS SDK | +| Session management | Basic HashMap | Full session with pending requests, progress tokens, cleanup | +| Validation | None | Size + schema validation | +| nostr-sdk version | 0.43 | 0.43 (same) | + +## Key Differences from TS SDK + +| Aspect | TS SDK | Rust SDK | +|--------|--------|----------| +| MCP SDK dependency | `@modelcontextprotocol/sdk` | Own JSON-RPC types (no official Rust MCP SDK) | +| Relay abstraction | `RelayHandler` interface, multiple implementations | `RelayPool` using nostr-sdk Client | +| Async model | Callbacks (`onmessage`, `onerror`, `onclose`) | Callbacks + channels (tokio::mpsc for event streams) | +| Gift wrap | Manual NIP-44 + finalize | nostr-sdk built-in gift_wrap | +| Logging | Pino (JSON) | tracing (structured) | + +--- + +## Estimation + +| Phase | Effort | Dependencies | +|-------|--------|-------------| +| Phase 1: Core | ~4h | None | ✅ Done | +| Phase 2: Transport | ~8h | Phase 1 | ✅ Done | +| Phase 3: Gateway & Proxy | ~3h | Phase 2 | ✅ Done | +| Phase 4: Discovery | ~3h | Phase 2 | ✅ Done | +| Phase 5: Examples & Docs | ~2h | Phase 3+4 | ✅ Done | +| **Total** | **~20h** | | **Complete** | + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/DESIGN.md).* diff --git a/src/content/docs/reference/rs-sdk/discovery.md b/src/content/docs/reference/rs-sdk/discovery.md new file mode 100644 index 0000000..42aaf0a --- /dev/null +++ b/src/content/docs/reference/rs-sdk/discovery.md @@ -0,0 +1,94 @@ +--- +title: "Discovery" +description: "ContextVM Rust SDK documentation for Discovery" +--- + + +The Rust SDK exposes public discovery helpers for finding announced servers and their published capabilities. + +These functions query public announcement events so clients can find servers before opening a direct session. + +## What is discoverable + +The current implementation supports: + +- servers via `discover_servers()` +- tools via `discover_tools()` +- resources via `discover_resources()` +- prompts via `discover_prompts()` +- resource templates via `discover_resource_templates()` + +When the `rmcp` feature is enabled, typed variants are also available for tools, resources, prompts, and resource templates. + +## Minimal example + +This follows the repository discovery example. + +```rust +use contextvm_sdk::discovery; +use contextvm_sdk::relay::RelayPool; +use contextvm_sdk::signer; + +#[tokio::main] +async fn main() -> contextvm_sdk::Result<()> { + let keys = signer::generate(); + let relays = vec!["wss://relay.damus.io".to_string()]; + + let relay_pool = RelayPool::new(keys).await?; + relay_pool.connect(&relays).await?; + let client = relay_pool.client(); + + let servers = discovery::discover_servers(client, &relays).await?; + for server in &servers { + println!("server: {:?}", server.server_info.name); + + let tools = discovery::discover_tools(client, &server.pubkey_parsed, &relays).await?; + println!("tools: {}", tools.len()); + } + + relay_pool.disconnect().await?; + Ok(()) +} +``` + +## Discovery event model + +The event kinds follow the public announcement model summarized in the repository root README: + +- `11316`: server announcement +- `11317`: tools list +- `11318`: resources list +- `11319`: resource templates +- `11320`: prompts list + +These event kinds are the SDK's public discovery model for server metadata and advertised MCP capabilities. + +## CEP-17 automatic relay resolution + +Clients can discover which relays a server uses without hardcoding relay URLs. Set `server_pubkey` to an nprofile (which embeds relay hints) and leave `relay_urls` empty: + +```rust +NostrClientTransportConfig::default() + .with_server_pubkey("nprofile1...") // contains pubkey + relay hints +``` + +When `start()` is called with empty `relay_urls`, the transport runs a 6-stage resolution pipeline: + +1. **Configured relays** -- if `relay_urls` is non-empty, use them directly +2. **nprofile hints** -- relay URLs embedded in the nprofile identity +3. **CEP-17 discovery** -- fetch kind 10002 relay-list events from bootstrap relays +4. **Fallback probing** -- probe `fallback_operational_relay_urls` in parallel with discovery +5. **Sequential fallback** -- if the race winner returned empty, await the other +6. **Bootstrap default** -- fall back to `DEFAULT_BOOTSTRAP_RELAY_URLS` as last resort + +The `discovery_relay_urls` and `fallback_operational_relay_urls` config fields customize stages 3-4. + +## Important limitations + +- discovery is public metadata, not a replacement for direct transport negotiation +- the current helpers fetch and parse latest public lists, but they do not replace direct session learning +- direct session learning still matters for encryption preferences, gift-wrap support, and first-message capability hints on an active connection + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/discovery.md).* diff --git a/src/content/docs/reference/rs-sdk/encryption.md b/src/content/docs/reference/rs-sdk/encryption.md new file mode 100644 index 0000000..92baddb --- /dev/null +++ b/src/content/docs/reference/rs-sdk/encryption.md @@ -0,0 +1,84 @@ +--- +title: "Encryption" +description: "ContextVM Rust SDK documentation for Encryption" +--- + + +ContextVM encryption in this SDK is controlled by `EncryptionMode` and `GiftWrapMode`. + +At a high level, direct traffic can be sent as plaintext ContextVM events or as encrypted NIP-44 payloads wrapped in gift-wrap events, depending on the configured policy on both peers. + +## Encryption modes + +`EncryptionMode` has three modes: + +- `Optional`: accept both plaintext and encrypted traffic +- `Required`: require encrypted traffic +- `Disabled`: reject encrypted traffic and use plaintext only + +These semantics are not only conceptual; they are also exercised by the transport integration tests. + +## Gift-wrap modes + +`GiftWrapMode` controls which outer encrypted event kind is used: + +- `Optional`: accept both modes and default to persistent wrapping until ephemeral support is learned from the peer +- `Ephemeral`: use kind `21059` +- `Persistent`: use kind `1059` + +The helper methods `allows_kind()` and `supports_ephemeral()` show the expected policy behavior. + +## Practical rules + +### Plaintext transport + +Plaintext ContextVM messages use kind `25910` and keep the MCP JSON-RPC payload in the event content. + +### Encrypted transport + +Encrypted ContextVM messages: + +1. serialize the MCP payload to JSON +2. encrypt it with NIP-44 +3. wrap it as a gift-wrap event using kind `1059` or `21059` + +The implementation details live in the SDK encryption module. + +## Response mirroring + +One important implementation detail is that server responses mirror the client’s inbound encryption format when policy allows it. + +This behavior is verified by the transport integration tests and is important for interoperable mixed-mode deployments. + +## Deduplication + +Both client and server transports deduplicate encrypted outer gift-wrap event ids before delivering them. + +This is covered by the deduplication and encrypted transport integration tests. + +## Example configuration + +```rust +use contextvm_sdk::core::types::{EncryptionMode, GiftWrapMode}; +use contextvm_sdk::transport::client::NostrClientTransportConfig; + +let config = NostrClientTransportConfig::default() + .with_relay_urls(vec!["wss://relay.damus.io".to_string()]) + .with_server_pubkey("") + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional); +``` + +## Discovery tags + +Encryption support is also surfaced through discovery tags and first-message capability learning. + +In practice, this matters for: + +- public announcements +- the first direct server-to-client message +- stateless operation + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/encryption.md).* diff --git a/src/content/docs/reference/rs-sdk/gateway.md b/src/content/docs/reference/rs-sdk/gateway.md new file mode 100644 index 0000000..41b9606 --- /dev/null +++ b/src/content/docs/reference/rs-sdk/gateway.md @@ -0,0 +1,139 @@ +--- +title: "Gateway" +description: "ContextVM Rust SDK documentation for Gateway" +--- + + +`NostrMCPGateway` is the simplest way to expose an MCP server through ContextVM. + +It wraps `NostrServerTransport`, receives incoming ContextVM requests from Nostr, and lets your application send responses back using the inbound event id. + +For native Rust applications, this is usually not the primary path. Most users should build an `rmcp` server and attach `NostrServerTransport` directly, as described in [native server guide](/reference/rs-sdk/server-transport). + +## When to use it + +Use the gateway when: + +- you already have MCP request handling logic +- you want a straightforward server loop +- you want optional public announcements without building directly on the transport layer + +Do not start here if you are writing a new native Rust MCP server from scratch. + +## Minimal example + +This follows the shape of the repository gateway example. + +```rust +use contextvm_sdk::core::types::{ + JsonRpcError, JsonRpcErrorResponse, JsonRpcMessage, JsonRpcResponse, ServerInfo, +}; +use contextvm_sdk::gateway::{GatewayConfig, NostrMCPGateway}; +use contextvm_sdk::signer; +use contextvm_sdk::transport::server::NostrServerTransportConfig; + +#[tokio::main] +async fn main() -> contextvm_sdk::Result<()> { + let keys = signer::generate(); + + let nostr_config = NostrServerTransportConfig::default() + .with_relay_urls(vec!["wss://relay.damus.io".to_string()]) + .with_server_info( + ServerInfo::default() + .with_name("Echo Server".to_string()) + .with_about("A simple ContextVM server".to_string()), + ) + .with_announced_server(true); + + let config = GatewayConfig::new(nostr_config); + + let mut gateway = NostrMCPGateway::new(keys, config).await?; + let mut rx = gateway.start().await?; + gateway.announce().await?; + + while let Some(req) = rx.recv().await { + let response = match &req.message { + JsonRpcMessage::Request(request) if request.method == "tools/list" => { + JsonRpcMessage::Response(JsonRpcResponse { + jsonrpc: "2.0".to_string(), + id: request.id.clone(), + result: serde_json::json!({ + "tools": [{ + "name": "echo", + "description": "Echo a message", + "inputSchema": { + "type": "object", + "properties": { + "message": { "type": "string" } + }, + "required": ["message"] + } + }] + }), + }) + } + JsonRpcMessage::Request(request) => JsonRpcMessage::ErrorResponse(JsonRpcErrorResponse { + jsonrpc: "2.0".to_string(), + id: request.id.clone(), + error: JsonRpcError { + code: -32601, + message: "Method not found".to_string(), + data: None, + }, + }), + _ => continue, + }; + + gateway.send_response(&req.event_id, response).await?; + } + + Ok(()) +} +``` + +## What the gateway gives you + +- a message channel of `IncomingRequest` +- automatic routing of responses by original Nostr event id through `send_response()` +- optional public announcements through `announce()` + +## When not to use it + +Prefer the native server transport path when: + +- your application is already modeled as an `rmcp` `ServerHandler` +- you want the normal `rmcp` running service lifecycle through `ServiceExt` +- you want docs and examples that match the broader `rmcp` ecosystem + +## Important server config + +The main operational knobs live on `NostrServerTransportConfig`: + +- `relay_urls`: relays to connect to +- `encryption_mode`: plaintext vs encrypted session policy +- `gift_wrap_mode`: choose between persistent and ephemeral gift wraps +- `server_info`: metadata used in public announcements +- `is_announced_server`: auto-publish announcements on start (CEP-6) +- `allowed_public_keys`: static client allowlist +- `excluded_capabilities`: allow public access to specific methods or capability names +- `max_sessions`, `cleanup_interval`, `session_timeout`: server-side session lifecycle +- `relay_list_urls`: relay URLs advertised in kind 10002 (CEP-17); defaults to `relay_urls` +- `bootstrap_relay_urls`: additional relays for publishing announcements (CEP-6/17) +- `publish_relay_list`: whether to publish kind 10002 relay list metadata; default `true` +- `profile_metadata`: optional profile metadata for kind 0 publication (CEP-23) + +## Behavioral notes + +- responses are routed using the inbound request event id, not just the JSON-RPC id +- for announced servers, public metadata publication is part of the supported flow +- authorization and allowlist bypass behavior are also exercised by the integration tests + +## rmcp path + +If your server already uses `rmcp`, the gateway also exposes the associated function `NostrMCPGateway::serve_handler()` so you can attach a handler directly without manually running the request loop. + +That said, the preferred native architecture is still `rmcp` service first and ContextVM transport second. + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/gateway.md).* diff --git a/src/content/docs/reference/rs-sdk/overview.md b/src/content/docs/reference/rs-sdk/overview.md new file mode 100644 index 0000000..0a2af25 --- /dev/null +++ b/src/content/docs/reference/rs-sdk/overview.md @@ -0,0 +1,111 @@ +--- +title: "Rust SDK Overview" +description: "ContextVM Rust SDK documentation for Rust SDK Overview" +--- + + +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).* diff --git a/src/content/docs/reference/rs-sdk/proxy.md b/src/content/docs/reference/rs-sdk/proxy.md new file mode 100644 index 0000000..ce5cf0c --- /dev/null +++ b/src/content/docs/reference/rs-sdk/proxy.md @@ -0,0 +1,122 @@ +--- +title: "Proxy" +description: "ContextVM Rust SDK documentation for Proxy" +--- + + +`NostrMCPProxy` is the simplest way to talk to a remote ContextVM server from Rust. + +It wraps `NostrClientTransport`, gives you a receiver for responses and notifications, and handles transport startup and shutdown. + +For native Rust applications, this is usually not the primary path. Most users should build an `rmcp` client and attach `NostrClientTransport` directly, as described in the native client guide. + +## When to use it + +Use the proxy when: + +- you already know the target server pubkey +- you want a lightweight request/response flow +- you do not need low-level transport hooks + +Do not start here if you are writing a new native Rust MCP client from scratch. + +## Loading an existing private key + +Like the native client transport, the proxy can reuse an existing Nostr identity instead of generating a new one. Load the signer with `from_sk()`: + +```rust +use contextvm_sdk::signer; + +let signer = signer::from_sk("")?; +``` + +Pass that signer to `NostrMCPProxy::new()` exactly as you would pass a freshly generated keypair. + +## Minimal example + +This follows the repository proxy example. + +```rust +use contextvm_sdk::core::types::{JsonRpcMessage, JsonRpcRequest}; +use contextvm_sdk::proxy::{NostrMCPProxy, ProxyConfig}; +use contextvm_sdk::signer; +use contextvm_sdk::transport::client::NostrClientTransportConfig; + +#[tokio::main] +async fn main() -> contextvm_sdk::Result<()> { + let keys = signer::from_sk("")?; + + let nostr_config = NostrClientTransportConfig::default() + .with_relay_urls(vec!["wss://relay.damus.io".to_string()]) + .with_server_pubkey(""); + + let config = ProxyConfig::new(nostr_config); + + let mut proxy = NostrMCPProxy::new(keys, config).await?; + let mut rx = proxy.start().await?; + + let request = JsonRpcMessage::Request(JsonRpcRequest { + jsonrpc: "2.0".to_string(), + id: serde_json::json!(1), + method: "tools/list".to_string(), + params: None, + }); + + proxy.send(&request).await?; + + if let Some(message) = rx.recv().await { + println!("{}", serde_json::to_string_pretty(&message)?); + } + + proxy.stop().await?; + Ok(()) +} +``` + +## Client config + +The main options live on `NostrClientTransportConfig`: + +- `relay_urls`: relays used for direct transport +- `server_pubkey`: target server identity in hex form +- `encryption_mode`: client encryption policy +- `gift_wrap_mode`: preferred gift-wrap kind policy +- `is_stateless`: emulate the initialize response locally +- `timeout`: pending request correlation retention + +## Stateless mode + +`is_stateless` is a major behavior switch. + +When enabled, the client can emulate initialize handling locally instead of waiting for a network roundtrip. This behavior is covered by the conformance tests. + +Use it when: + +- you want faster startup for short-lived clients +- you control the server behavior and know stateless operation is acceptable + +Avoid assuming that every server workflow depends only on stateless behavior. + +## Behavioral notes + +- responses are correlated at the transport level, not just by raw receive order +- the client learns peer capabilities from discovery tags on inbound messages +- encrypted traffic is deduplicated by outer gift-wrap event id before delivery + +## When not to use it + +Prefer the native client transport path when: + +- your application is already modeled as an `rmcp` `ClientHandler` +- you want the normal running-client workflow from `ServiceExt` +- you want examples that match the rest of the `rmcp` client ecosystem + +## rmcp path + +If you are building on `rmcp`, use the associated function `NostrMCPProxy::serve_client_handler()` instead of manually sending and receiving raw `JsonRpcMessage` values. + +That said, the preferred native architecture is still `rmcp` client first and ContextVM transport second. + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/proxy.md).* diff --git a/src/content/docs/reference/rs-sdk/rmcp.md b/src/content/docs/reference/rs-sdk/rmcp.md new file mode 100644 index 0000000..8d6fb6c --- /dev/null +++ b/src/content/docs/reference/rs-sdk/rmcp.md @@ -0,0 +1,52 @@ +--- +title: "RMCP Integration" +description: "ContextVM Rust SDK documentation for RMCP Integration" +--- + + +For native Rust applications, `rmcp` is the main application layer and ContextVM is the transport layer. + +The Rust SDK exposes that integration behind the `rmcp` feature and re-exports the `rmcp` crate when that feature is enabled. The bridge lives in the SDK's rmcp transport layer. + +## Recommended mental model + +Use `rmcp` to define your server or client behavior, then attach ContextVM transports. + +That mirrors the transport-agnostic `rmcp` model, especially `ServiceExt` and the standard `handler.serve(transport)` pattern. + +The native entry points in this SDK are therefore: + +- `NostrServerTransport` for servers +- `NostrClientTransport` for clients + +For that workflow, use the native server and native client guides in this directory. + +## Server-side integration + +Use the associated function `NostrMCPGateway::serve_handler()` to serve an `rmcp` server handler directly over ContextVM. + +## Client-side integration + +Use the associated function `NostrMCPProxy::serve_client_handler()` to connect an `rmcp` client handler through the ContextVM client worker. + +## Why this still exists as a separate page + +The base SDK does not require `rmcp`. The core message model is represented by `JsonRpcMessage` and related internal JSON-RPC types. + +That separation keeps the transport usable as a lower-level protocol layer, but most application authors will want the `rmcp` path. + +The gateway and proxy APIs are convenience layers on top of this broader model, not the primary architecture for native apps. + +## Behavioral confidence + +The conversion pipeline is covered by the SDK test suite, which tests: + +- JSON-RPC parsing into internal message types +- internal-to-rmcp conversion +- rmcp-to-internal conversion +- request id preservation through the bridge +- event-id based routing assumptions used by the server worker + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/rmcp.md).* diff --git a/src/content/docs/reference/rs-sdk/server-transport.md b/src/content/docs/reference/rs-sdk/server-transport.md new file mode 100644 index 0000000..6018768 --- /dev/null +++ b/src/content/docs/reference/rs-sdk/server-transport.md @@ -0,0 +1,186 @@ +--- +title: "Native Server Guide" +description: "ContextVM Rust SDK documentation for Native Server Guide" +--- + + +Use this path when you are building a native ContextVM server in Rust. + +The recommended architecture is: + +- define an `rmcp` server handler +- create a `NostrServerTransport` +- attach the transport to the handler with `rmcp`'s `ServiceExt` + +This is the same model used by the standard `rmcp` server examples, except the transport is Nostr instead of stdio. + +## The high-level shape + +In `rmcp`, a native server is normally started with `YourHandler.serve(transport)`. + +For ContextVM, the transport becomes `NostrServerTransport`. In the current SDK API, you pass that transport directly to `ServiceExt`; there is no extra adapter step in the public workflow. + +## Loading an existing private key + +If the server should run under a stable Nostr identity, load the signer from an existing private key with `from_sk()`: + +```rust +use contextvm_sdk::signer; + +let signer = signer::from_sk("")?; +println!("server pubkey: {}", signer.public_key().to_hex()); +``` + +This is the right choice for long-lived servers, announced servers, and deployments where clients must recognize the same public key across restarts. + +## Example + +```rust +use contextvm_sdk::transport::server::{ + NostrServerTransport, NostrServerTransportConfig, +}; +use contextvm_sdk::{signer, EncryptionMode, GiftWrapMode, ServerInfo}; +use rmcp::{ + ServerHandler, ServiceExt, + handler::server::{router::tool::ToolRouter, wrapper::Parameters}, + model::*, + schemars, tool, tool_handler, tool_router, +}; + +const RELAY_URL: &str = "wss://relay.contextvm.org"; + +#[derive(Clone)] +struct DemoServer { + tool_router: ToolRouter, +} + +impl DemoServer { + fn new() -> Self { + Self { + tool_router: Self::tool_router(), + } + } +} + +#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] +struct EchoParams { + message: String, +} + +#[tool_router] +impl DemoServer { + #[tool(description = "Echo a message back unchanged")] + async fn echo( + &self, + Parameters(EchoParams { message }): Parameters, + ) -> Result { + Ok(CallToolResult::success(vec![Content::text(format!( + "Echo: {message}" + ))])) + } +} + +#[tool_handler] +impl ServerHandler for DemoServer { + fn get_info(&self) -> rmcp::model::ServerInfo { + rmcp::model::ServerInfo { + protocol_version: ProtocolVersion::LATEST, + capabilities: ServerCapabilities::builder().enable_tools().build(), + server_info: Implementation { + name: "contextvm-native-echo".to_string(), + title: Some("ContextVM Native Echo Server".to_string()), + version: "0.1.0".to_string(), + description: Some("Native rmcp echo server over ContextVM/Nostr".to_string()), + icons: None, + website_url: None, + }, + instructions: Some("Call the echo tool with a message string".to_string()), + } + } +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::from_default_env() + .add_directive("contextvm_sdk=info".parse()?) + .add_directive("rmcp=warn".parse()?), + ) + .init(); + + let signer = signer::generate(); + let pubkey = signer.public_key().to_hex(); + + println!("Native ContextVM echo server starting"); + println!("Relay: {RELAY_URL}"); + println!("Server pubkey: {pubkey}"); + + let transport = NostrServerTransport::new( + signer, + NostrServerTransportConfig::default() + .with_relay_urls(vec![RELAY_URL.to_string()]) + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional) + .with_announced_server(false) + .with_server_info( + ServerInfo::default() + .with_name("contextvm-native-echo".to_string()) + .with_about("Native rmcp echo server example".to_string()), + ), + ) + .await?; + + let service = DemoServer::new().serve(transport).await?; + println!("Server ready. Press Ctrl+C to stop."); + service.waiting().await?; + Ok(()) +} +``` + +This follows the same flow as the repository's native echo server example. + +## What the transport adds + +`NostrServerTransport` is not just a byte stream adapter. It adds ContextVM-specific behavior on top of `rmcp` server semantics: + +- Nostr relay connectivity via `NostrServerTransport::new()` +- public announcements via `announce()` +- publication of tools, resources, prompts, and resource templates +- client authorization via `allowed_public_keys` in `NostrServerTransportConfig` +- capability exclusions via `CapabilityExclusion` +- encryption negotiation and response mirroring via `send_response()` +- session management and request routing inside the server event loop + +## Configuration fields that matter first + +Start with these fields in `NostrServerTransportConfig`: + +- `relay_urls`: relays the server will publish to and listen on +- `is_announced_server`: whether the server should participate in public discovery +- `encryption_mode`: plaintext vs encrypted policy +- `gift_wrap_mode`: persistent vs ephemeral wrapping policy +- `allowed_public_keys`: allowlist for private or restricted servers +- `excluded_capabilities`: allow specific methods without fully opening the server +- `relay_list_urls`: relay URLs advertised in kind 10002 (CEP-17); defaults to `relay_urls` +- `bootstrap_relay_urls`: additional relays for publishing announcements (CEP-6/17); merged with `relay_list_urls` +- `publish_relay_list`: whether to publish kind 10002 relay list metadata; default `true` +- `profile_metadata`: optional profile metadata for kind 0 publication (CEP-23) + +## When to use this instead of the gateway + +Use this page's approach when you are writing a new Rust MCP server. + +Use the gateway guide when you already have a request loop or existing local MCP service abstraction and want a thinner bridge. + +## Behavioral notes + +- The `rmcp` server handshake follows `ServiceExt::serve()` on the server handler. +- `rmcp` accepts pre-init ping and enters the main loop immediately after initialization completes. +- ContextVM response routing depends on request event ids. +- Encryption mirroring and announcement behavior are covered by the integration tests. +- When `is_announced_server` is `true`, the transport auto-publishes all announcement events on `start()` via synthetic MCP requests: kind 11316 (server announcement), kinds 11317-11320 (tools, resources, templates, prompts), kind 10002 (relay list), and kind 0 (profile metadata if configured). + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/server-transport.md).* diff --git a/src/content/docs/reference/rs-sdk/stateless.md b/src/content/docs/reference/rs-sdk/stateless.md new file mode 100644 index 0000000..79f036a --- /dev/null +++ b/src/content/docs/reference/rs-sdk/stateless.md @@ -0,0 +1,110 @@ +--- +title: "Stateless Mode" +description: "ContextVM Rust SDK documentation for Stateless Mode" +--- + + +Stateless mode is a client-side transport behavior enabled through `NostrClientTransportConfig::with_stateless()`. + +It is designed for flows where the client should behave as if initialization succeeded without waiting for the server to answer over the network. + +## What stateless mode actually does + +When `is_stateless` is enabled on `NostrClientTransportConfig`, the client transport intercepts two parts of the normal MCP startup sequence inside `NostrClientTransport::send()`: + +- an outgoing `initialize` request +- an outgoing `notifications/initialized` notification + +For the `initialize` request, the transport locally emulates a successful initialize response instead of publishing the request to the relay network. + +For the `notifications/initialized` notification, the transport simply swallows the notification and does not send it over the network. + +## What does not change + +Stateless mode does not make the whole transport local-only. + +After initialization is emulated, normal requests are still serialized and sent through Nostr. + +That means stateless mode changes startup semantics, not the rest of the request/response transport model. + +## When to use it + +Use stateless mode when: + +- you want faster startup for short-lived clients +- you control both sides and do not need a server-provided initialize payload +- you are using the proxy or native client flow mainly for direct tool calls after startup + +Avoid it when: + +- you need the server's real initialize response +- your workflow depends on server-specific initialize metadata +- you want startup behavior to strictly follow the network exchange + +## Example + +```rust +use contextvm_sdk::transport::client::{ + NostrClientTransport, NostrClientTransportConfig, +}; +use contextvm_sdk::{signer, EncryptionMode, GiftWrapMode}; +use rmcp::{ClientHandler, ServiceExt}; + +#[derive(Clone, Default)] +struct DemoClient; + +impl ClientHandler for DemoClient {} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let signer = signer::generate(); + + let transport = NostrClientTransport::new( + signer, + NostrClientTransportConfig::default() + .with_relay_urls(vec!["wss://relay.contextvm.org".to_string()]) + .with_server_pubkey("") + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional) + .with_stateless(true), + ) + .await?; + + let client = DemoClient.serve(transport).await?; + + // Initialize completed locally; subsequent requests still go over Nostr. + let tools = client.list_all_tools().await?; + println!("Discovered {} tool(s)", tools.len()); + + client.cancel().await?; + Ok(()) +} +``` + +## Emulated initialize shape + +The emulated initialize response includes: + +- `protocolVersion` +- `serverInfo` +- `capabilities` + +This is verified by the transport tests in the repository. + +The placeholder `serverInfo.name` used by the emulated response is currently `Emulated-Stateless-Server`. + +## Relationship to discovery and learned capabilities + +Stateless mode does not disable peer capability learning. + +The client still advertises its own capabilities through discovery tags, and it still learns server capabilities from inbound tags later in the session. + +So even in stateless mode, encryption and ephemeral gift-wrap support can still be learned from later inbound traffic. + +## Practical limitation + +Because the initialize roundtrip is skipped, stateless mode should be treated as an optimization for compatible workflows, not as a universal replacement for normal MCP startup. + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/stateless.md).* diff --git a/src/content/docs/reference/rs-sdk/transport-modes.md b/src/content/docs/reference/rs-sdk/transport-modes.md new file mode 100644 index 0000000..7e32d98 --- /dev/null +++ b/src/content/docs/reference/rs-sdk/transport-modes.md @@ -0,0 +1,124 @@ +--- +title: "Transport Modes" +description: "ContextVM Rust SDK documentation for Transport Modes" +--- + + +This page focuses on the transport behavior switches that are spread across the SDK APIs: + +- `EncryptionMode` +- `GiftWrapMode` +- stateless mode via `NostrClientTransportConfig::with_stateless()` + +The existing guides mention these knobs in context. This page collects them into one operational reference. + +## Encryption modes + +`EncryptionMode` controls whether the transport accepts or emits plaintext vs encrypted direct traffic. + +The three modes are: + +- `Optional`: mirror mode; encrypted traffic is allowed and plaintext is also allowed +- `Required`: reject plaintext direct traffic and require encrypted direct traffic +- `Disabled`: reject encrypted direct traffic and use plaintext only + +The exact enforcement is implemented in the client and server transport layers. + +### What `Optional` really means + +`Optional` does not mean "always plaintext is fine" or "always encrypt everything". + +At the base transport level, the outgoing encryption choice for direct traffic is mirror-oriented: + +- `EncryptionMode::Required` always encrypts direct traffic +- `EncryptionMode::Disabled` never encrypts direct traffic +- `EncryptionMode::Optional` uses the known encryption state of the peer interaction when available + +## Gift-wrap modes + +`GiftWrapMode` only matters when traffic is encrypted. + +The three modes are: + +- `Optional`: accept both persistent and ephemeral gift wraps; prefer persistent until ephemeral support is known +- `Ephemeral`: require kind `21059` +- `Persistent`: require kind `1059` + +The acceptance rules are defined by `GiftWrapMode::allows_kind()`, and whether a mode can advertise or choose ephemeral wrapping is defined by `GiftWrapMode::supports_ephemeral()`. + +### Client outbound behavior + +Client selection follows this behavior: + +- `Persistent` always uses persistent gift wrap +- `Ephemeral` always uses ephemeral gift wrap +- `Optional` uses persistent first, then switches to ephemeral once peer support is learned + +### Server outbound behavior + +Server response and notification selection follow the current transport implementation. + +Important server rules: + +- if a correlated encrypted request used a valid wrap kind, the server mirrors it when possible +- for notifications, learned client support for ephemeral gift wrap can change the fallback behavior +- `Optional` still falls back to persistent when no stronger signal exists + +## Stateless mode + +Stateless mode is client-only and is controlled by `NostrClientTransportConfig::with_stateless()`. + +It changes initialization behavior only: + +- outgoing `initialize` is emulated locally +- outgoing `notifications/initialized` is suppressed +- later requests still go through the normal Nostr transport path + +See the dedicated stateless mode guide in the Rust SDK reference section. + +## Capability tags and mode signaling + +Mode choices affect discovery and capability tags. + +### Client-side signaling + +Client tags follow this behavior: + +- if encryption is not disabled, the client advertises encryption support +- if gift-wrap mode is not persistent, the client also advertises ephemeral gift-wrap support + +### Server-side signaling + +Server announcement tags follow this behavior: + +- if encryption is not disabled, the server advertises encryption support +- if gift-wrap mode supports ephemeral wrapping, the server also advertises ephemeral support + +This is why `GiftWrapMode::Optional` and `GiftWrapMode::Ephemeral` both advertise ephemeral support, while `GiftWrapMode::Persistent` does not. + +## Example configurations + +```rust +use contextvm_sdk::{EncryptionMode, GiftWrapMode}; +use contextvm_sdk::transport::client::NostrClientTransportConfig; + +let interoperable = NostrClientTransportConfig::default() + .with_server_pubkey("") + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional); + +let strict_encrypted = NostrClientTransportConfig::default() + .with_server_pubkey("") + .with_encryption_mode(EncryptionMode::Required) + .with_gift_wrap_mode(GiftWrapMode::Persistent); + +let stateless_client = NostrClientTransportConfig::default() + .with_server_pubkey("") + .with_encryption_mode(EncryptionMode::Optional) + .with_gift_wrap_mode(GiftWrapMode::Optional) + .with_stateless(true); +``` + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transport-modes.md).* diff --git a/src/content/docs/reference/rs-sdk/transports.md b/src/content/docs/reference/rs-sdk/transports.md new file mode 100644 index 0000000..7dba6bc --- /dev/null +++ b/src/content/docs/reference/rs-sdk/transports.md @@ -0,0 +1,145 @@ +--- +title: "Transports (Low-Level)" +description: "ContextVM Rust SDK documentation for Transports (Low-Level)" +--- + + +Use this page when you want to understand the transport layer itself. + +If you are building a normal native server or client, start with the dedicated native server or native client guide first. + +- `NostrClientTransport`: client-side direct transport +- `NostrServerTransport`: server-side direct transport + +## Why use the transport layer directly + +Use transports directly when you need to: + +- integrate with your own request loop +- control announcement timing yourself +- tune authorization and session behavior +- embed the transport in higher-level abstractions + +## Signer choice + +All transport constructors accept an existing signer, not just a newly generated one. + +- Use `generate()` for temporary identities in examples, tests, and short-lived sessions. +- Use `from_sk()` when you need a stable identity backed by a pre-existing hex or `nsec` private key. + +```rust +use contextvm_sdk::signer; + +let signer = signer::from_sk("")?; +``` + +## Low-level client transport example + +```rust +use contextvm_sdk::core::types::{JsonRpcMessage, JsonRpcRequest}; +use contextvm_sdk::signer; +use contextvm_sdk::transport::client::{ + NostrClientTransport, NostrClientTransportConfig, +}; + +#[tokio::main] +async fn main() -> contextvm_sdk::Result<()> { + let keys = signer::generate(); + let mut transport = NostrClientTransport::new( + keys, + NostrClientTransportConfig::default() + .with_relay_urls(vec!["wss://relay.damus.io".to_string()]) + .with_server_pubkey(""), + ) + .await?; + + transport.start().await?; + let mut rx = transport.take_message_receiver().expect("receiver available"); + + transport + .send(&JsonRpcMessage::Request(JsonRpcRequest { + jsonrpc: "2.0".to_string(), + id: serde_json::json!(1), + method: "tools/list".to_string(), + params: None, + })) + .await?; + + if let Some(message) = rx.recv().await { + println!("received: {:?}", message); + } + + transport.close().await?; + Ok(()) +} +``` + +## Low-level server transport example + +```rust +use contextvm_sdk::core::types::{JsonRpcMessage, JsonRpcResponse}; +use contextvm_sdk::signer; +use contextvm_sdk::transport::server::{ + NostrServerTransport, NostrServerTransportConfig, +}; + +#[tokio::main] +async fn main() -> contextvm_sdk::Result<()> { + let keys = signer::generate(); + let mut transport = NostrServerTransport::new( + keys, + NostrServerTransportConfig::default().with_announced_server(true), + ) + .await?; + + transport.start().await?; + let mut rx = transport.take_message_receiver().expect("receiver available"); + + while let Some(req) = rx.recv().await { + if let Some(id) = req.message.id() { + transport + .send_response( + &req.event_id, + JsonRpcMessage::Response(JsonRpcResponse { + jsonrpc: "2.0".to_string(), + id: id.clone(), + result: serde_json::json!({"ok": true}), + }), + ) + .await?; + } + } + + Ok(()) +} +``` + +## Server-side semantics to understand + +The server transport does more than relay bytes. + +It manages: + +- multi-client session state +- request route storage +- authorization via `allowed_public_keys` +- allowlist bypasses via `CapabilityExclusion` +- announcement publication +- encryption negotiation and response mirroring + +Those behaviors are part of the server transport implementation and are exercised heavily by the integration tests. + +## What the server receives + +Incoming traffic is delivered as `IncomingRequest`, which includes: + +- the parsed `JsonRpcMessage` +- the client pubkey +- the original Nostr request event id +- whether the incoming message was encrypted + +That extra metadata is what allows correct response routing and encryption mirroring. + + +--- +*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transports.md).* From bdd734caf8d8d141b405fd0cad5d597706fff8e2 Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:46:44 +0530 Subject: [PATCH 06/11] docs: rewrite sidebar, update landing page and cross-references --- astro.config.mjs | 250 +++++++----------- .../docs/getting-started/quick-overview.md | 16 +- src/content/docs/how-to/cvmi/commands.md | 2 +- src/content/docs/how-to/cvmi/installation.md | 4 +- src/content/docs/how-to/cvmi/overview.md | 6 +- src/content/docs/how-to/cvmi/skills/.gitkeep | 0 .../docs/how-to/payments/rails/.gitkeep | 0 src/content/docs/index.mdx | 23 +- src/content/docs/reference/ceps/cep-15.md | 2 +- src/content/docs/reference/ceps/cep-17.md | 2 +- src/content/docs/reference/ceps/cep-19.md | 6 +- src/content/docs/reference/ceps/cep-22.md | 2 +- src/content/docs/reference/ceps/cep-23.md | 2 +- src/content/docs/reference/ceps/cep-24.md | 2 +- src/content/docs/reference/ceps/cep-4.md | 2 +- src/content/docs/reference/ceps/cep-41.md | 8 +- src/content/docs/reference/ceps/cep-6.md | 8 +- src/content/docs/reference/ceps/cep-8.md | 16 +- .../reference/ceps/informational/.gitkeep | 0 .../reference/ceps/informational/cep-21.md | 4 +- .../reference/ceps/informational/cep-35.md | 18 +- src/content/docs/reference/spec/.gitkeep | 0 .../docs/reference/spec/ctxvm-draft-spec.md | 4 +- .../docs/reference/ts-sdk/core/.gitkeep | 0 .../ts-sdk/core/common-tool-schemas.md | 6 +- .../docs/reference/ts-sdk/gateway/.gitkeep | 0 .../docs/reference/ts-sdk/payments/.gitkeep | 0 .../reference/ts-sdk/payments/overview.md | 4 +- .../docs/reference/ts-sdk/proxy/.gitkeep | 0 .../docs/reference/ts-sdk/proxy/overview.md | 2 +- .../docs/reference/ts-sdk/quick-overview.md | 32 +-- .../docs/reference/ts-sdk/relay/.gitkeep | 0 .../docs/reference/ts-sdk/signer/.gitkeep | 0 .../docs/reference/ts-sdk/transports/.gitkeep | 0 .../ts-sdk/transports/base-nostr-transport.md | 2 +- .../transports/nostr-client-transport.md | 4 +- .../transports/nostr-server-transport.md | 4 +- .../ts-sdk/transports/open-stream.md | 18 +- .../ts-sdk/transports/oversized-transfer.md | 16 +- src/content/docs/tutorials/.gitkeep | 0 40 files changed, 211 insertions(+), 254 deletions(-) delete mode 100644 src/content/docs/how-to/cvmi/skills/.gitkeep delete mode 100644 src/content/docs/how-to/payments/rails/.gitkeep delete mode 100644 src/content/docs/reference/ceps/informational/.gitkeep delete mode 100644 src/content/docs/reference/spec/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/core/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/gateway/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/payments/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/proxy/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/relay/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/signer/.gitkeep delete mode 100644 src/content/docs/reference/ts-sdk/transports/.gitkeep delete mode 100644 src/content/docs/tutorials/.gitkeep diff --git a/astro.config.mjs b/astro.config.mjs index c5bfdaf..a0cf73c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -45,201 +45,151 @@ export default defineConfig({ ], }, { - label: 'Specification', + label: 'Reference', items: [ - { label: 'Specification', slug: 'spec/ctxvm-draft-spec' }, - { label: 'CEP - Guidelines', slug: 'spec/cep-guidelines' }, { - label: 'CEPs', + label: 'Specification', items: [ - { label: 'CEP-4: Encryption Support', slug: 'spec/ceps/cep-4' }, - { - label: 'CEP-6: Public Server Announcements', - slug: 'spec/ceps/cep-6', - }, - { - label: 'CEP-8: Capability Pricing and Payment Flow', - slug: 'spec/ceps/cep-8', - }, - { - label: 'CEP-15: Common Tool Schemas', - slug: 'spec/ceps/cep-15', - }, - { - label: 'CEP-17: Server Relay List Metadata', - slug: 'spec/ceps/cep-17', - }, - { - label: 'CEP-19: Ephemeral Gift Wraps', - slug: 'spec/ceps/cep-19', - }, - { - label: 'CEP-22: Oversized Payload Transfer', - slug: 'spec/ceps/cep-22', - }, - { - label: - 'CEP-23: Server Profile Metadata and Social Communications', - slug: 'spec/ceps/cep-23', - }, - { - label: 'CEP-24: Server Reviews', - slug: 'spec/ceps/cep-24', - }, - { - label: 'CEP-41: Open-Ended Stream Transfer', - slug: 'spec/ceps/cep-41', - }, - { - label: 'Informational', - items: [ - { - label: 'CEP-16: Client Public Key Injection', - slug: 'spec/ceps/informational/cep-16', - }, - { - label: - 'CEP-21: Payment Method Identifier (PMI) Recommendations', - slug: 'spec/ceps/informational/cep-21', - }, - { - label: - 'CEP-35: Stateless Session Discovery and Capability Learning', - slug: 'spec/ceps/informational/cep-35', - }, - ], - }, + { label: 'Specification', slug: 'reference/spec/ctxvm-draft-spec' }, + { label: 'CEP - Guidelines', slug: 'reference/spec/cep-guidelines' }, ], }, - ], - }, - { - label: 'TypeScript SDK', - items: [ - { label: 'Quick Overview', slug: 'ts-sdk/quick-overview' }, { - label: 'Core Concepts', - items: [ - { label: 'Constants', slug: 'ts-sdk/core/constants' }, - { label: 'Interfaces', slug: 'ts-sdk/core/interfaces' }, - { label: 'Logging', slug: 'ts-sdk/core/logging' }, - { - label: 'Relay handler', - slug: 'ts-sdk/relay/relay-handler-interface', - }, - { - label: 'Nostr signer', - slug: 'ts-sdk/signer/nostr-signer-interface', - }, - { label: 'Encryption', slug: 'ts-sdk/core/encryption' }, - { - label: 'Common Tool Schemas', - slug: 'ts-sdk/core/common-tool-schemas', - }, - ], - }, - { - label: 'Transports', + label: 'CEPs', items: [ + { label: 'CEP-4: Encryption Support', slug: 'reference/ceps/cep-4' }, + { label: 'CEP-6: Public Server Announcements', slug: 'reference/ceps/cep-6' }, + { label: 'CEP-8: Capability Pricing and Payment Flow', slug: 'reference/ceps/cep-8' }, + { label: 'CEP-15: Common Tool Schemas', slug: 'reference/ceps/cep-15' }, + { label: 'CEP-17: Server Relay List Metadata', slug: 'reference/ceps/cep-17' }, + { label: 'CEP-19: Ephemeral Gift Wraps', slug: 'reference/ceps/cep-19' }, + { label: 'CEP-22: Oversized Payload Transfer', slug: 'reference/ceps/cep-22' }, + { label: 'CEP-23: Server Profile Metadata and Social Communications', slug: 'reference/ceps/cep-23' }, + { label: 'CEP-24: Server Reviews', slug: 'reference/ceps/cep-24' }, + { label: 'CEP-41: Open-Ended Streams', slug: 'reference/ceps/cep-41' }, { - label: 'Base Nostr Transport', - slug: 'ts-sdk/transports/base-nostr-transport', - }, - { - label: 'Nostr Client Transport', - slug: 'ts-sdk/transports/nostr-client-transport', - }, - { - label: 'Nostr Server Transport', - slug: 'ts-sdk/transports/nostr-server-transport', - }, - { - label: 'Oversized Transfer', - slug: 'ts-sdk/transports/oversized-transfer', - }, - { - label: 'Open Stream', - slug: 'ts-sdk/transports/open-stream', + label: 'Informational', + items: [ + { label: 'CEP-16: Client Public Key Injection', slug: 'reference/ceps/informational/cep-16' }, + { label: 'CEP-21: PMI Recommendations', slug: 'reference/ceps/informational/cep-21' }, + { label: 'CEP-35: Stateless Session Discovery', slug: 'reference/ceps/informational/cep-35' }, + ], }, ], }, { - label: 'Components', + label: 'TypeScript SDK', items: [ + { label: 'Quick Overview', slug: 'reference/ts-sdk/quick-overview' }, { - label: 'Relay Handlers', + label: 'Core Concepts', items: [ - { - label: 'Applesauce Relay Pool', - slug: 'ts-sdk/relay/applesauce-relay-pool', - }, - { - label: 'Custom Relay Handler Development', - slug: 'ts-sdk/relay/custom-relay-handler', - }, + { label: 'Constants', slug: 'reference/ts-sdk/core/constants' }, + { label: 'Interfaces', slug: 'reference/ts-sdk/core/interfaces' }, + { label: 'Logging', slug: 'reference/ts-sdk/core/logging' }, + { label: 'Relay Handler', slug: 'reference/ts-sdk/relay/relay-handler-interface' }, + { label: 'Nostr Signer', slug: 'reference/ts-sdk/signer/nostr-signer-interface' }, + { label: 'Encryption', slug: 'reference/ts-sdk/core/encryption' }, + { label: 'Common Tool Schemas', slug: 'reference/ts-sdk/core/common-tool-schemas' }, ], }, { - label: 'Signers', + label: 'Transports', items: [ - { - label: 'Private Key Signer', - slug: 'ts-sdk/signer/private-key-signer', - }, - { - label: 'Custom Signer Development', - slug: 'ts-sdk/signer/custom-signer-development', - }, + { label: 'Base Nostr Transport', slug: 'reference/ts-sdk/transports/base-nostr-transport' }, + { label: 'Nostr Client Transport', slug: 'reference/ts-sdk/transports/nostr-client-transport' }, + { label: 'Nostr Server Transport', slug: 'reference/ts-sdk/transports/nostr-server-transport' }, + { label: 'Oversized Transfer', slug: 'reference/ts-sdk/transports/oversized-transfer' }, + { label: 'Open Stream', slug: 'reference/ts-sdk/transports/open-stream' }, ], }, - { label: 'Gateway', slug: 'ts-sdk/gateway/overview' }, - { label: 'Proxy', slug: 'ts-sdk/proxy/overview' }, { - label: 'Payments', + label: 'Components', items: [ - { label: 'Overview', slug: 'ts-sdk/payments/overview' }, { - label: 'Getting Started', - slug: 'ts-sdk/payments/getting-started', + label: 'Relay Handlers', + items: [ + { label: 'Applesauce Relay Pool', slug: 'reference/ts-sdk/relay/applesauce-relay-pool' }, + { label: 'Custom Relay Handler', slug: 'reference/ts-sdk/relay/custom-relay-handler' }, + ], }, - { label: 'Server', slug: 'ts-sdk/payments/server' }, - { label: 'Client', slug: 'ts-sdk/payments/client' }, { - label: 'Rails', + label: 'Signers', items: [ - { - label: 'Lightning over NWC', - slug: 'ts-sdk/payments/rails/lightning-nwc', - }, + { label: 'Private Key Signer', slug: 'reference/ts-sdk/signer/private-key-signer' }, + { label: 'Custom Signer Development', slug: 'reference/ts-sdk/signer/custom-signer-development' }, ], }, + { label: 'Gateway', slug: 'reference/ts-sdk/gateway/overview' }, + { label: 'Proxy', slug: 'reference/ts-sdk/proxy/overview' }, { - label: 'Build Your Own Rail', - slug: 'ts-sdk/payments/custom-rails', + label: 'Payments', + items: [ + { label: 'Overview', slug: 'reference/ts-sdk/payments/overview' }, + ], }, ], }, ], }, { - label: 'Tutorials', + label: 'Rust SDK', items: [ + { label: 'Overview', slug: 'reference/rs-sdk/overview' }, + { label: 'Native Server Guide', slug: 'reference/rs-sdk/server-transport' }, + { label: 'Native Client Guide', slug: 'reference/rs-sdk/client-transport' }, + { label: 'Gateway', slug: 'reference/rs-sdk/gateway' }, + { label: 'Proxy', slug: 'reference/rs-sdk/proxy' }, + { label: 'Discovery', slug: 'reference/rs-sdk/discovery' }, + { label: 'Encryption', slug: 'reference/rs-sdk/encryption' }, + { label: 'Transport Modes', slug: 'reference/rs-sdk/transport-modes' }, + { label: 'Transports (Low-Level)', slug: 'reference/rs-sdk/transports' }, + { label: 'Stateless Mode', slug: 'reference/rs-sdk/stateless' }, + { label: 'RMCP Integration', slug: 'reference/rs-sdk/rmcp' }, + { + label: 'Design', + items: [ + { label: 'Architecture & Design', slug: 'reference/rs-sdk/design' }, + ], + }, + ], + }, + ], + }, + { + label: 'How-to', + items: [ + { + label: 'CVMI CLI', + items: [ + { label: 'Overview', slug: 'how-to/cvmi/overview' }, + { label: 'Installation', slug: 'how-to/cvmi/installation' }, + { label: 'Commands', slug: 'how-to/cvmi/commands' }, + { label: 'Configuration', slug: 'how-to/cvmi/configuration' }, + { label: 'Skills Overview', slug: 'how-to/cvmi/skills/overview' }, + ], + }, + { + label: 'Payments', + items: [ + { label: 'Getting Started', slug: 'how-to/payments/getting-started' }, + { label: 'Server', slug: 'how-to/payments/server' }, + { label: 'Client', slug: 'how-to/payments/client' }, { - label: 'Client-Server Communication', - slug: 'ts-sdk/tutorials/client-server-communication', + label: 'Rails', + items: [ + { label: 'Lightning over NWC', slug: 'how-to/payments/rails/lightning-nwc' }, + ], }, + { label: 'Build Your Own Rail', slug: 'how-to/payments/custom-rails' }, ], }, ], }, { - label: 'CVMI (CLI Tool)', + label: 'Tutorials', items: [ - { label: 'Overview', slug: 'cvmi/overview' }, - { label: 'Installation', slug: 'cvmi/installation' }, - { label: 'Commands', slug: 'cvmi/commands' }, - { label: 'Configuration', slug: 'cvmi/configuration' }, - { label: 'Skills Overview', slug: 'cvmi/skills/overview' }, + { label: 'Client-Server Communication', slug: 'tutorials/client-server-communication' }, ], }, ], diff --git a/src/content/docs/getting-started/quick-overview.md b/src/content/docs/getting-started/quick-overview.md index e015c53..6688cf4 100644 --- a/src/content/docs/getting-started/quick-overview.md +++ b/src/content/docs/getting-started/quick-overview.md @@ -15,14 +15,14 @@ Our documentation is organized into several main sections: ### 📋 Specification -- **[Specification](/spec/ctxvm-draft-spec)**: The official ContextVM draft specification detailing the protocol -- **[CEP - Guidelines](/spec/cep-guidelines)**: ContextVM Enhancement Proposal guidelines for contributing to the protocol +- **[Specification](/reference/spec/ctxvm-draft-spec)**: The official ContextVM draft specification detailing the protocol +- **[CEP - Guidelines](/reference/spec/cep-guidelines)**: ContextVM Enhancement Proposal guidelines for contributing to the protocol ### 🛠️ ts-SDK The TypeScript SDK provides tools and libraries for building applications with ContextVM: -- **[SDK Quick Overview](/ts-sdk/quick-overview)**: A comprehensive overview of the SDK's modules and core concepts +- **[SDK Quick Overview](/reference/ts-sdk/quick-overview)**: A comprehensive overview of the SDK's modules and core concepts - **Core Concepts**: Fundamental definitions, constants, interfaces, and utilities - **Transports**: Communication modules for MCP over Nostr - **Components**: Gateway, Relay Handlers, Signers, and Proxy implementations @@ -40,16 +40,16 @@ ContextVM is a protocol that bridges the Model Context Protocol (MCP) with the N ## Getting Started -1. **Read the Specification**: Start with the [ContextVM specification](/spec/ctxvm-draft-spec) to understand the protocol -2. **Explore the SDK**: Check out the [SDK Quick Overview](/ts-sdk/quick-overview) for development guidance +1. **Read the Specification**: Start with the [ContextVM specification](/reference/spec/ctxvm-draft-spec) to understand the protocol +2. **Explore the SDK**: Check out the [SDK Quick Overview](/reference/ts-sdk/quick-overview) for development guidance 3. **Follow Tutorials**: Work through practical examples to see ContextVM in action ## Next Steps Choose your path based on your interests: -- **Protocol Development**: Dive into the [Specification](/spec/ctxvm-draft-spec) to understand the protocol details -- **SDK Development**: Start with the [SDK Quick Overview](/ts-sdk/quick-overview) to begin building with ContextVM -- **Contributing**: Learn about contributing to the protocol with [CEP Guidelines](/spec/cep-guidelines) +- **Protocol Development**: Dive into the [Specification](/reference/spec/ctxvm-draft-spec) to understand the protocol details +- **SDK Development**: Start with the [SDK Quick Overview](/reference/ts-sdk/quick-overview) to begin building with ContextVM +- **Contributing**: Learn about contributing to the protocol with [CEP Guidelines](/reference/spec/cep-guidelines) For the latest updates and community discussions, visit our [GitHub repository](https://github.com/contextvm/). diff --git a/src/content/docs/how-to/cvmi/commands.md b/src/content/docs/how-to/cvmi/commands.md index b0c4dac..243f2a3 100644 --- a/src/content/docs/how-to/cvmi/commands.md +++ b/src/content/docs/how-to/cvmi/commands.md @@ -278,4 +278,4 @@ All commands support these global options: ## Environment Variables -See the [Configuration](/cvmi/configuration) page for details on environment variables that affect command behavior. +See the [Configuration](/how-to/cvmi/configuration) page for details on environment variables that affect command behavior. diff --git a/src/content/docs/how-to/cvmi/installation.md b/src/content/docs/how-to/cvmi/installation.md index f610614..c33b30b 100644 --- a/src/content/docs/how-to/cvmi/installation.md +++ b/src/content/docs/how-to/cvmi/installation.md @@ -110,5 +110,5 @@ cvmi serve -- npx -y @modelcontextprotocol/server-filesystem /tmp Now that you have CVMI installed, explore: -- [Commands Reference](/cvmi/commands) - Learn about all available commands -- [Configuration](/cvmi/configuration) - Set up your environment and preferences +- [Commands Reference](/how-to/cvmi/commands) - Learn about all available commands +- [Configuration](/how-to/cvmi/configuration) - Set up your environment and preferences diff --git a/src/content/docs/how-to/cvmi/overview.md b/src/content/docs/how-to/cvmi/overview.md index b9362b1..f8009d7 100644 --- a/src/content/docs/how-to/cvmi/overview.md +++ b/src/content/docs/how-to/cvmi/overview.md @@ -89,6 +89,6 @@ Generate strongly typed TypeScript clients directly from a live ContextVM server ## Next Steps -- [Install CVMI](/cvmi/installation) - Get started with CVMI -- [Commands Reference](/cvmi/commands) - Learn about available commands -- [Configuration](/cvmi/configuration) - Configure CVMI for your needs +- [Install CVMI](/how-to/cvmi/installation) - Get started with CVMI +- [Commands Reference](/how-to/cvmi/commands) - Learn about available commands +- [Configuration](/how-to/cvmi/configuration) - Configure CVMI for your needs diff --git a/src/content/docs/how-to/cvmi/skills/.gitkeep b/src/content/docs/how-to/cvmi/skills/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/how-to/payments/rails/.gitkeep b/src/content/docs/how-to/payments/rails/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx index ae457d1..d375e0e 100644 --- a/src/content/docs/index.mdx +++ b/src/content/docs/index.mdx @@ -34,42 +34,49 @@ import HeroGetStartedCTAStyles from '../../components/HeroGetStartedCTAStyles.as + diff --git a/src/content/docs/reference/ceps/cep-15.md b/src/content/docs/reference/ceps/cep-15.md index 11433d5..ab9a320 100644 --- a/src/content/docs/reference/ceps/cep-15.md +++ b/src/content/docs/reference/ceps/cep-15.md @@ -495,7 +495,7 @@ Works identically across all providers implementing the same schema hash. ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) - [NIP-73: External Content IDs](https://github.com/nostr-protocol/nips/blob/master/73.md) - [RFC 8785: JSON Canonicalization Scheme (JCS)](https://tools.ietf.org/html/rfc8785) - [MCP Specification: Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) diff --git a/src/content/docs/reference/ceps/cep-17.md b/src/content/docs/reference/ceps/cep-17.md index 3b5ce9a..561885d 100644 --- a/src/content/docs/reference/ceps/cep-17.md +++ b/src/content/docs/reference/ceps/cep-17.md @@ -138,7 +138,7 @@ Servers that do not publish a relay list event are treated the same as before - ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) - Server announcements (kind 11316) provide the pubkey needed to query relay lists +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) - Server announcements (kind 11316) provide the pubkey needed to query relay lists ## Reference Implementation diff --git a/src/content/docs/reference/ceps/cep-19.md b/src/content/docs/reference/ceps/cep-19.md index 68cf17d..81fb54f 100644 --- a/src/content/docs/reference/ceps/cep-19.md +++ b/src/content/docs/reference/ceps/cep-19.md @@ -105,6 +105,6 @@ A reference implementation is available in the [ContextVM SDK](https://github.co ## Dependencies -- [CEP-4: Encryption Support](/spec/ceps/cep-4) -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) -- [CEP-35: Stateless Session Discovery and Capability Learning](/spec/ceps/informational/cep-35) +- [CEP-4: Encryption Support](/reference/ceps/cep-4) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) +- [CEP-35: Stateless Session Discovery and Capability Learning](/reference/ceps/informational/cep-35) diff --git a/src/content/docs/reference/ceps/cep-22.md b/src/content/docs/reference/ceps/cep-22.md index db57c81..a826410 100644 --- a/src/content/docs/reference/ceps/cep-22.md +++ b/src/content/docs/reference/ceps/cep-22.md @@ -461,7 +461,7 @@ Implementations that ignore the new tags or do not understand the oversized-tran ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) ## Reference Implementation diff --git a/src/content/docs/reference/ceps/cep-23.md b/src/content/docs/reference/ceps/cep-23.md index 489fad5..d5658dd 100644 --- a/src/content/docs/reference/ceps/cep-23.md +++ b/src/content/docs/reference/ceps/cep-23.md @@ -79,4 +79,4 @@ A reference implementation of this metadata publishing can be found in the [Cont ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) diff --git a/src/content/docs/reference/ceps/cep-24.md b/src/content/docs/reference/ceps/cep-24.md index 74647a8..7b06c8e 100644 --- a/src/content/docs/reference/ceps/cep-24.md +++ b/src/content/docs/reference/ceps/cep-24.md @@ -112,4 +112,4 @@ A reference implementation for server review UI and data fetching can be found i ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) diff --git a/src/content/docs/reference/ceps/cep-4.md b/src/content/docs/reference/ceps/cep-4.md index 4064207..80f6d03 100644 --- a/src/content/docs/reference/ceps/cep-4.md +++ b/src/content/docs/reference/ceps/cep-4.md @@ -118,4 +118,4 @@ A reference implementation can be found in the [ContextVM sdk](https://github.co ## Dependencies -- [cep-19: Ephemeral Gift Wraps](/spec/ceps/cep-19) +- [cep-19: Ephemeral Gift Wraps](/reference/ceps/cep-19) diff --git a/src/content/docs/reference/ceps/cep-41.md b/src/content/docs/reference/ceps/cep-41.md index 1a236e7..258aa03 100644 --- a/src/content/docs/reference/ceps/cep-41.md +++ b/src/content/docs/reference/ceps/cep-41.md @@ -518,10 +518,10 @@ This CEP introduces no breaking changes: ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) -- [CEP-19: Ephemeral Gift Wraps](/spec/ceps/cep-19) -- [CEP-22: Oversized Payload Transfer](/spec/ceps/cep-22) -- [CEP-35: Discoverability Patterns for ContextVM Capabilities](/spec/ceps/informational/cep-35) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) +- [CEP-19: Ephemeral Gift Wraps](/reference/ceps/cep-19) +- [CEP-22: Oversized Payload Transfer](/reference/ceps/cep-22) +- [CEP-35: Discoverability Patterns for ContextVM Capabilities](/reference/ceps/informational/cep-35) ## Reference Implementation diff --git a/src/content/docs/reference/ceps/cep-6.md b/src/content/docs/reference/ceps/cep-6.md index 815c540..e156679 100644 --- a/src/content/docs/reference/ceps/cep-6.md +++ b/src/content/docs/reference/ceps/cep-6.md @@ -103,7 +103,7 @@ Because direct-message replay is session-scoped, it does not replace public anno As in the Server Announcement event, the `content` field contains a JSON string with the list of capabilities. The list is the result of a call to the `list` method of each capability. -**Note**: For tools list announcements (kind 11317), see [CEP-15: Common Tool Schemas](/spec/ceps/cep-15) for additional tag conventions that enable schema discovery and ecosystem integration. +**Note**: For tools list announcements (kind 11317), see [CEP-15: Common Tool Schemas](/reference/ceps/cep-15) for additional tag conventions that enable schema discovery and ecosystem integration. ### Tools List Event Example @@ -161,6 +161,6 @@ A reference implementation can be found in the [ContextVM SDK server transport i ## Dependencies -- [CEP-4: Encryption Support](/spec/ceps/cep-4) -- [CEP-15: Common Tool Schemas](/spec/ceps/cep-15) — Extends tools list announcements with schema discovery and NIP-73 integration -- [CEP-35: Stateless Session Discovery and Capability Learning](/spec/ceps/informational/cep-35) +- [CEP-4: Encryption Support](/reference/ceps/cep-4) +- [CEP-15: Common Tool Schemas](/reference/ceps/cep-15) — Extends tools list announcements with schema discovery and NIP-73 integration +- [CEP-35: Stateless Session Discovery and Capability Learning](/reference/ceps/informational/cep-35) diff --git a/src/content/docs/reference/ceps/cep-8.md b/src/content/docs/reference/ceps/cep-8.md index 852c674..2ce470e 100644 --- a/src/content/docs/reference/ceps/cep-8.md +++ b/src/content/docs/reference/ceps/cep-8.md @@ -37,7 +37,7 @@ This CEP defines: This CEP does **not** define: -- Privacy guarantees for payment messages (use encryption mechanisms in [CEP-4](/spec/ceps/cep-4) where required). +- Privacy guarantees for payment messages (use encryption mechanisms in [CEP-4](/reference/ceps/cep-4) where required). - Rate limiting / abuse prevention mechanisms. - Currency conversion rules or exchange rate discovery. @@ -152,7 +152,7 @@ Pricing information is advertised using the `cap` tag in server announcements an The `cap` tag indicates that using the `get_weather` tool costs 100 satoshis, allowing clients to display pricing to users. -When `cap` tags are attached to a capability list response, they describe the pricing surface of that specific response payload. They are response-local discovery metadata for the listed capabilities, not by themselves a replacement for the peer's general session discovery baseline as defined in [CEP-35: Stateless Session Discovery and Capability Learning](/spec/ceps/informational/cep-35). +When `cap` tags are attached to a capability list response, they describe the pricing surface of that specific response payload. They are response-local discovery metadata for the listed capabilities, not by themselves a replacement for the peer's general session discovery baseline as defined in [CEP-35: Stateless Session Discovery and Capability Learning](/reference/ceps/informational/cep-35). ### Payment Method Identifiers (PMI) @@ -176,7 +176,7 @@ PMIs MUST follow the format defined by the [W3C Payment Method Identifiers](http This CEP maintains no in-document registry of recommended PMIs. -Recommended PMIs and naming conventions are documented in the informational companion CEP, [CEP-21: Payment Method Identifier (PMI) Recommendations](/spec/ceps/informational/cep-21). +Recommended PMIs and naming conventions are documented in the informational companion CEP, [CEP-21: Payment Method Identifier (PMI) Recommendations](/reference/ceps/informational/cep-21). #### PMI Benefits and Roles @@ -189,7 +189,7 @@ Using standardized PMIs provides: ### PMI Discovery -PMI discovery allows clients and servers to determine compatibility with payment methods, similar to encryption support discovery in [CEP-4](/spec/ceps/cep-4). +PMI discovery allows clients and servers to determine compatibility with payment methods, similar to encryption support discovery in [CEP-4](/reference/ceps/cep-4). #### PMI Advertisement @@ -245,7 +245,7 @@ Servers can discover PMI support through: In stateless operation (no prior initialization), clients that want to use paid capabilities SHOULD include one or more `pmi` tags in the request event so the server can select a compatible payment method. -When sent on the first direct client-to-server message of a session, these `pmi` tags participate in the session discovery baseline described by [CEP-35: Stateless Session Discovery and Capability Learning](/spec/ceps/informational/cep-35). When sent on later requests, they are interpreted in the context of those requests unless another CEP explicitly defines stronger session-update semantics. +When sent on the first direct client-to-server message of a session, these `pmi` tags participate in the session discovery baseline described by [CEP-35: Stateless Session Discovery and Capability Learning](/reference/ceps/informational/cep-35). When sent on later requests, they are interpreted in the context of those requests unless another CEP explicitly defines stronger session-update semantics. ### Payment Flow @@ -492,7 +492,7 @@ A reference implementation of this CEP is available in the [ContextVM TypeScript ## Dependencies -- [CEP-4: Encryption Support](/spec/ceps/cep-4) -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) -- [CEP-35: Stateless Session Discovery and Capability Learning](/spec/ceps/informational/cep-35) +- [CEP-4: Encryption Support](/reference/ceps/cep-4) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) +- [CEP-35: Stateless Session Discovery and Capability Learning](/reference/ceps/informational/cep-35) - [W3C Payment Method Identifiers](https://www.w3.org/TR/payment-method-id/) diff --git a/src/content/docs/reference/ceps/informational/.gitkeep b/src/content/docs/reference/ceps/informational/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ceps/informational/cep-21.md b/src/content/docs/reference/ceps/informational/cep-21.md index 7181400..a64b2f3 100644 --- a/src/content/docs/reference/ceps/informational/cep-21.md +++ b/src/content/docs/reference/ceps/informational/cep-21.md @@ -11,7 +11,7 @@ description: Recommended PMIs and naming conventions for CEP-8 payments ## Abstract -This CEP provides **non-normative** recommendations for Payment Method Identifiers (PMIs) used with [CEP-8](/spec/ceps/cep-8). +This CEP provides **non-normative** recommendations for Payment Method Identifiers (PMIs) used with [CEP-8](/reference/ceps/cep-8). It exists to: @@ -61,4 +61,4 @@ This is a convention for discovery and interoperability; support is ultimately i ## Dependencies -- [CEP-8: Capability Pricing and Payment Flow](/spec/ceps/cep-8) +- [CEP-8: Capability Pricing and Payment Flow](/reference/ceps/cep-8) diff --git a/src/content/docs/reference/ceps/informational/cep-35.md b/src/content/docs/reference/ceps/informational/cep-35.md index f0a95d7..06149f3 100644 --- a/src/content/docs/reference/ceps/informational/cep-35.md +++ b/src/content/docs/reference/ceps/informational/cep-35.md @@ -152,11 +152,11 @@ This CEP does not replace feature-specific CEPs. Instead, it defines the behavio Relevant specifications include: -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) -- [CEP-8: Capability Pricing and Payment Flow](/spec/ceps/cep-8) -- [CEP-17: Relay List Metadata Discovery](/spec/ceps/cep-17) -- [CEP-19: Ephemeral Gift Wrap for Encrypted Transport](/spec/ceps/cep-19) -- [CEP-22: Oversized Transfer](/spec/ceps/cep-22) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) +- [CEP-8: Capability Pricing and Payment Flow](/reference/ceps/cep-8) +- [CEP-17: Relay List Metadata Discovery](/reference/ceps/cep-17) +- [CEP-19: Ephemeral Gift Wrap for Encrypted Transport](/reference/ceps/cep-19) +- [CEP-22: Oversized Transfer](/reference/ceps/cep-22) These CEPs define individual discovery vocabularies or feature semantics. This CEP defines how implementations should exchange and learn that information in stateless session context. @@ -192,7 +192,7 @@ This behavior is already established in the ContextVM TypeScript SDK, which serv ## Dependencies -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) -- [CEP-8: Capability Pricing and Payment Flow](/spec/ceps/cep-8) -- [CEP-19: Ephemeral Gift Wrap for Encrypted Transport](/spec/ceps/cep-19) -- [CEP-22: Oversized Transfer](/spec/ceps/cep-22) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) +- [CEP-8: Capability Pricing and Payment Flow](/reference/ceps/cep-8) +- [CEP-19: Ephemeral Gift Wrap for Encrypted Transport](/reference/ceps/cep-19) +- [CEP-22: Oversized Transfer](/reference/ceps/cep-22) diff --git a/src/content/docs/reference/spec/.gitkeep b/src/content/docs/reference/spec/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/spec/ctxvm-draft-spec.md b/src/content/docs/reference/spec/ctxvm-draft-spec.md index 187885e..3b6d140 100644 --- a/src/content/docs/reference/spec/ctxvm-draft-spec.md +++ b/src/content/docs/reference/spec/ctxvm-draft-spec.md @@ -322,8 +322,8 @@ The following CEPs have been accepted: The following CEPs have been finalized: -- [CEP-4: Encryption Support](/spec/ceps/cep-4) -- [CEP-6: Public Server Announcements](/spec/ceps/cep-6) +- [CEP-4: Encryption Support](/reference/ceps/cep-4) +- [CEP-6: Public Server Announcements](/reference/ceps/cep-6) ## Complete Protocol Flow diff --git a/src/content/docs/reference/ts-sdk/core/.gitkeep b/src/content/docs/reference/ts-sdk/core/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md b/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md index adae1fa..6eb0712 100644 --- a/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md +++ b/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md @@ -5,7 +5,7 @@ description: Compute and publish CEP-15 common tool schema hashes with the @cont # Common Tool Schemas -The `@contextvm/sdk` includes helpers for [CEP-15](/spec/ceps/cep-15) common tool schemas. +The `@contextvm/sdk` includes helpers for [CEP-15](/reference/ceps/cep-15) common tool schemas. For most server integrations, prefer `withCommonToolSchemas()`. It decorates `NostrServerTransport` and publishes the required metadata automatically. @@ -80,7 +80,7 @@ This is the recommended path because the SDK will automatically: `categories` are lightweight discoverability hints for announced `tools/list` events. The SDK trims whitespace, removes empty values, and deduplicates repeated categories while preserving the original order of the remaining entries. -For more transport-specific context, see [Nostr Server Transport](/ts-sdk/transports/nostr-server-transport#cep-15-common-tool-schemas). +For more transport-specific context, see [Nostr Server Transport](/reference/ts-sdk/transports/nostr-server-transport#cep-15-common-tool-schemas). ## Exports @@ -173,4 +173,4 @@ This is mainly useful for tests, debugging, and custom verification flows. ## Next Steps -For the recommended server-side integration, see [Nostr Server Transport](/ts-sdk/transports/nostr-server-transport#cep-15-common-tool-schemas). +For the recommended server-side integration, see [Nostr Server Transport](/reference/ts-sdk/transports/nostr-server-transport#cep-15-common-tool-schemas). diff --git a/src/content/docs/reference/ts-sdk/gateway/.gitkeep b/src/content/docs/reference/ts-sdk/gateway/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/payments/.gitkeep b/src/content/docs/reference/ts-sdk/payments/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/payments/overview.md b/src/content/docs/reference/ts-sdk/payments/overview.md index f72855c..97b5fe1 100644 --- a/src/content/docs/reference/ts-sdk/payments/overview.md +++ b/src/content/docs/reference/ts-sdk/payments/overview.md @@ -250,8 +250,8 @@ In practice, when you use payments wrappers, PMI advertisement is handled for yo ## Related -- [CEP-8 Specification](/spec/ceps/cep-8) -- [CEP-21: Payment Rejection](/spec/ceps/informational/cep-21) +- [CEP-8 Specification](/reference/ceps/cep-8) +- [CEP-21: Payment Rejection](/reference/ceps/informational/cep-21) - [Paid Servers and Clients Guide](/docs/payments-paid-servers-and-clients) ## Next steps diff --git a/src/content/docs/reference/ts-sdk/proxy/.gitkeep b/src/content/docs/reference/ts-sdk/proxy/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/proxy/overview.md b/src/content/docs/reference/ts-sdk/proxy/overview.md index 20bc486..fc8ee1b 100644 --- a/src/content/docs/reference/ts-sdk/proxy/overview.md +++ b/src/content/docs/reference/ts-sdk/proxy/overview.md @@ -83,4 +83,4 @@ In this setup, a separate MCP client process could connect to this proxy's `Stdi Next, we'll look at the server-side equivalent of the proxy: -- **[Gateway](/ts-sdk/gateway/overview)** +- **[Gateway](/reference/ts-sdk/gateway/overview)** diff --git a/src/content/docs/reference/ts-sdk/quick-overview.md b/src/content/docs/reference/ts-sdk/quick-overview.md index 55a1b9e..bf59ebb 100644 --- a/src/content/docs/reference/ts-sdk/quick-overview.md +++ b/src/content/docs/reference/ts-sdk/quick-overview.md @@ -27,15 +27,15 @@ This will install the SDK and its dependencies into your project. The SDK is organized into several modules, each providing a specific set of functionalities: -- **[Core](/ts-sdk/core/interfaces)**: Contains fundamental definitions, constants, interfaces, and utilities (e.g., encryption, serialization). -- **[Logging](/ts-sdk/core/logging)**: SDK logging conventions, configuration and best practices (Pino-based). -- **[Transports](/ts-sdk/transports/base-nostr-transport)**: Critical for communication, this module provides `NostrClientTransport` and `NostrServerTransport` implementations for enabling MCP over Nostr. -- **[Common Tool Schemas](/ts-sdk/core/common-tool-schemas)**: Utilities and transport integration for publishing CEP-15 common tool schema metadata. -- **[Signer](/ts-sdk/signer/nostr-signer-interface)**: Provides cryptographic signing capabilities required for Nostr events -- **[Relay](/ts-sdk/relay/relay-handler-interface)**: Manages Nostr relay connections, abstracting the complexity of relay interactions. -- **[Proxy](/ts-sdk/proxy/overview)**: A client-side MCP server that connects to other servers through Nostr, exposing their capabilities locally, specially useful for clients that don't natively support Nostr transport. -- **[Gateway](/ts-sdk/gateway/overview)**: An MCP server transport that binds to another MCP server, exposing its capabilities to the Nostr network, specially useful for servers that don't natively support Nostr transport. -- **[Payments](/ts-sdk/payments/overview)**: Add CEP-8 payments to servers and clients with Lightning, NWC, and custom rails. +- **[Core](/reference/ts-sdk/core/interfaces)**: Contains fundamental definitions, constants, interfaces, and utilities (e.g., encryption, serialization). +- **[Logging](/reference/ts-sdk/core/logging)**: SDK logging conventions, configuration and best practices (Pino-based). +- **[Transports](/reference/ts-sdk/transports/base-nostr-transport)**: Critical for communication, this module provides `NostrClientTransport` and `NostrServerTransport` implementations for enabling MCP over Nostr. +- **[Common Tool Schemas](/reference/ts-sdk/core/common-tool-schemas)**: Utilities and transport integration for publishing CEP-15 common tool schema metadata. +- **[Signer](/reference/ts-sdk/signer/nostr-signer-interface)**: Provides cryptographic signing capabilities required for Nostr events +- **[Relay](/reference/ts-sdk/relay/relay-handler-interface)**: Manages Nostr relay connections, abstracting the complexity of relay interactions. +- **[Proxy](/reference/ts-sdk/proxy/overview)**: A client-side MCP server that connects to other servers through Nostr, exposing their capabilities locally, specially useful for clients that don't natively support Nostr transport. +- **[Gateway](/reference/ts-sdk/gateway/overview)**: An MCP server transport that binds to another MCP server, exposing its capabilities to the Nostr network, specially useful for servers that don't natively support Nostr transport. +- **[Payments](/reference/ts-sdk/payments/overview)**: Add CEP-8 payments to servers and clients with Lightning, NWC, and custom rails. ## Core Concepts @@ -54,16 +54,16 @@ These components are fundamental for creating and broadcasting Nostr events, whi The SDK provides two specialized transports to send and receive MCP messages over the Nostr network: -- [`NostrClientTransport`](/ts-sdk/transports/nostr-client-transport): Used by MCP clients to connect to remote MCP servers exposed via Nostr. -- [`NostrServerTransport`](/ts-sdk/transports/nostr-server-transport): Used by MCP servers to expose their capabilities through Nostr, publish relay discoverability metadata, and optionally publish CEP-23 `kind:0` server profiles. +- [`NostrClientTransport`](/reference/ts-sdk/transports/nostr-client-transport): Used by MCP clients to connect to remote MCP servers exposed via Nostr. +- [`NostrServerTransport`](/reference/ts-sdk/transports/nostr-server-transport): Used by MCP servers to expose their capabilities through Nostr, publish relay discoverability metadata, and optionally publish CEP-23 `kind:0` server profiles. -Server transports can also publish [CEP-15](/spec/ceps/cep-15) common tool schema metadata for interoperable tool discovery across providers. +Server transports can also publish [CEP-15](/reference/ceps/cep-15) common tool schema metadata for interoperable tool discovery across providers. These transports handle the serialization of MCP messages into Nostr events and manage the communication flow. -On the client side, [`NostrClientTransport`](/ts-sdk/transports/nostr-client-transport) can use explicit operational relays, `nprofile` relay hints, or CEP-17 relay-list discovery. This means client configurations can now omit `relayHandler` when discovery-based resolution is desired. +On the client side, [`NostrClientTransport`](/reference/ts-sdk/transports/nostr-client-transport) can use explicit operational relays, `nprofile` relay hints, or CEP-17 relay-list discovery. This means client configurations can now omit `relayHandler` when discovery-based resolution is desired. -On the server side, [`NostrServerTransport`](/ts-sdk/transports/nostr-server-transport) now separates three publication concerns: +On the server side, [`NostrServerTransport`](/reference/ts-sdk/transports/nostr-server-transport) now separates three publication concerns: - ContextVM capability announcements for protocol discovery; - relay-list publication for reachability discovery; @@ -75,8 +75,8 @@ This allows operators to publish a profile without making the server fully annou To simplify integration with existing MCP applications, the SDK provides two high-level bridging components: -- [`NostrMCPProxy`](/ts-sdk/proxy/overview): A client-side bridge that allows an MCP client to communicate with a remote MCP server over Nostr without requiring native Nostr support in the client. -- [`NostrMCPGateway`](/ts-sdk/gateway/overview): A server-side bridge that exposes an existing MCP server to the Nostr network, allowing it to be discovered and used by Nostr-native clients. +- [`NostrMCPProxy`](/reference/ts-sdk/proxy/overview): A client-side bridge that allows an MCP client to communicate with a remote MCP server over Nostr without requiring native Nostr support in the client. +- [`NostrMCPGateway`](/reference/ts-sdk/gateway/overview): A server-side bridge that exposes an existing MCP server to the Nostr network, allowing it to be discovered and used by Nostr-native clients. These components abstract away the underlying transport complexities, making it easy to connect conventional MCP setups with the decentralized Nostr ecosystem. diff --git a/src/content/docs/reference/ts-sdk/relay/.gitkeep b/src/content/docs/reference/ts-sdk/relay/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/signer/.gitkeep b/src/content/docs/reference/ts-sdk/signer/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/transports/.gitkeep b/src/content/docs/reference/ts-sdk/transports/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md b/src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md index 62cc829..5086f8a 100644 --- a/src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md +++ b/src/content/docs/reference/ts-sdk/transports/base-nostr-transport.md @@ -48,7 +48,7 @@ The `GiftWrapMode` enum controls which NIP-59 gift wrap kind is used for encrypt - **`EPHEMERAL`**: Always uses ephemeral gift wraps (kind `21059`). Only use this when you know the remote peer supports ephemeral gift wraps. - **`PERSISTENT`**: Always uses persistent gift wraps (kind `1059`). Use this for maximum compatibility with existing implementations. -Ephemeral gift wraps (kind `21059`) are preferred for privacy-sensitive communications as relays are not expected to store them. See [CEP-19: Ephemeral Gift Wraps](/spec/ceps/cep-19) for more details. +Ephemeral gift wraps (kind `21059`) are preferred for privacy-sensitive communications as relays are not expected to store them. See [CEP-19: Ephemeral Gift Wraps](/reference/ceps/cep-19) for more details. ### Example: Using Ephemeral Gift Wraps diff --git a/src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md b/src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md index 77ba969..72e9d7d 100644 --- a/src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md +++ b/src/content/docs/reference/ts-sdk/transports/nostr-client-transport.md @@ -121,8 +121,8 @@ This keeps the active relay set minimal and avoids automatically merging every p Some transport features are activated per request, not just per transport instance. -- [Oversized Transfer](/ts-sdk/transports/oversized-transfer) uses the MCP request `progressToken` as the CEP-22 transfer identifier. -- [Open Stream](/ts-sdk/transports/open-stream) uses the MCP request `progressToken` as the CEP-41 stream identifier. +- [Oversized Transfer](/reference/ts-sdk/transports/oversized-transfer) uses the MCP request `progressToken` as the CEP-22 transfer identifier. +- [Open Stream](/reference/ts-sdk/transports/open-stream) uses the MCP request `progressToken` as the CEP-41 stream identifier. When you use the MCP TypeScript SDK through high-level request APIs and provide an `onprogress` callback, the SDK usually creates that token automatically. When you construct raw requests manually, you must provide the token yourself if you want request-scoped progress-based transport features to activate. diff --git a/src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md b/src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md index efb1beb..19160d8 100644 --- a/src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md +++ b/src/content/docs/reference/ts-sdk/transports/nostr-server-transport.md @@ -317,7 +317,7 @@ console.log('MCP server is running and available on Nostr.'); ## CEP-15 Common Tool Schemas -If your server implements a shared tool contract defined by [CEP-15](/spec/ceps/cep-15), you can opt specific tools into common-schema publication. +If your server implements a shared tool contract defined by [CEP-15](/reference/ceps/cep-15), you can opt specific tools into common-schema publication. Use `withCommonToolSchemas()` to decorate the transport before connecting the server: @@ -401,7 +401,7 @@ Use this for tools that are intended to match a shared public contract across pr - If you provide an `outputSchema`, it participates in the hash and should remain stable across providers. - Schemas used for hashing must be self-contained. Remote `$ref` values must be resolved before hashing. -For lower-level hashing and verification utilities, see [Common Tool Schemas](/ts-sdk/core/common-tool-schemas). +For lower-level hashing and verification utilities, see [Common Tool Schemas](/reference/ts-sdk/core/common-tool-schemas). ## How It Works diff --git a/src/content/docs/reference/ts-sdk/transports/open-stream.md b/src/content/docs/reference/ts-sdk/transports/open-stream.md index 6ab71ed..d2da2d7 100644 --- a/src/content/docs/reference/ts-sdk/transports/open-stream.md +++ b/src/content/docs/reference/ts-sdk/transports/open-stream.md @@ -5,7 +5,7 @@ description: CEP-41 open-ended stream support in the ContextVM TypeScript SDK # Open Stream -Open stream is the SDK support for [CEP-41: Open-Ended Stream Transfer](/spec/ceps/cep-41). It is designed for MCP exchanges that produce useful output incrementally, such as long-running tool execution, progressive generation, and event-like result delivery. +Open stream is the SDK support for [CEP-41: Open-Ended Stream Transfer](/reference/ceps/cep-41). It is designed for MCP exchanges that produce useful output incrementally, such as long-running tool execution, progressive generation, and event-like result delivery. In the SDK, CEP-41 support is exposed as a small set of transport-layer primitives plus a convenience helper for tool calls, all documented on this page. @@ -32,7 +32,7 @@ Typical cases include: - feeds or server-side event sequences associated with a request - long-running tool calls where users benefit from intermediate output before the final MCP response arrives -If you only need to move one bounded oversized payload, prefer [Oversized Transfer](/ts-sdk/transports/oversized-transfer), which implements CEP-22 bounded chunking and reassembly. +If you only need to move one bounded oversized payload, prefer [Oversized Transfer](/reference/ts-sdk/transports/oversized-transfer), which implements CEP-22 bounded chunking and reassembly. ## Mental Model @@ -116,7 +116,7 @@ If your application already has its own request correlation or tracing scheme, y This is why the helper is usually preferable to assembling the request metadata and session correlation manually. -For consistency with other progress-based transport features such as [Oversized Transfer](/ts-sdk/transports/oversized-transfer), remember that high-level MCP TypeScript SDK usage can usually create the request `progressToken` automatically when `onprogress` is used, while low-level manual requests must provide that token explicitly. On the MCP TypeScript SDK low-level `client.request()` path, `resetTimeoutOnProgress: true` also depends on `onprogress` being provided. +For consistency with other progress-based transport features such as [Oversized Transfer](/reference/ts-sdk/transports/oversized-transfer), remember that high-level MCP TypeScript SDK usage can usually create the request `progressToken` automatically when `onprogress` is used, while low-level manual requests must provide that token explicitly. On the MCP TypeScript SDK low-level `client.request()` path, `resetTimeoutOnProgress: true` also depends on `onprogress` being provided. ## Enabling Open Stream on Transports @@ -256,7 +256,7 @@ await server.connect(transport); This example shows the full producer-side shape: -- an MCP server created with [`McpServer`](/ts-sdk/transports/open-stream.md:144) +- an MCP server created with [`McpServer`](/reference/ts-sdk/transports/open-stream.md:144) - a [`NostrServerTransport`](src/transport/nostr-server-transport.ts) with `openStream.enabled` - a registered tool that reads the injected stream writer from `extra._meta.stream` - a server-managed [`OpenStreamWriter`](src/transport/open-stream/writer.ts:26) that publishes CEP-41 frames while the tool is running @@ -387,13 +387,13 @@ This behavior aligns with the reference implementation tested in [`src/transport ## Relationship to the CEP -For protocol-level semantics, validation rules, and wire examples, refer to [CEP-41: Open-Ended Stream Transfer](/spec/ceps/cep-41). +For protocol-level semantics, validation rules, and wire examples, refer to [CEP-41: Open-Ended Stream Transfer](/reference/ceps/cep-41). This SDK page focuses on how those semantics map onto the TypeScript API surface. ## Related Documentation -- [CEP-41: Open-Ended Stream Transfer](/spec/ceps/cep-41) -- [Oversized Transfer](/ts-sdk/transports/oversized-transfer) -- [Nostr Client Transport](/ts-sdk/transports/nostr-client-transport) -- [Nostr Server Transport](/ts-sdk/transports/nostr-server-transport) +- [CEP-41: Open-Ended Stream Transfer](/reference/ceps/cep-41) +- [Oversized Transfer](/reference/ts-sdk/transports/oversized-transfer) +- [Nostr Client Transport](/reference/ts-sdk/transports/nostr-client-transport) +- [Nostr Server Transport](/reference/ts-sdk/transports/nostr-server-transport) diff --git a/src/content/docs/reference/ts-sdk/transports/oversized-transfer.md b/src/content/docs/reference/ts-sdk/transports/oversized-transfer.md index 116e858..381bfb8 100644 --- a/src/content/docs/reference/ts-sdk/transports/oversized-transfer.md +++ b/src/content/docs/reference/ts-sdk/transports/oversized-transfer.md @@ -5,13 +5,13 @@ description: Bounded oversized payload transfer for ContextVM using MCP progress # Oversized Transfer -Oversized transfer is the SDK feature that automatically switches a message to the [CEP-22: Oversized Payload Transfer](/spec/ceps/cep-22) flow when a normal relay event would likely be too large. +Oversized transfer is the SDK feature that automatically switches a message to the [CEP-22: Oversized Payload Transfer](/reference/ceps/cep-22) flow when a normal relay event would likely be too large. In normal use, application code does not send chunks or manage transfer state directly. The transport handles that internally. ## Default Behavior -Oversized transfer is enabled by default on both [`Nostr Client Transport`](/ts-sdk/transports/nostr-client-transport) and [`Nostr Server Transport`](/ts-sdk/transports/nostr-server-transport). +Oversized transfer is enabled by default on both [`Nostr Client Transport`](/reference/ts-sdk/transports/nostr-client-transport) and [`Nostr Server Transport`](/reference/ts-sdk/transports/nostr-server-transport). With defaults: @@ -24,7 +24,7 @@ This means most consumers do not need to configure anything unless they want str ## Request Activation and `progressToken` -CEP-22 oversized transfer is request-scoped. It is only available for a logical exchange when the originating MCP request includes a `progressToken`, as described in [CEP-22: Oversized Payload Transfer](/spec/ceps/cep-22). +CEP-22 oversized transfer is request-scoped. It is only available for a logical exchange when the originating MCP request includes a `progressToken`, as described in [CEP-22: Oversized Payload Transfer](/reference/ceps/cep-22). In practice, this matters most on the client side: @@ -75,7 +75,7 @@ When using the MCP TypeScript SDK, remember that this timeout-reset behavior is ### Low-level transport usage -If you are working below the usual MCP client helpers, such as constructing raw requests for [`NostrClientTransport`](/ts-sdk/transports/nostr-client-transport), treat `progressToken` as part of the activation contract for CEP-22. +If you are working below the usual MCP client helpers, such as constructing raw requests for [`NostrClientTransport`](/reference/ts-sdk/transports/nostr-client-transport), treat `progressToken` as part of the activation contract for CEP-22. - High-level MCP SDK usage with `onprogress` usually handles this automatically. - Manual raw requests must include the token explicitly in request metadata. @@ -173,10 +173,10 @@ If an oversized transfer fails, the transport may surface one of these errors: - Prefer high-level MCP client calls with `onprogress` so the SDK can assign a `progressToken` automatically. - Set `resetTimeoutOnProgress: true` for requests that may emit progress or trigger CEP-22 oversized transfer. - Tighten `policy` values if you operate in a more adversarial or resource-constrained environment. -- Refer to [CEP-22: Oversized Payload Transfer](/spec/ceps/cep-22) for protocol-level behavior. +- Refer to [CEP-22: Oversized Payload Transfer](/reference/ceps/cep-22) for protocol-level behavior. ## Related Documentation -- [CEP-22: Oversized Payload Transfer](/spec/ceps/cep-22) -- [Nostr Client Transport](/ts-sdk/transports/nostr-client-transport) -- [Nostr Server Transport](/ts-sdk/transports/nostr-server-transport) +- [CEP-22: Oversized Payload Transfer](/reference/ceps/cep-22) +- [Nostr Client Transport](/reference/ts-sdk/transports/nostr-client-transport) +- [Nostr Server Transport](/reference/ts-sdk/transports/nostr-server-transport) diff --git a/src/content/docs/tutorials/.gitkeep b/src/content/docs/tutorials/.gitkeep deleted file mode 100644 index e69de29..0000000 From 8eebec3d1c8a9ff1b31f3c6efd185a204399ee67 Mon Sep 17 00:00:00 2001 From: Khushvendra Date: Tue, 9 Jun 2026 22:47:51 +0530 Subject: [PATCH 07/11] docs: verify build and clean up --- .github/workflows/deploy-github-pages.yml | 2 +- astro.config.mjs | 330 ++++++++++++------ src/content.config.ts | 6 +- .../docs/getting-started/quick-overview.md | 14 +- src/content/docs/how-to/payments/client.md | 6 +- .../docs/how-to/payments/custom-rails.md | 10 +- .../docs/how-to/payments/getting-started.md | 20 +- .../how-to/payments/rails/lightning-nwc.md | 4 +- src/content/docs/how-to/payments/server.md | 18 +- src/content/docs/index.mdx | 6 +- src/content/docs/reference/ceps/cep-41.md | 2 +- .../docs/reference/rs-sdk/client-transport.md | 5 +- src/content/docs/reference/rs-sdk/design.md | 128 +++---- .../docs/reference/rs-sdk/discovery.md | 5 +- .../docs/reference/rs-sdk/encryption.md | 5 +- src/content/docs/reference/rs-sdk/gateway.md | 5 +- src/content/docs/reference/rs-sdk/overview.md | 21 +- src/content/docs/reference/rs-sdk/proxy.md | 5 +- src/content/docs/reference/rs-sdk/rmcp.md | 5 +- .../docs/reference/rs-sdk/server-transport.md | 5 +- .../docs/reference/rs-sdk/stateless.md | 5 +- .../docs/reference/rs-sdk/transport-modes.md | 5 +- .../docs/reference/rs-sdk/transports.md | 5 +- .../ts-sdk/core/common-tool-schemas.md | 60 ++-- .../docs/reference/ts-sdk/core/constants.md | 10 +- .../docs/reference/ts-sdk/core/encryption.md | 4 +- .../docs/reference/ts-sdk/core/interfaces.md | 6 +- .../docs/reference/ts-sdk/core/logging.md | 48 +-- .../docs/reference/ts-sdk/gateway/overview.md | 40 +-- .../reference/ts-sdk/payments/overview.md | 18 +- .../docs/reference/ts-sdk/proxy/overview.md | 16 +- .../ts-sdk/relay/applesauce-relay-pool.md | 8 +- .../signer/custom-signer-development.md | 14 +- .../ts-sdk/signer/private-key-signer.md | 4 +- .../ts-sdk/transports/base-nostr-transport.md | 12 +- .../transports/nostr-client-transport.md | 44 +-- .../transports/nostr-server-transport.md | 142 ++++---- .../ts-sdk/transports/open-stream.md | 102 +++--- .../ts-sdk/transports/oversized-transfer.md | 6 +- .../tutorials/client-server-communication.md | 72 ++-- src/utils/docSource.ts | 12 +- 41 files changed, 685 insertions(+), 550 deletions(-) diff --git a/.github/workflows/deploy-github-pages.yml b/.github/workflows/deploy-github-pages.yml index 0d93a34..823a41e 100644 --- a/.github/workflows/deploy-github-pages.yml +++ b/.github/workflows/deploy-github-pages.yml @@ -38,7 +38,7 @@ jobs: - name: Build site env: - GITHUB_PAGES: 'true' + GITHUB_PAGES: "true" run: bun run build - name: Upload Pages artifact diff --git a/astro.config.mjs b/astro.config.mjs index a0cf73c..c681026 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,131 +1,231 @@ // @ts-check -import { defineConfig } from 'astro/config'; -import starlight from '@astrojs/starlight'; +import { defineConfig } from "astro/config"; +import starlight from "@astrojs/starlight"; -const isGitHubPages = process.env.GITHUB_PAGES === 'true'; -const githubPagesBase = '/contextvm-docs'; +const isGitHubPages = process.env.GITHUB_PAGES === "true"; +const githubPagesBase = "/contextvm-docs"; // https://astro.build/config export default defineConfig({ site: isGitHubPages - ? 'https://contextvm.github.io/contextvm-docs' - : 'https://docs.contextvm.org', - base: isGitHubPages ? githubPagesBase : '/', + ? "https://contextvm.github.io/contextvm-docs" + : "https://docs.contextvm.org", + base: isGitHubPages ? githubPagesBase : "/", integrations: [ starlight({ - title: 'ContextVM Documentation', - description: 'Documentation for ContextVM', + title: "ContextVM Documentation", + description: "Documentation for ContextVM", logo: { - light: './src/assets/contextvm-logo.svg', - dark: './src/assets/contextvm-logo.svg', + light: "./src/assets/contextvm-logo.svg", + dark: "./src/assets/contextvm-logo.svg", replacesTitle: false, }, social: [ { - icon: 'github', - label: 'ContextVM', - href: 'https://github.com/contextvm/ts-sdk', + icon: "github", + label: "ContextVM", + href: "https://github.com/contextvm/ts-sdk", }, { - icon: 'external', - label: 'ContextVM Website', - href: 'https://contextvm.org/', + icon: "external", + label: "ContextVM Website", + href: "https://contextvm.org/", }, ], components: { - PageTitle: './src/components/starlight/PageTitle.astro', - ThemeProvider: './src/components/starlight/ThemeProvider.astro', - ThemeSelect: './src/components/starlight/ThemeSelect.astro', + PageTitle: "./src/components/starlight/PageTitle.astro", + ThemeProvider: "./src/components/starlight/ThemeProvider.astro", + ThemeSelect: "./src/components/starlight/ThemeSelect.astro", }, sidebar: [ { - label: 'Getting Started', + label: "Getting Started", items: [ - { label: 'Quick Overview', slug: 'getting-started/quick-overview' }, + { label: "Quick Overview", slug: "getting-started/quick-overview" }, ], }, { - label: 'Reference', + label: "Reference", items: [ { - label: 'Specification', + label: "Specification", items: [ - { label: 'Specification', slug: 'reference/spec/ctxvm-draft-spec' }, - { label: 'CEP - Guidelines', slug: 'reference/spec/cep-guidelines' }, + { + label: "Specification", + slug: "reference/spec/ctxvm-draft-spec", + }, + { + label: "CEP - Guidelines", + slug: "reference/spec/cep-guidelines", + }, ], }, { - label: 'CEPs', + label: "CEPs", items: [ - { label: 'CEP-4: Encryption Support', slug: 'reference/ceps/cep-4' }, - { label: 'CEP-6: Public Server Announcements', slug: 'reference/ceps/cep-6' }, - { label: 'CEP-8: Capability Pricing and Payment Flow', slug: 'reference/ceps/cep-8' }, - { label: 'CEP-15: Common Tool Schemas', slug: 'reference/ceps/cep-15' }, - { label: 'CEP-17: Server Relay List Metadata', slug: 'reference/ceps/cep-17' }, - { label: 'CEP-19: Ephemeral Gift Wraps', slug: 'reference/ceps/cep-19' }, - { label: 'CEP-22: Oversized Payload Transfer', slug: 'reference/ceps/cep-22' }, - { label: 'CEP-23: Server Profile Metadata and Social Communications', slug: 'reference/ceps/cep-23' }, - { label: 'CEP-24: Server Reviews', slug: 'reference/ceps/cep-24' }, - { label: 'CEP-41: Open-Ended Streams', slug: 'reference/ceps/cep-41' }, - { - label: 'Informational', + { + label: "CEP-4: Encryption Support", + slug: "reference/ceps/cep-4", + }, + { + label: "CEP-6: Public Server Announcements", + slug: "reference/ceps/cep-6", + }, + { + label: "CEP-8: Capability Pricing and Payment Flow", + slug: "reference/ceps/cep-8", + }, + { + label: "CEP-15: Common Tool Schemas", + slug: "reference/ceps/cep-15", + }, + { + label: "CEP-17: Server Relay List Metadata", + slug: "reference/ceps/cep-17", + }, + { + label: "CEP-19: Ephemeral Gift Wraps", + slug: "reference/ceps/cep-19", + }, + { + label: "CEP-22: Oversized Payload Transfer", + slug: "reference/ceps/cep-22", + }, + { + label: + "CEP-23: Server Profile Metadata and Social Communications", + slug: "reference/ceps/cep-23", + }, + { + label: "CEP-24: Server Reviews", + slug: "reference/ceps/cep-24", + }, + { + label: "CEP-41: Open-Ended Streams", + slug: "reference/ceps/cep-41", + }, + { + label: "Informational", items: [ - { label: 'CEP-16: Client Public Key Injection', slug: 'reference/ceps/informational/cep-16' }, - { label: 'CEP-21: PMI Recommendations', slug: 'reference/ceps/informational/cep-21' }, - { label: 'CEP-35: Stateless Session Discovery', slug: 'reference/ceps/informational/cep-35' }, + { + label: "CEP-16: Client Public Key Injection", + slug: "reference/ceps/informational/cep-16", + }, + { + label: "CEP-21: PMI Recommendations", + slug: "reference/ceps/informational/cep-21", + }, + { + label: "CEP-35: Stateless Session Discovery", + slug: "reference/ceps/informational/cep-35", + }, ], }, ], }, { - label: 'TypeScript SDK', + label: "TypeScript SDK", items: [ - { label: 'Quick Overview', slug: 'reference/ts-sdk/quick-overview' }, { - label: 'Core Concepts', + label: "Quick Overview", + slug: "reference/ts-sdk/quick-overview", + }, + { + label: "Core Concepts", items: [ - { label: 'Constants', slug: 'reference/ts-sdk/core/constants' }, - { label: 'Interfaces', slug: 'reference/ts-sdk/core/interfaces' }, - { label: 'Logging', slug: 'reference/ts-sdk/core/logging' }, - { label: 'Relay Handler', slug: 'reference/ts-sdk/relay/relay-handler-interface' }, - { label: 'Nostr Signer', slug: 'reference/ts-sdk/signer/nostr-signer-interface' }, - { label: 'Encryption', slug: 'reference/ts-sdk/core/encryption' }, - { label: 'Common Tool Schemas', slug: 'reference/ts-sdk/core/common-tool-schemas' }, + { + label: "Constants", + slug: "reference/ts-sdk/core/constants", + }, + { + label: "Interfaces", + slug: "reference/ts-sdk/core/interfaces", + }, + { label: "Logging", slug: "reference/ts-sdk/core/logging" }, + { + label: "Relay Handler", + slug: "reference/ts-sdk/relay/relay-handler-interface", + }, + { + label: "Nostr Signer", + slug: "reference/ts-sdk/signer/nostr-signer-interface", + }, + { + label: "Encryption", + slug: "reference/ts-sdk/core/encryption", + }, + { + label: "Common Tool Schemas", + slug: "reference/ts-sdk/core/common-tool-schemas", + }, ], }, { - label: 'Transports', + label: "Transports", items: [ - { label: 'Base Nostr Transport', slug: 'reference/ts-sdk/transports/base-nostr-transport' }, - { label: 'Nostr Client Transport', slug: 'reference/ts-sdk/transports/nostr-client-transport' }, - { label: 'Nostr Server Transport', slug: 'reference/ts-sdk/transports/nostr-server-transport' }, - { label: 'Oversized Transfer', slug: 'reference/ts-sdk/transports/oversized-transfer' }, - { label: 'Open Stream', slug: 'reference/ts-sdk/transports/open-stream' }, + { + label: "Base Nostr Transport", + slug: "reference/ts-sdk/transports/base-nostr-transport", + }, + { + label: "Nostr Client Transport", + slug: "reference/ts-sdk/transports/nostr-client-transport", + }, + { + label: "Nostr Server Transport", + slug: "reference/ts-sdk/transports/nostr-server-transport", + }, + { + label: "Oversized Transfer", + slug: "reference/ts-sdk/transports/oversized-transfer", + }, + { + label: "Open Stream", + slug: "reference/ts-sdk/transports/open-stream", + }, ], }, { - label: 'Components', + label: "Components", items: [ { - label: 'Relay Handlers', + label: "Relay Handlers", items: [ - { label: 'Applesauce Relay Pool', slug: 'reference/ts-sdk/relay/applesauce-relay-pool' }, - { label: 'Custom Relay Handler', slug: 'reference/ts-sdk/relay/custom-relay-handler' }, + { + label: "Applesauce Relay Pool", + slug: "reference/ts-sdk/relay/applesauce-relay-pool", + }, + { + label: "Custom Relay Handler", + slug: "reference/ts-sdk/relay/custom-relay-handler", + }, ], }, { - label: 'Signers', + label: "Signers", items: [ - { label: 'Private Key Signer', slug: 'reference/ts-sdk/signer/private-key-signer' }, - { label: 'Custom Signer Development', slug: 'reference/ts-sdk/signer/custom-signer-development' }, + { + label: "Private Key Signer", + slug: "reference/ts-sdk/signer/private-key-signer", + }, + { + label: "Custom Signer Development", + slug: "reference/ts-sdk/signer/custom-signer-development", + }, ], }, - { label: 'Gateway', slug: 'reference/ts-sdk/gateway/overview' }, - { label: 'Proxy', slug: 'reference/ts-sdk/proxy/overview' }, { - label: 'Payments', + label: "Gateway", + slug: "reference/ts-sdk/gateway/overview", + }, + { label: "Proxy", slug: "reference/ts-sdk/proxy/overview" }, + { + label: "Payments", items: [ - { label: 'Overview', slug: 'reference/ts-sdk/payments/overview' }, + { + label: "Overview", + slug: "reference/ts-sdk/payments/overview", + }, ], }, ], @@ -133,23 +233,38 @@ export default defineConfig({ ], }, { - label: 'Rust SDK', + label: "Rust SDK", items: [ - { label: 'Overview', slug: 'reference/rs-sdk/overview' }, - { label: 'Native Server Guide', slug: 'reference/rs-sdk/server-transport' }, - { label: 'Native Client Guide', slug: 'reference/rs-sdk/client-transport' }, - { label: 'Gateway', slug: 'reference/rs-sdk/gateway' }, - { label: 'Proxy', slug: 'reference/rs-sdk/proxy' }, - { label: 'Discovery', slug: 'reference/rs-sdk/discovery' }, - { label: 'Encryption', slug: 'reference/rs-sdk/encryption' }, - { label: 'Transport Modes', slug: 'reference/rs-sdk/transport-modes' }, - { label: 'Transports (Low-Level)', slug: 'reference/rs-sdk/transports' }, - { label: 'Stateless Mode', slug: 'reference/rs-sdk/stateless' }, - { label: 'RMCP Integration', slug: 'reference/rs-sdk/rmcp' }, - { - label: 'Design', + { label: "Overview", slug: "reference/rs-sdk/overview" }, + { + label: "Native Server Guide", + slug: "reference/rs-sdk/server-transport", + }, + { + label: "Native Client Guide", + slug: "reference/rs-sdk/client-transport", + }, + { label: "Gateway", slug: "reference/rs-sdk/gateway" }, + { label: "Proxy", slug: "reference/rs-sdk/proxy" }, + { label: "Discovery", slug: "reference/rs-sdk/discovery" }, + { label: "Encryption", slug: "reference/rs-sdk/encryption" }, + { + label: "Transport Modes", + slug: "reference/rs-sdk/transport-modes", + }, + { + label: "Transports (Low-Level)", + slug: "reference/rs-sdk/transports", + }, + { label: "Stateless Mode", slug: "reference/rs-sdk/stateless" }, + { label: "RMCP Integration", slug: "reference/rs-sdk/rmcp" }, + { + label: "Design", items: [ - { label: 'Architecture & Design', slug: 'reference/rs-sdk/design' }, + { + label: "Architecture & Design", + slug: "reference/rs-sdk/design", + }, ], }, ], @@ -157,39 +272,54 @@ export default defineConfig({ ], }, { - label: 'How-to', + label: "How-to", items: [ { - label: 'CVMI CLI', + label: "CVMI CLI", items: [ - { label: 'Overview', slug: 'how-to/cvmi/overview' }, - { label: 'Installation', slug: 'how-to/cvmi/installation' }, - { label: 'Commands', slug: 'how-to/cvmi/commands' }, - { label: 'Configuration', slug: 'how-to/cvmi/configuration' }, - { label: 'Skills Overview', slug: 'how-to/cvmi/skills/overview' }, + { label: "Overview", slug: "how-to/cvmi/overview" }, + { label: "Installation", slug: "how-to/cvmi/installation" }, + { label: "Commands", slug: "how-to/cvmi/commands" }, + { label: "Configuration", slug: "how-to/cvmi/configuration" }, + { + label: "Skills Overview", + slug: "how-to/cvmi/skills/overview", + }, ], }, { - label: 'Payments', + label: "Payments", items: [ - { label: 'Getting Started', slug: 'how-to/payments/getting-started' }, - { label: 'Server', slug: 'how-to/payments/server' }, - { label: 'Client', slug: 'how-to/payments/client' }, { - label: 'Rails', + label: "Getting Started", + slug: "how-to/payments/getting-started", + }, + { label: "Server", slug: "how-to/payments/server" }, + { label: "Client", slug: "how-to/payments/client" }, + { + label: "Rails", items: [ - { label: 'Lightning over NWC', slug: 'how-to/payments/rails/lightning-nwc' }, + { + label: "Lightning over NWC", + slug: "how-to/payments/rails/lightning-nwc", + }, ], }, - { label: 'Build Your Own Rail', slug: 'how-to/payments/custom-rails' }, + { + label: "Build Your Own Rail", + slug: "how-to/payments/custom-rails", + }, ], }, ], }, { - label: 'Tutorials', + label: "Tutorials", items: [ - { label: 'Client-Server Communication', slug: 'tutorials/client-server-communication' }, + { + label: "Client-Server Communication", + slug: "tutorials/client-server-communication", + }, ], }, ], diff --git a/src/content.config.ts b/src/content.config.ts index 6a7b7a0..7fbcf2c 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -1,6 +1,6 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; +import { defineCollection } from "astro:content"; +import { docsLoader } from "@astrojs/starlight/loaders"; +import { docsSchema } from "@astrojs/starlight/schema"; export const collections = { docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), diff --git a/src/content/docs/getting-started/quick-overview.md b/src/content/docs/getting-started/quick-overview.md index 6688cf4..c393941 100644 --- a/src/content/docs/getting-started/quick-overview.md +++ b/src/content/docs/getting-started/quick-overview.md @@ -28,6 +28,14 @@ The TypeScript SDK provides tools and libraries for building applications with C - **Components**: Gateway, Relay Handlers, Signers, and Proxy implementations - **Tutorials**: Practical examples and guides +### 🦀 rs-SDK + +The Rust SDK provides a native Rust implementation of the ContextVM protocol: + +- **[SDK Overview](/reference/rs-sdk/overview)**: Introduction to the Rust SDK and its architecture +- **Native Transports**: Server, client, and low-level Nostr transport guides +- **Design & Architecture**: Detailed breakdown of components and implementation decisions + ## What is ContextVM? ContextVM is a protocol that bridges the Model Context Protocol (MCP) with the Nostr network, enabling decentralized communication. It allows MCP servers and clients to communicate over the Nostr protocol, leveraging its decentralized infrastructure for secure and private interactions. The protocol is designed to be used programmatically or by Large Language Models (LLMs). Client and server interactions can be triggered by a user's input through an interface or by an LLM, as the underlying MCP protocol allows LLMs to use it. @@ -36,12 +44,12 @@ ContextVM is a protocol that bridges the Model Context Protocol (MCP) with the N - **Decentralized Communication**: Use Nostr's decentralized network for MCP communication - **Security First**: Leveraging Nostr's cryptographic primitives for verification, authorization, and additional features -- **Easy Integration**: Typescript SDK to work with ContextVM +- **Easy Integration**: TypeScript and Rust SDKs to work with ContextVM ## Getting Started 1. **Read the Specification**: Start with the [ContextVM specification](/reference/spec/ctxvm-draft-spec) to understand the protocol -2. **Explore the SDK**: Check out the [SDK Quick Overview](/reference/ts-sdk/quick-overview) for development guidance +2. **Explore the SDKs**: Check out the [TypeScript SDK Quick Overview](/reference/ts-sdk/quick-overview) or [Rust SDK Overview](/reference/rs-sdk/overview) for development guidance 3. **Follow Tutorials**: Work through practical examples to see ContextVM in action ## Next Steps @@ -49,7 +57,7 @@ ContextVM is a protocol that bridges the Model Context Protocol (MCP) with the N Choose your path based on your interests: - **Protocol Development**: Dive into the [Specification](/reference/spec/ctxvm-draft-spec) to understand the protocol details -- **SDK Development**: Start with the [SDK Quick Overview](/reference/ts-sdk/quick-overview) to begin building with ContextVM +- **SDK Development**: Start with the [TypeScript SDK Quick Overview](/reference/ts-sdk/quick-overview) or [Rust SDK Overview](/reference/rs-sdk/overview) to begin building with ContextVM - **Contributing**: Learn about contributing to the protocol with [CEP Guidelines](/reference/spec/cep-guidelines) For the latest updates and community discussions, visit our [GitHub repository](https://github.com/contextvm/). diff --git a/src/content/docs/how-to/payments/client.md b/src/content/docs/how-to/payments/client.md index 542965c..8114149 100644 --- a/src/content/docs/how-to/payments/client.md +++ b/src/content/docs/how-to/payments/client.md @@ -21,7 +21,7 @@ A `PaymentHandler` implements one PMI (one payment rail). The built-in handler s import { LnBolt11NwcPaymentHandler, withClientPayments, -} from '@contextvm/sdk/payments'; +} from "@contextvm/sdk/payments"; const handler = new LnBolt11NwcPaymentHandler({ nwcConnectionString: process.env.NWC_CLIENT_CONNECTION!, @@ -68,7 +68,7 @@ This is designed for: import { withClientPayments, type PaymentHandlerRequest, -} from '@contextvm/sdk/payments'; +} from "@contextvm/sdk/payments"; const paidTransport = withClientPayments(baseTransport, { handlers: [handler], @@ -76,7 +76,7 @@ const paidTransport = withClientPayments(baseTransport, { // ctx?.method examples: "tools/call", "prompts/get", "resources/read" // ctx?.capability examples: "tool:add", "prompt:welcome", "resource:greeting://alice" if (req.amount > 500) return false; - if (ctx?.capability === 'tool:expensive_tool') return false; + if (ctx?.capability === "tool:expensive_tool") return false; return true; }, }); diff --git a/src/content/docs/how-to/payments/custom-rails.md b/src/content/docs/how-to/payments/custom-rails.md index e0cad7a..d37a65f 100644 --- a/src/content/docs/how-to/payments/custom-rails.md +++ b/src/content/docs/how-to/payments/custom-rails.md @@ -35,10 +35,10 @@ import type { PaymentProcessor, PaymentProcessorCreateParams, PaymentProcessorVerifyParams, -} from '@contextvm/sdk/payments'; +} from "@contextvm/sdk/payments"; export class MyRailPaymentProcessor implements PaymentProcessor { - public readonly pmi = 'my-rail-v1'; + public readonly pmi = "my-rail-v1"; public async createPaymentRequired( params: PaymentProcessorCreateParams, @@ -54,7 +54,7 @@ export class MyRailPaymentProcessor implements PaymentProcessor { return { amount: params.amount, pay_req: JSON.stringify({ - invoiceId: '...', + invoiceId: "...", requestEventId: params.requestEventId, }), description: params.description, @@ -86,10 +86,10 @@ Skeleton: import type { PaymentHandler, PaymentHandlerRequest, -} from '@contextvm/sdk/payments'; +} from "@contextvm/sdk/payments"; export class MyRailPaymentHandler implements PaymentHandler { - public readonly pmi = 'my-rail-v1'; + public readonly pmi = "my-rail-v1"; public async canHandle(_req: PaymentHandlerRequest): Promise { // Optional: enforce client policy (max amount, disabled rail, etc.) diff --git a/src/content/docs/how-to/payments/getting-started.md b/src/content/docs/how-to/payments/getting-started.md index 23254cb..8d40e03 100644 --- a/src/content/docs/how-to/payments/getting-started.md +++ b/src/content/docs/how-to/payments/getting-started.md @@ -17,15 +17,15 @@ If you haven’t set up Nostr transports yet, start with the transport docs firs Define what is paid using `pricedCapabilities`. ```ts -import type { PricedCapability } from '@contextvm/sdk/payments'; +import type { PricedCapability } from "@contextvm/sdk/payments"; export const pricedCapabilities: PricedCapability[] = [ { - method: 'tools/call', - name: 'my-tool', + method: "tools/call", + name: "my-tool", amount: 10, - currencyUnit: 'sats', - description: 'Example paid tool', + currencyUnit: "sats", + description: "Example paid tool", }, ]; ``` @@ -38,8 +38,8 @@ Create a processor, then wrap your server transport. import { LnBolt11NwcPaymentProcessor, withServerPayments, -} from '@contextvm/sdk/payments'; -import { NostrServerTransport } from '@contextvm/sdk/transport'; +} from "@contextvm/sdk/payments"; +import { NostrServerTransport } from "@contextvm/sdk/transport"; const baseTransport = new NostrServerTransport({ signer, @@ -71,8 +71,8 @@ Create a handler and wrap your client transport. import { LnBolt11NwcPaymentHandler, withClientPayments, -} from '@contextvm/sdk/payments'; -import { NostrClientTransport } from '@contextvm/sdk/transport'; +} from "@contextvm/sdk/payments"; +import { NostrClientTransport } from "@contextvm/sdk/transport"; const baseTransport = new NostrClientTransport({ signer, @@ -97,7 +97,7 @@ Any request that matches `pricedCapabilities` will trigger the payment flow. ```ts await client.callTool({ - name: 'my-tool', + name: "my-tool", arguments: { example: true }, }); ``` diff --git a/src/content/docs/how-to/payments/rails/lightning-nwc.md b/src/content/docs/how-to/payments/rails/lightning-nwc.md index 148e937..31fbd86 100644 --- a/src/content/docs/how-to/payments/rails/lightning-nwc.md +++ b/src/content/docs/how-to/payments/rails/lightning-nwc.md @@ -24,7 +24,7 @@ In practice, both the server and the client will have an NWC connection string. ### Server processor ```ts -import { LnBolt11NwcPaymentProcessor } from '@contextvm/sdk/payments'; +import { LnBolt11NwcPaymentProcessor } from "@contextvm/sdk/payments"; const processor = new LnBolt11NwcPaymentProcessor({ nwcConnectionString: process.env.NWC_SERVER_CONNECTION!, @@ -36,7 +36,7 @@ The server-side NWC wallet must be able to **create invoices** and support whate ### Client handler ```ts -import { LnBolt11NwcPaymentHandler } from '@contextvm/sdk/payments'; +import { LnBolt11NwcPaymentHandler } from "@contextvm/sdk/payments"; const handler = new LnBolt11NwcPaymentHandler({ nwcConnectionString: process.env.NWC_CLIENT_CONNECTION!, diff --git a/src/content/docs/how-to/payments/server.md b/src/content/docs/how-to/payments/server.md index 0fda9b8..2a7d5b0 100644 --- a/src/content/docs/how-to/payments/server.md +++ b/src/content/docs/how-to/payments/server.md @@ -17,15 +17,15 @@ For priced requests, the middleware ensures **no unpaid forwarding**. You price individual capabilities by `method` + `name`. ```ts -import type { PricedCapability } from '@contextvm/sdk/payments'; +import type { PricedCapability } from "@contextvm/sdk/payments"; const pricedCapabilities: PricedCapability[] = [ - { method: 'tools/call', name: 'add', amount: 10, currencyUnit: 'sats' }, + { method: "tools/call", name: "add", amount: 10, currencyUnit: "sats" }, { - method: 'resources/read', - name: 'private://*', + method: "resources/read", + name: "private://*", amount: 5, - currencyUnit: 'sats', + currencyUnit: "sats", }, ]; ``` @@ -48,7 +48,7 @@ You can configure multiple processors (multiple PMIs). The server selects a proc import { LnBolt11NwcPaymentProcessor, withServerPayments, -} from '@contextvm/sdk/payments'; +} from "@contextvm/sdk/payments"; const processor = new LnBolt11NwcPaymentProcessor({ nwcConnectionString: process.env.NWC_SERVER_CONNECTION!, @@ -65,7 +65,7 @@ withServerPayments(transport, { `resolvePrice` runs on every priced request and returns the final quote. ```ts -import type { ResolvePriceFn } from '@contextvm/sdk/payments'; +import type { ResolvePriceFn } from "@contextvm/sdk/payments"; const resolvePrice: ResolvePriceFn = async ({ capability, @@ -102,12 +102,12 @@ Guidance: To reject a priced request without creating an invoice, return `{ reject: true, message? }` from `resolvePrice`. ```ts -import type { ResolvePriceFn } from '@contextvm/sdk/payments'; +import type { ResolvePriceFn } from "@contextvm/sdk/payments"; const resolvePrice: ResolvePriceFn = async ({ capability, clientPubkey }) => { const isBlocked = await isUserBlocked(clientPubkey); if (isBlocked) { - return { reject: true, message: 'Access denied' }; + return { reject: true, message: "Access denied" }; } return { amount: capability.amount }; diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx index d375e0e..071625c 100644 --- a/src/content/docs/index.mdx +++ b/src/content/docs/index.mdx @@ -22,9 +22,9 @@ hero: variant: minimal --- -import { CardGrid } from '@astrojs/starlight/components'; -import IconLinkCard from '../../components/IconLinkCard.astro'; -import HeroGetStartedCTAStyles from '../../components/HeroGetStartedCTAStyles.astro'; +import { CardGrid } from "@astrojs/starlight/components"; +import IconLinkCard from "../../components/IconLinkCard.astro"; +import HeroGetStartedCTAStyles from "../../components/HeroGetStartedCTAStyles.astro"; diff --git a/src/content/docs/reference/ceps/cep-41.md b/src/content/docs/reference/ceps/cep-41.md index 258aa03..cd85e01 100644 --- a/src/content/docs/reference/ceps/cep-41.md +++ b/src/content/docs/reference/ceps/cep-41.md @@ -525,4 +525,4 @@ This CEP introduces no breaking changes: ## Reference Implementation -A reference implementation can be found in the ContextVM TS SDK. \ No newline at end of file +A reference implementation can be found in the ContextVM TS SDK. diff --git a/src/content/docs/reference/rs-sdk/client-transport.md b/src/content/docs/reference/rs-sdk/client-transport.md index 588f9f5..db3196c 100644 --- a/src/content/docs/reference/rs-sdk/client-transport.md +++ b/src/content/docs/reference/rs-sdk/client-transport.md @@ -3,7 +3,6 @@ title: "Native Client Guide" description: "ContextVM Rust SDK documentation for Native Client Guide" --- - Use this path when you are building a native ContextVM client in Rust. The recommended architecture is: @@ -174,6 +173,6 @@ Use the proxy guide when you want a simpler message-oriented bridge and do not w - Capability learning and gift-wrap handling happen inside the client transport implementation. - When `relay_urls` is empty, `start()` runs 6-stage relay resolution before connecting: configured relays > nprofile hints > CEP-17 kind 10002 discovery > fallback probing > bootstrap defaults. Callers can set `server_pubkey` to an nprofile and omit `relay_urls` entirely. - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/client-transport.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/client-transport.md)._ diff --git a/src/content/docs/reference/rs-sdk/design.md b/src/content/docs/reference/rs-sdk/design.md index ac2f6bb..7aa082d 100644 --- a/src/content/docs/reference/rs-sdk/design.md +++ b/src/content/docs/reference/rs-sdk/design.md @@ -3,22 +3,22 @@ title: "Architecture & Design" description: "ContextVM Rust SDK documentation for Architecture & Design" --- - **Date:** 2026-03-11 **Status:** Implementation Complete (Phase 1-5) **Reference:** [ContextVM TS SDK](https://github.com/ContextVM/sdk) · [ContextVM Draft Spec](https://contextvm.org) · [Existing Rust crate](https://github.com/k0sti/clarity/tree/main/crates/cvm) ## Verification Summary (2026-03-11) -| Check | Result | -|-------|--------| -| `cargo check` | ✅ Clean (2 unused import warnings) | -| `cargo test` | ✅ 8 unit + 3 doc tests pass | -| `cargo build --examples` | ✅ All 3 examples compile | -| Source LOC | 1,914 across 17 files | -| Tasks complete | 22/22 | +| Check | Result | +| ------------------------ | ----------------------------------- | +| `cargo check` | ✅ Clean (2 unused import warnings) | +| `cargo test` | ✅ 8 unit + 3 doc tests pass | +| `cargo build --examples` | ✅ All 3 examples compile | +| Source LOC | 1,914 across 17 files | +| Tasks complete | 22/22 | ### Remaining Polish + - Fix 2 unused import warnings (`Error` in base.rs, `Instant` in server.rs) - Add more unit tests for transport/gateway/proxy (currently only core + encryption tested) - Integration tests with live relay (requires test relay setup) @@ -74,22 +74,22 @@ rust-contextvm-sdk/ ## Module Mapping: TS SDK → Rust SDK -| TS SDK Module | TS LOC | Rust Module | Source | Status | -|---------------|--------|-------------|--------|--------| -| `core/constants.ts` | 87 | `core/constants.rs` (64 LOC) | Port from existing Rust | ✅ done | -| `core/interfaces.ts` | 61 | `core/types.rs` (188 LOC) | Port from existing Rust | ✅ done | -| `core/encryption.ts` | 64 | `encryption/mod.rs` (86 LOC) | Port from existing Rust | ✅ done | -| `core/utils/serializers.ts` | ~60 | `core/serializers.rs` (74 LOC) | New | ✅ done | -| `core/utils/utils.ts` | ~30 | `core/validation.rs` (64 LOC) | New | ✅ done | -| `relay/simple-relay-pool.ts` | ~100 | `relay/mod.rs` (108 LOC) | Port from existing Rust | ✅ done | -| `signer/private-key-signer.ts` | ~50 | `signer/mod.rs` (15 LOC) | Port from existing Rust | ✅ done | -| `transport/base-nostr-transport.ts` | 355 | `transport/base.rs` (139 LOC) | New | ✅ done | -| `transport/nostr-client-transport.ts` | 411 | `transport/client.rs` (228 LOC) | Rewrite from existing | ✅ done | -| `transport/nostr-server-transport.ts` | 944 | `transport/server.rs` (583 LOC) | Rewrite from existing | ✅ done | -| `gateway/index.ts` | 151 | `gateway/mod.rs` (82 LOC) | New | ✅ done | -| `proxy/index.ts` | 96 | `proxy/mod.rs` (71 LOC) | New | ✅ done | -| *(n/a — new)* | — | `discovery/mod.rs` (154 LOC) | New | ✅ done | -| *(n/a — new)* | — | `core/error.rs` (40 LOC) | New | ✅ done | +| TS SDK Module | TS LOC | Rust Module | Source | Status | +| ------------------------------------- | ------ | ------------------------------- | ----------------------- | ------- | +| `core/constants.ts` | 87 | `core/constants.rs` (64 LOC) | Port from existing Rust | ✅ done | +| `core/interfaces.ts` | 61 | `core/types.rs` (188 LOC) | Port from existing Rust | ✅ done | +| `core/encryption.ts` | 64 | `encryption/mod.rs` (86 LOC) | Port from existing Rust | ✅ done | +| `core/utils/serializers.ts` | ~60 | `core/serializers.rs` (74 LOC) | New | ✅ done | +| `core/utils/utils.ts` | ~30 | `core/validation.rs` (64 LOC) | New | ✅ done | +| `relay/simple-relay-pool.ts` | ~100 | `relay/mod.rs` (108 LOC) | Port from existing Rust | ✅ done | +| `signer/private-key-signer.ts` | ~50 | `signer/mod.rs` (15 LOC) | Port from existing Rust | ✅ done | +| `transport/base-nostr-transport.ts` | 355 | `transport/base.rs` (139 LOC) | New | ✅ done | +| `transport/nostr-client-transport.ts` | 411 | `transport/client.rs` (228 LOC) | Rewrite from existing | ✅ done | +| `transport/nostr-server-transport.ts` | 944 | `transport/server.rs` (583 LOC) | Rewrite from existing | ✅ done | +| `gateway/index.ts` | 151 | `gateway/mod.rs` (82 LOC) | New | ✅ done | +| `proxy/index.ts` | 96 | `proxy/mod.rs` (71 LOC) | New | ✅ done | +| _(n/a — new)_ | — | `discovery/mod.rs` (154 LOC) | New | ✅ done | +| _(n/a — new)_ | — | `core/error.rs` (40 LOC) | New | ✅ done | **TS SDK total:** ~2,169 LOC (non-test) **Existing Rust (reference):** ~782 LOC @@ -121,11 +121,11 @@ tracing-subscriber = "0.3" ## Tasks ### Phase 1: Core Foundation -*Port and enhance existing code. Establish project structure.* + +_Port and enhance existing code. Establish project structure._ - **1.1** Initialize Cargo project with workspace structure and dependencies - **Verify:** `cargo check` passes with empty lib.rs - - **1.2** Port `core/constants.rs` from existing crate - All event kinds (25910, 1059, 11316-11320) - All tag constants (p, e, cap, name, website, picture, about, support_encryption) @@ -177,7 +177,8 @@ tracing-subscriber = "0.3" - **Verify:** Integration test with a local relay (or mock): connect, publish, fetch ### Phase 2: Transport Layer -*The core of the SDK. Implements MCP Transport trait over Nostr.* + +_The core of the SDK. Implements MCP Transport trait over Nostr._ - **2.1** Define Rust `Transport` trait - ```rust @@ -219,7 +220,7 @@ tracing-subscriber = "0.3" - Stateless mode: emulate initialize response locally - Process incoming: decrypt gift wrap → verify server pubkey → correlate → dispatch - Notification handling (no `e` tag → notification) - - **Verify:** + - **Verify:** - Unit test: send request, receive correlated response - Unit test: stateless mode emulates initialize - Unit test: rejects events from wrong server pubkey @@ -246,7 +247,8 @@ tracing-subscriber = "0.3" - Unit test: session cleanup removes stale sessions ### Phase 3: Gateway & Proxy -*Higher-level components that compose transports.* + +_Higher-level components that compose transports._ - **3.1** Implement `NostrMCPGateway` - Takes: local MCP transport (any `Transport`) + NostrServerTransportConfig @@ -274,7 +276,8 @@ tracing-subscriber = "0.3" - Test: messages flow both directions ### Phase 4: Discovery & Announcements -*Server discovery features from the ContextVM spec.* + +_Server discovery features from the ContextVM spec._ - **4.1** Implement server announcement publishing - Publish kind 11316 (server info) with name/about/website/picture/support_encryption tags @@ -296,7 +299,8 @@ tracing-subscriber = "0.3" - **Verify:** After deletion, discovery returns empty ### Phase 5: Examples & Documentation -*Working examples and API docs.* + +_Working examples and API docs._ - **5.1** Create `examples/gateway.rs` - Expose a simple MCP server (echo tool) via Nostr gateway @@ -319,44 +323,44 @@ tracing-subscriber = "0.3" ## Key Differences from Existing Rust Crate -| Aspect | Existing (clarity/crates/cvm) | New SDK | -|--------|-------------------------------|---------| -| MCP types | Raw JSON strings | Typed `JsonRpcMessage` enum with serde | -| Transport trait | None | `Transport` trait matching MCP SDK pattern | -| Base transport | None | `BaseNostrTransport` with shared logic | -| Server dispatch | `handle_event` logs only | Full request correlation + multi-client routing | -| Gateway | None | `NostrMCPGateway` (bidirectional bridge) | -| Proxy | None | `NostrMCPProxy` (bidirectional bridge) | -| Announcements | `announce` + `publish_tools` | All 5 kinds + deletion + discovery | -| Authorization | None | Pubkey whitelist with capability exclusions | -| Encryption negotiation | Enum defined, not enforced | Full mode enforcement per TS SDK | -| Session management | Basic HashMap | Full session with pending requests, progress tokens, cleanup | -| Validation | None | Size + schema validation | -| nostr-sdk version | 0.43 | 0.43 (same) | +| Aspect | Existing (clarity/crates/cvm) | New SDK | +| ---------------------- | ----------------------------- | ------------------------------------------------------------ | +| MCP types | Raw JSON strings | Typed `JsonRpcMessage` enum with serde | +| Transport trait | None | `Transport` trait matching MCP SDK pattern | +| Base transport | None | `BaseNostrTransport` with shared logic | +| Server dispatch | `handle_event` logs only | Full request correlation + multi-client routing | +| Gateway | None | `NostrMCPGateway` (bidirectional bridge) | +| Proxy | None | `NostrMCPProxy` (bidirectional bridge) | +| Announcements | `announce` + `publish_tools` | All 5 kinds + deletion + discovery | +| Authorization | None | Pubkey whitelist with capability exclusions | +| Encryption negotiation | Enum defined, not enforced | Full mode enforcement per TS SDK | +| Session management | Basic HashMap | Full session with pending requests, progress tokens, cleanup | +| Validation | None | Size + schema validation | +| nostr-sdk version | 0.43 | 0.43 (same) | ## Key Differences from TS SDK -| Aspect | TS SDK | Rust SDK | -|--------|--------|----------| -| MCP SDK dependency | `@modelcontextprotocol/sdk` | Own JSON-RPC types (no official Rust MCP SDK) | -| Relay abstraction | `RelayHandler` interface, multiple implementations | `RelayPool` using nostr-sdk Client | -| Async model | Callbacks (`onmessage`, `onerror`, `onclose`) | Callbacks + channels (tokio::mpsc for event streams) | -| Gift wrap | Manual NIP-44 + finalize | nostr-sdk built-in gift_wrap | -| Logging | Pino (JSON) | tracing (structured) | +| Aspect | TS SDK | Rust SDK | +| ------------------ | -------------------------------------------------- | ---------------------------------------------------- | +| MCP SDK dependency | `@modelcontextprotocol/sdk` | Own JSON-RPC types (no official Rust MCP SDK) | +| Relay abstraction | `RelayHandler` interface, multiple implementations | `RelayPool` using nostr-sdk Client | +| Async model | Callbacks (`onmessage`, `onerror`, `onclose`) | Callbacks + channels (tokio::mpsc for event streams) | +| Gift wrap | Manual NIP-44 + finalize | nostr-sdk built-in gift_wrap | +| Logging | Pino (JSON) | tracing (structured) | --- ## Estimation -| Phase | Effort | Dependencies | -|-------|--------|-------------| -| Phase 1: Core | ~4h | None | ✅ Done | -| Phase 2: Transport | ~8h | Phase 1 | ✅ Done | -| Phase 3: Gateway & Proxy | ~3h | Phase 2 | ✅ Done | -| Phase 4: Discovery | ~3h | Phase 2 | ✅ Done | -| Phase 5: Examples & Docs | ~2h | Phase 3+4 | ✅ Done | -| **Total** | **~20h** | | **Complete** | - +| Phase | Effort | Dependencies | +| ------------------------ | -------- | ------------ | ------------ | +| Phase 1: Core | ~4h | None | ✅ Done | +| Phase 2: Transport | ~8h | Phase 1 | ✅ Done | +| Phase 3: Gateway & Proxy | ~3h | Phase 2 | ✅ Done | +| Phase 4: Discovery | ~3h | Phase 2 | ✅ Done | +| Phase 5: Examples & Docs | ~2h | Phase 3+4 | ✅ Done | +| **Total** | **~20h** | | **Complete** | --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/DESIGN.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/DESIGN.md)._ diff --git a/src/content/docs/reference/rs-sdk/discovery.md b/src/content/docs/reference/rs-sdk/discovery.md index 42aaf0a..1801aa1 100644 --- a/src/content/docs/reference/rs-sdk/discovery.md +++ b/src/content/docs/reference/rs-sdk/discovery.md @@ -3,7 +3,6 @@ title: "Discovery" description: "ContextVM Rust SDK documentation for Discovery" --- - The Rust SDK exposes public discovery helpers for finding announced servers and their published capabilities. These functions query public announcement events so clients can find servers before opening a direct session. @@ -89,6 +88,6 @@ The `discovery_relay_urls` and `fallback_operational_relay_urls` config fields c - the current helpers fetch and parse latest public lists, but they do not replace direct session learning - direct session learning still matters for encryption preferences, gift-wrap support, and first-message capability hints on an active connection - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/discovery.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/discovery.md)._ diff --git a/src/content/docs/reference/rs-sdk/encryption.md b/src/content/docs/reference/rs-sdk/encryption.md index 92baddb..ea62025 100644 --- a/src/content/docs/reference/rs-sdk/encryption.md +++ b/src/content/docs/reference/rs-sdk/encryption.md @@ -3,7 +3,6 @@ title: "Encryption" description: "ContextVM Rust SDK documentation for Encryption" --- - ContextVM encryption in this SDK is controlled by `EncryptionMode` and `GiftWrapMode`. At a high level, direct traffic can be sent as plaintext ContextVM events or as encrypted NIP-44 payloads wrapped in gift-wrap events, depending on the configured policy on both peers. @@ -79,6 +78,6 @@ In practice, this matters for: - the first direct server-to-client message - stateless operation - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/encryption.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/encryption.md)._ diff --git a/src/content/docs/reference/rs-sdk/gateway.md b/src/content/docs/reference/rs-sdk/gateway.md index 41b9606..3dddf3e 100644 --- a/src/content/docs/reference/rs-sdk/gateway.md +++ b/src/content/docs/reference/rs-sdk/gateway.md @@ -3,7 +3,6 @@ title: "Gateway" description: "ContextVM Rust SDK documentation for Gateway" --- - `NostrMCPGateway` is the simplest way to expose an MCP server through ContextVM. It wraps `NostrServerTransport`, receives incoming ContextVM requests from Nostr, and lets your application send responses back using the inbound event id. @@ -134,6 +133,6 @@ If your server already uses `rmcp`, the gateway also exposes the associated func That said, the preferred native architecture is still `rmcp` service first and ContextVM transport second. - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/gateway.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/gateway.md)._ diff --git a/src/content/docs/reference/rs-sdk/overview.md b/src/content/docs/reference/rs-sdk/overview.md index 0a2af25..3eea9d9 100644 --- a/src/content/docs/reference/rs-sdk/overview.md +++ b/src/content/docs/reference/rs-sdk/overview.md @@ -3,7 +3,6 @@ title: "Rust SDK Overview" description: "ContextVM Rust SDK documentation for Rust SDK Overview" --- - 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. @@ -24,14 +23,14 @@ This is the same pattern shown by the `rmcp` server and client examples. The onl 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()` | +| 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 @@ -106,6 +105,6 @@ The Rust SDK already implements behavior that users should rely on: 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).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/overview.md)._ diff --git a/src/content/docs/reference/rs-sdk/proxy.md b/src/content/docs/reference/rs-sdk/proxy.md index ce5cf0c..5a2c5f9 100644 --- a/src/content/docs/reference/rs-sdk/proxy.md +++ b/src/content/docs/reference/rs-sdk/proxy.md @@ -3,7 +3,6 @@ title: "Proxy" description: "ContextVM Rust SDK documentation for Proxy" --- - `NostrMCPProxy` is the simplest way to talk to a remote ContextVM server from Rust. It wraps `NostrClientTransport`, gives you a receiver for responses and notifications, and handles transport startup and shutdown. @@ -117,6 +116,6 @@ If you are building on `rmcp`, use the associated function `NostrMCPProxy::serve That said, the preferred native architecture is still `rmcp` client first and ContextVM transport second. - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/proxy.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/proxy.md)._ diff --git a/src/content/docs/reference/rs-sdk/rmcp.md b/src/content/docs/reference/rs-sdk/rmcp.md index 8d6fb6c..e8a14de 100644 --- a/src/content/docs/reference/rs-sdk/rmcp.md +++ b/src/content/docs/reference/rs-sdk/rmcp.md @@ -3,7 +3,6 @@ title: "RMCP Integration" description: "ContextVM Rust SDK documentation for RMCP Integration" --- - For native Rust applications, `rmcp` is the main application layer and ContextVM is the transport layer. The Rust SDK exposes that integration behind the `rmcp` feature and re-exports the `rmcp` crate when that feature is enabled. The bridge lives in the SDK's rmcp transport layer. @@ -47,6 +46,6 @@ The conversion pipeline is covered by the SDK test suite, which tests: - request id preservation through the bridge - event-id based routing assumptions used by the server worker - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/rmcp.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/rmcp.md)._ diff --git a/src/content/docs/reference/rs-sdk/server-transport.md b/src/content/docs/reference/rs-sdk/server-transport.md index 6018768..4af9273 100644 --- a/src/content/docs/reference/rs-sdk/server-transport.md +++ b/src/content/docs/reference/rs-sdk/server-transport.md @@ -3,7 +3,6 @@ title: "Native Server Guide" description: "ContextVM Rust SDK documentation for Native Server Guide" --- - Use this path when you are building a native ContextVM server in Rust. The recommended architecture is: @@ -181,6 +180,6 @@ Use the gateway guide when you already have a request loop or existing local MCP - Encryption mirroring and announcement behavior are covered by the integration tests. - When `is_announced_server` is `true`, the transport auto-publishes all announcement events on `start()` via synthetic MCP requests: kind 11316 (server announcement), kinds 11317-11320 (tools, resources, templates, prompts), kind 10002 (relay list), and kind 0 (profile metadata if configured). - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/server-transport.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/server-transport.md)._ diff --git a/src/content/docs/reference/rs-sdk/stateless.md b/src/content/docs/reference/rs-sdk/stateless.md index 79f036a..995818b 100644 --- a/src/content/docs/reference/rs-sdk/stateless.md +++ b/src/content/docs/reference/rs-sdk/stateless.md @@ -3,7 +3,6 @@ title: "Stateless Mode" description: "ContextVM Rust SDK documentation for Stateless Mode" --- - Stateless mode is a client-side transport behavior enabled through `NostrClientTransportConfig::with_stateless()`. It is designed for flows where the client should behave as if initialization succeeded without waiting for the server to answer over the network. @@ -105,6 +104,6 @@ So even in stateless mode, encryption and ephemeral gift-wrap support can still Because the initialize roundtrip is skipped, stateless mode should be treated as an optimization for compatible workflows, not as a universal replacement for normal MCP startup. - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/stateless.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/stateless.md)._ diff --git a/src/content/docs/reference/rs-sdk/transport-modes.md b/src/content/docs/reference/rs-sdk/transport-modes.md index 7e32d98..013a9bd 100644 --- a/src/content/docs/reference/rs-sdk/transport-modes.md +++ b/src/content/docs/reference/rs-sdk/transport-modes.md @@ -3,7 +3,6 @@ title: "Transport Modes" description: "ContextVM Rust SDK documentation for Transport Modes" --- - This page focuses on the transport behavior switches that are spread across the SDK APIs: - `EncryptionMode` @@ -119,6 +118,6 @@ let stateless_client = NostrClientTransportConfig::default() .with_stateless(true); ``` - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transport-modes.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transport-modes.md)._ diff --git a/src/content/docs/reference/rs-sdk/transports.md b/src/content/docs/reference/rs-sdk/transports.md index 7dba6bc..773fe23 100644 --- a/src/content/docs/reference/rs-sdk/transports.md +++ b/src/content/docs/reference/rs-sdk/transports.md @@ -3,7 +3,6 @@ title: "Transports (Low-Level)" description: "ContextVM Rust SDK documentation for Transports (Low-Level)" --- - Use this page when you want to understand the transport layer itself. If you are building a normal native server or client, start with the dedicated native server or native client guide first. @@ -140,6 +139,6 @@ Incoming traffic is delivered as `IncomingRequest`, which includes: That extra metadata is what allows correct response routing and encryption mirroring. - --- -*This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transports.md).* + +_This page was ported from the [ContextVM Rust SDK repository](https://github.com/ContextVM/rs-sdk/tree/main/docs/transports.md)._ diff --git a/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md b/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md index 6eb0712..8acab5a 100644 --- a/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md +++ b/src/content/docs/reference/ts-sdk/core/common-tool-schemas.md @@ -16,40 +16,42 @@ Use the lower-level utilities on this page when you need to precompute hashes, v The usual integration point is `withCommonToolSchemas()`: ```typescript -import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { NostrServerTransport, PrivateKeySigner, withCommonToolSchemas, -} from '@contextvm/sdk'; +} from "@contextvm/sdk"; const server = new McpServer({ - name: 'translation-server', - version: '1.0.0', + name: "translation-server", + version: "1.0.0", }); server.registerTool( - 'translate_text', + "translate_text", { - description: 'Translate text between languages.', + description: "Translate text between languages.", inputSchema: { - type: 'object', + type: "object", properties: { - text: { type: 'string' }, - target_language: { type: 'string' }, + text: { type: "string" }, + target_language: { type: "string" }, }, - required: ['text', 'target_language'], + required: ["text", "target_language"], }, outputSchema: { - type: 'object', + type: "object", properties: { - translated_text: { type: 'string' }, + translated_text: { type: "string" }, }, - required: ['translated_text'], + required: ["translated_text"], }, }, async ({ text, target_language }) => ({ - content: [{ type: 'text', text: `Translated to ${target_language}: ${text}` }], + content: [ + { type: "text", text: `Translated to ${target_language}: ${text}` }, + ], structuredContent: { translated_text: `Translated to ${target_language}: ${text}`, }, @@ -58,13 +60,13 @@ server.registerTool( const transport = withCommonToolSchemas( new NostrServerTransport({ - signer: new PrivateKeySigner('your-server-private-key'), - relayHandler: ['wss://relay.damus.io'], + signer: new PrivateKeySigner("your-server-private-key"), + relayHandler: ["wss://relay.damus.io"], isAnnouncedServer: true, }), { - tools: [{ name: 'translate_text' }], - categories: ['translation', 'language-tools'], + tools: [{ name: "translate_text" }], + categories: ["translation", "language-tools"], }, ); @@ -110,24 +112,24 @@ The resulting normalized schema is then suitable for deterministic hashing. ## Computing a schema hash ```typescript -import { computeCommonSchemaHash } from '@contextvm/sdk'; +import { computeCommonSchemaHash } from "@contextvm/sdk"; const schemaHash = computeCommonSchemaHash({ - name: 'translate_text', + name: "translate_text", inputSchema: { - type: 'object', + type: "object", properties: { - text: { type: 'string', description: 'Input text' }, - target_language: { type: 'string', title: 'Target language' }, + text: { type: "string", description: "Input text" }, + target_language: { type: "string", title: "Target language" }, }, - required: ['text', 'target_language'], + required: ["text", "target_language"], }, outputSchema: { - type: 'object', + type: "object", properties: { - translated_text: { type: 'string' }, + translated_text: { type: "string" }, }, - required: ['translated_text'], + required: ["translated_text"], }, }); ``` @@ -146,8 +148,8 @@ If you need to verify a schema hash yourself, compute it from the tool definitio import { COMMON_SCHEMA_META_NAMESPACE, computeCommonSchemaHash, -} from '@contextvm/sdk'; -import type { Tool } from '@modelcontextprotocol/sdk/types.js'; +} from "@contextvm/sdk"; +import type { Tool } from "@modelcontextprotocol/sdk/types.js"; function hasMatchingSchemaHash(tool: Tool): boolean { const expectedHash = computeCommonSchemaHash({ diff --git a/src/content/docs/reference/ts-sdk/core/constants.md b/src/content/docs/reference/ts-sdk/core/constants.md index fede072..49212e9 100644 --- a/src/content/docs/reference/ts-sdk/core/constants.md +++ b/src/content/docs/reference/ts-sdk/core/constants.md @@ -44,11 +44,11 @@ The `announcementMethods` object maps capability types to their corresponding MC ```typescript export const announcementMethods = { - server: 'initialize', - tools: 'tools/list', - resources: 'resources/list', - resourceTemplates: 'resources/templates/list', - prompts: 'prompts/list', + server: "initialize", + tools: "tools/list", + resources: "resources/list", + resourceTemplates: "resources/templates/list", + prompts: "prompts/list", } as const; ``` diff --git a/src/content/docs/reference/ts-sdk/core/encryption.md b/src/content/docs/reference/ts-sdk/core/encryption.md index b4fd466..b65d4e5 100644 --- a/src/content/docs/reference/ts-sdk/core/encryption.md +++ b/src/content/docs/reference/ts-sdk/core/encryption.md @@ -36,8 +36,8 @@ The standard implementation of NIP-17 is designed for persistent private message Encryption is configured at the transport level using the `EncryptionMode` enum. You can set the desired mode when creating a `NostrClientTransport` or `NostrServerTransport`. ```typescript -import { NostrClientTransport } from '@contextvm/sdk'; -import { EncryptionMode } from '@contextvm/sdk'; +import { NostrClientTransport } from "@contextvm/sdk"; +import { EncryptionMode } from "@contextvm/sdk"; const transport = new NostrClientTransport({ // ... other options diff --git a/src/content/docs/reference/ts-sdk/core/interfaces.md b/src/content/docs/reference/ts-sdk/core/interfaces.md index ca3bcae..6eef392 100644 --- a/src/content/docs/reference/ts-sdk/core/interfaces.md +++ b/src/content/docs/reference/ts-sdk/core/interfaces.md @@ -74,9 +74,9 @@ The `EncryptionMode` enum defines the encryption policy for a transport. ```typescript export enum EncryptionMode { - OPTIONAL = 'optional', - REQUIRED = 'required', - DISABLED = 'disabled', + OPTIONAL = "optional", + REQUIRED = "required", + DISABLED = "disabled", } ``` diff --git a/src/content/docs/reference/ts-sdk/core/logging.md b/src/content/docs/reference/ts-sdk/core/logging.md index ea7dbca..cead3ff 100644 --- a/src/content/docs/reference/ts-sdk/core/logging.md +++ b/src/content/docs/reference/ts-sdk/core/logging.md @@ -12,13 +12,13 @@ The SDK uses Pino for high-performance logging with structured JSON output. By d [`typescript`](src/content/docs/ts-sdk/core/logging.md:10) ```typescript -import { createLogger } from '@contextvm/sdk/core'; +import { createLogger } from "@contextvm/sdk/core"; // Create a logger for your module -const logger = createLogger('my-module'); +const logger = createLogger("my-module"); -logger.info('Application started'); -logger.error('An error occurred', { error: 'details' }); +logger.info("Application started"); +logger.error("An error occurred", { error: "details" }); ``` #### Configuration Options @@ -26,14 +26,14 @@ logger.error('An error occurred', { error: 'details' }); [`typescript`](src/content/docs/ts-sdk/core/logging.md:20) ```typescript -import { createLogger, LoggerConfig } from '@contextvm/sdk/core'; +import { createLogger, LoggerConfig } from "@contextvm/sdk/core"; const config: LoggerConfig = { - level: 'debug', // Minimum log level (debug, info, warn, error) - file: 'app.log', // Optional: log to a file instead of stderr + level: "debug", // Minimum log level (debug, info, warn, error) + file: "app.log", // Optional: log to a file instead of stderr }; -const logger = createLogger('my-module', config); +const logger = createLogger("my-module", config); ``` **Note:** Pretty printing is automatically enabled when logs are written to stderr/stdout (not to a file) for better readability during development. @@ -72,11 +72,11 @@ LOG_ENABLED=false node app.js ```javascript // Set this in a