You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
extra_common_tags and pricing_tags setters on transport
Add d tag to all replaceable events — not needed. Kinds 11316–11320 are standard replaceable (10000–19999 per NIP-01), replaced by pubkey+kind only. TS SDK doesn't add one either.
Schema-to-kind mapping: define AnnouncementMapping that maps MCP response schemas to Nostr event kinds (InitializeResult → 11316, ListToolsResult → 11317, ListResourcesResult → 11318, ListResourceTemplatesResult → 11319, ListPromptsResult → 11320) (feat: auto-publish server announcements on start (CEP-6) #78 )
publish_public_announcements(): send synthetic MCP requests (initialize, tools/list, resources/list, resourceTemplates/list, prompts/list) with sentinel id 'announcement' and publish results as Nostr events (feat: auto-publish server announcements on start (CEP-6) #78 )
This issue tracks closing the gap with the TS SDK's CEP-6 implementation, using the spec and TS SDK
AnnouncementManageras the reference.Supersedes #59 which had a higher-level plan.
1. Core data structures (foundation)
SERVER_ANNOUNCEMENT_KIND(11316),TOOLS_LIST_KIND(11317),RESOURCES_LIST_KIND(11318),RESOURCETEMPLATES_LIST_KIND(11319),PROMPTS_LIST_KIND(11320) in
src/core/constants.rsNAME,ABOUT,WEBSITE,PICTURE,SUPPORT_ENCRYPTION,SUPPORT_ENCRYPTION_EPHEMERALinsrc/core/constants.rsDEFAULT_BOOTSTRAP_RELAY_URLSconstant (6 relay URLs for CEP-17 discoverability) insrc/core/constants.rsUNENCRYPTED_KINDSarray containing all 5 announcement kinds insrc/core/constants.rsServerInfostruct with builder pattern (name,version,picture,website,about) insrc/core/types.rsServerAnnouncementstruct for client-side parsing (pubkey,server_info,event_id,created_at) insrc/discovery/mod.rsis_announced_server: boolconfig flag inNostrServerTransportConfigProfileMetadatastruct withname,about,picture,banner,website,nip05,lud16+#[serde(flatten)] extrafor custom fields (CEP-23) (feat: add ProfileMetadata type and update ServerAnnouncement parsing (CEP-6) #77)- not needed. We serialize rmcp's rawServerAnnouncementContentstructInitializeResultdirectly as kind 11316 content, same as the TS SDK.2. Server-side announcement publishing
announce()→ kind 11316 withServerInfocontent + common tagspublish_tools(Vec<serde_json::Value>)→ kind 11317publish_resources(Vec<serde_json::Value>)→ kind 11318publish_prompts(Vec<serde_json::Value>)→ kind 11320publish_resource_templates(Vec<serde_json::Value>)→ kind 11319delete_announcements(reason)→ NIP-09 kind 5 for all announcement kindspublish_tools_typed(),publish_resources_typed(),publish_prompts_typed(),publish_resource_templates_typed()extra_common_tagsandpricing_tagssetters on transportAdd— not needed. Kinds 11316–11320 are standard replaceable (10000–19999 per NIP-01), replaced by pubkey+kind only. TS SDK doesn't add one either.dtag to all replaceable eventsInitializeResultas kind 11316 content (protocol_version,capabilities,server_info,instructions) instead ofServerInfoonly (feat: auto-publish server announcements on start (CEP-6) #78 )3. Client-side discovery
discover_servers()→ fetches kind 11316, returnsVec<ServerAnnouncement>discover_tools()→ fetches kind 11317discover_resources()→ fetches kind 11318discover_prompts()→ fetches kind 11320discover_resource_templates()→ fetches kind 11319discover_tools_typed(),discover_resources_typed(),discover_prompts_typed(),discover_resource_templates_typed()ServerAnnouncementparsing to handleServerAnnouncementContent(extractprotocol_version,capabilitiesalongsideserver_info) (feat: add ProfileMetadata type and update ServerAnnouncement parsing (CEP-6) #77 )4. Discovery tag emission & learning (done via CEP-35)
get_common_tags()helper: builds server info + capability tags from config (feat: add tag composition, server discovery tag emission and capability learning for CEP-35 #57)take_pending_server_discovery_tags(session): returns common tags on first response per client, empty after (feat: add tag composition, server discovery tag emission and capability learning for CEP-35 #57)send_response()andsend_notification(): include discovery tags on first message to each client (feat: add tag composition, server discovery tag emission and capability learning for CEP-35 #57)support_encryptionandsupport_encryption_ephemeralcapability tags auto-added (feat: add tag composition, server discovery tag emission and capability learning for CEP-35 #57)learn_peer_capabilities()on inbound event tags, OR-assign toClientSession(feat: add tag composition, server discovery tag emission and capability learning for CEP-35 #57)5. AnnouncementManager orchestrator
AnnouncementManagerstruct (refactor: extract AnnouncementManager from NostrServerTransport (CEP-35) #74)get_server_info_tags(),get_capability_tags(),get_common_tags()with caching and cache invalidation (refactor: extract AnnouncementManager from NostrServerTransport (CEP-35) #74)set_extra_common_tags(),set_internal_common_tags(),set_pricing_tags()on manager (refactor: extract AnnouncementManager from NostrServerTransport (CEP-35) #74)announce(),publish_tools(), etc. to delegate toAnnouncementManager(refactor: extract AnnouncementManager from NostrServerTransport (CEP-35) #74)AnnouncementMappingthat maps MCP response schemas to Nostr event kinds (InitializeResult→ 11316,ListToolsResult→ 11317,ListResourcesResult→ 11318,ListResourceTemplatesResult→ 11319,ListPromptsResult→ 11320) (feat: auto-publish server announcements on start (CEP-6) #78 )publish_public_announcements(): send synthetic MCP requests (initialize,tools/list,resources/list,resourceTemplates/list,prompts/list) with sentinel id'announcement'and publish results as Nostr events (feat: auto-publish server announcements on start (CEP-6) #78 )handle_announcement_response(message): intercept responses with sentinel id, validate against schema, map to event kind, callpublish_announcement_event()(feat: auto-publish server announcements on start (CEP-6) #78 )is_announced_server: true— spawn announcement task instart()(feat: auto-publish server announcements on start (CEP-6) #78 )6. Relay list & profile metadata publishing
publish_relay_list()→ kind 10002 (NIP-65): empty content, tags =[["r", relay_url], ...]for each configured relay (feat: relay list and profile metadata publishing (CEP-6) #79 )get_discoverability_publish_relay_urls(): merge configured + bootstrap relay URLs, deduplicate (feat: relay list and profile metadata publishing (CEP-6) #79 )ws://127.0.0.1:*) (feat: relay list and profile metadata publishing (CEP-6) #79 )bootstrap_relay_urlswith opt-out (publish_relay_list: false) (feat: relay list and profile metadata publishing (CEP-6) #79 )publish_profile_metadata()→ kind 0 (NIP-01 / CEP-23): content = JSON-serializedProfileMetadata, empty tags (opt-in via config) (feat: relay list and profile metadata publishing (CEP-6) #79 )7. Tests
- not needed (see section 2)dtag presence verificationInitializeResultcontent serialization/deserialization roundtrip (feat: add ProfileMetadata type and update ServerAnnouncement parsing (CEP-6) #77 )announce: truetriggers synthetic requests and event publishing on start (feat: auto-publish server announcements on start (CEP-6) #78 )Reference
contextvm-docs/src/content/docs/spec/ceps/cep-6.mdAnnouncementManager:sdk/src/transport/nostr-server/announcement-manager.ts(721 LOC, 17 tests)SessionStore:sdk/src/transport/nostr-server/session-store.ts(hasSentCommonTagstracking)sdk/src/core/constants.ts(event kinds 11316–11320)src/transport/server/mod.rs:669-897(publish methods + tag helpers)src/discovery/mod.rs(client-side discovery API)src/core/constants.rs(kinds + tags)src/core/types.rs(ServerInfo,ClientSession)