diff --git a/.gitignore b/.gitignore index a7e46e7..6906021 100644 --- a/.gitignore +++ b/.gitignore @@ -177,3 +177,4 @@ dist # codebase* .aider* +.prettierrc \ No newline at end of file diff --git a/docs/dvmcp-spec.md b/docs/dvmcp-spec.md new file mode 100644 index 0000000..9d6c6c8 --- /dev/null +++ b/docs/dvmcp-spec.md @@ -0,0 +1,340 @@ +# DVMCP + +### Data Vending Machine Context Protocol + +#### MCP Integration for Data Vending Machines + +`draft` + +This document defines how Data Vending Machines can expose Model Context Protocol (MCP) server capabilities through the Nostr network, enabling standardized access to computational tools for machines and humans. + +## Introduction + +The [Model Context Protocol](https://modelcontextprotocol.io/introduction) provides a robust framework for exposing AI capabilities and tools, while Nostr's Data Vending Machines offer a decentralized marketplace for computational services. This document defines how to bridge these protocols, allowing MCP servers to advertise and provide their services through the Nostr network. + +## Motivation + +While DVMs already provide a framework for computational services, and MCP offers a standardized way to expose AI capabilities, there hasn't been a standardized way to bridge these protocols. This specification aims to: + +1. Enable discovery of MCP services through Nostr's decentralized network +2. Standardize how MCP tools can be exposed as DVM services +3. Provide a consistent experience for users accessing AI capabilities +4. Maintain compatibility with both protocols while preserving their security models + +## Protocol Overview + +There are three main actors in this workflow: + +- Service providers: Entities running MCP servers that expose tools and capabilities +- DVMs: Bridge components that translate between Nostr and MCP protocols +- Customers: Nostr clients that discover and utilize the exposed capabilities + +The protocol consists of four main phases: + +1. Service Discovery: Finding available MCP-enabled DVMs +2. Tool Discovery: Retrieving available tools from a specific DVM +3. Job Execution: Requesting tool execution and receiving results +4. Job Feedback: Handling payment and status updates + +## Event Kinds + +This specification defines how to use existing DVM event kinds (5000-7000) for MCP integration: + +| Kind | Description | +| ---- | ------------------------------- | +| 5000 | Tool discovery request | +| 6000 | Tool catalog response | +| 5001 | Tool execution request | +| 6001 | Tool execution response | +| 7000 | Job feedback and payment status | + +## Service Discovery + +Service providers SHOULD announce their DVM capabilities using NIP-89 handler information events. This enables clients to discover MCP-enabled DVMs through Nostr's existing discovery mechanisms. + +```json +{ + "kind": 31990, + "pubkey": "", + "content": { + "name": "MCP Tools DVM", + "about": "AI and computational tools via MCP" + }, + "tags": [ + ["d", ""], + ["k", "5000"], // Tool discovery + ["k", "5001"], // Tool execution + ["capabilities", "mcp-1.0"], + ["t", "mcp"] + ] +} +``` + +### Required Tags + +- `d`: A unique identifier for this announcement that should be maintained consistently for announcement updates +- `k`: The event kinds this DVM supports (must include 5000 and 5001 for MCP support) +- `capabilities`: Must include "mcp-1.0" to indicate MCP protocol support +- `t`: Should include "mcp" to aid in discovery + +### Tool Discovery Request (kind: 5000) + +Clients discover available tools by sending a kind 5000 event. This initiates the tool discovery process. + +```json +{ + "kind": 5000, + "content": "", + "tags": [ + ["output", "application/json"], + ["bid", ""] + ] +} +``` + +The `p` tag MAY be included to target a specific provider: + +```json +["p", ""] +``` + +### Tool Catalog Response (kind: 6000) + +The DVM MUST respond with a kind 6000 event that lists all available tools and their specifications: + +```json +{ + "kind": 6000, + "content": { + "tools": [ + { + "name": "", + "inputSchema": { + "type": "object", + "properties": { + "text": { + "type": "string", + "description": "Input text to process", + "minLength": 1, + "maxLength": 10000 + }, + "temperature": { + "type": "number", + "description": "Sampling temperature", + "minimum": 0, + "maximum": 2, + "default": 0.7 + }, + "max_tokens": { + "type": "integer", + "description": "Maximum tokens to generate", + "minimum": 1, + "maximum": 2048 + } + }, + "required": ["text"], + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" + } + } + ] + }, + "tags": [["e", ""]] +} +``` + +The tool catalog response preserves the full MCP tool definition format, allowing clients to understand: + +- Required and optional parameters +- Parameter types and constraints +- Expected response formats + +Common parameter and properties types include: + +- `string`: Text input with optional length constraints +- `number`: Floating-point values with optional ranges +- `integer`: Whole numbers with optional ranges +- `boolean`: True/false flags +- `array`: Lists of values with optional item constraints +- `object`: Nested parameter structures + +## Job Execution + +Tools are executed through a request/response pair of events. + +### Job Request (kind: 5001) + +Tools are executed using a kind 5001 event: + +```json +{ + "kind": 5001, + "content": { + "name": "", + "parameters": { + "text": "The input text to be processed", + "temperature": 0.8, + "max_tokens": 1024 + } + }, + "tags": [["p", ""]] +} +``` + +The content object MUST include: + +- `name`: The name of the tool to execute +- `parameters`: An object matching the tool's inputSchema + +The content object MAY include: + +- `timeout`: Maximum execution time in milliseconds +- `metadata`: Additional execution context + +### Job Response (kind: 6001) + +```json +{ + "kind": 6001, + "content": { + "content": [ + { + "type": "text", + "text": "Primary response text" + }, + { + "type": "text", + "text": "Secondary response text" + }, + { + "type": "image/svg+xml", + "text": "..." + } + ], + "isError": false, + "metadata": { + "processing_time": 1.23, + "token_count": 150 + } + }, + "tags": [ + ["e", ""], + ["status", "success"] + ] +} +``` + +The response content MUST include: + +- `content`: An array of content blocks from the MCP tool execution +- `isError`: Boolean indicating if an error occurred + +The response content MAY include: + +- `metadata`: Additional context about the execution + +Each content block MUST specify: + +- `type`: The MIME type of the content +- `text`: The actual content data + +## Job Feedback + +DVMs use kind 7000 events to provide updates about job status and payment requirements. This enables proper handling of long-running jobs and payment flows. + +```json +{ + "kind": 7000, + "content": "", + "tags": [ + ["status", "", ""], + ["amount", "", ""], + ["e", "", ""], + ["p", ""] + ] +} +``` + +### Status Values + +The `status` tag MUST use one of these values: + +- `payment-required`: Payment needed before execution +- `processing`: Job is being processed +- `error`: Job failed to process +- `success`: Job completed successfully +- `partial`: Job partially completed + +### Payment Flow + +A typical payment flow proceeds as follows: + +1. Client submits job request +2. DVM responds requesting payment +3. Client pays the invoice +4. DVM processes the job +5. DVM returns results + +## Error Handling + +DVMs MUST handle both protocol and execution errors appropriately: + +### Protocol Errors + +- Invalid request format +- Missing required parameters +- Parameter validation failures +- Unknown tool requests + +### Execution Errors + +- MCP server connection failures +- Tool execution timeouts +- Resource exhaustion +- Internal errors + +For any error, DVMs MUST: + +1. Send a kind 7000 event with status "error" +2. Include relevant error details in the content +3. Set isError=true in any kind 6001 response + +## Implementation Requirements + +DVMs implementing this protocol MUST: + +1. Properly handle MCP server initialization and capability negotiation +2. Transform tool definitions and parameters between MCP and DVM formats +3. Validate all parameters against the published schema +4. Implement appropriate job feedback and error handling +5. Follow NIP-89 for service registration +6. Handle payment flows securely +7. Maintain proper state during long-running operations +8. Implement appropriate timeouts and resource limits + +## Complete Protocol Flow + +```mermaid +sequenceDiagram + participant Client as Nostr Client + participant Relay as Nostr Relay + participant DVM as MCP-DVM Bridge + participant Server as MCP Server + + Client->>Relay: Query kind:31990 + Relay-->>Client: DVM handler info + + Client->>DVM: kind:5000 (List Tools) + DVM->>Server: Initialize + Get Tools + Server-->>DVM: Tool Definitions + DVM-->>Client: kind:6000 (Tool Catalog) + + Client->>DVM: kind:5001 (Execute Tool) + DVM-->>Client: (Optional)kind:7000 (payment-required) + Client->>DVM: Payment + DVM-->>Client: kind:7000 (processing) + DVM->>Server: Execute Tool + Server-->>DVM: Results + DVM-->>Client: kind:7000 (success) + DVM-->>Client: kind:6001 (Results) +``` diff --git a/package.json b/package.json index 5bcc777..ab10a6b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "module": "src/dvm-bridge.ts", "type": "module", "scripts": { - "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"", + "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", "dev": "bun --watch src/dvm-bridge.ts", "start": "bun run src/dvm-bridge.ts", "typecheck": "tsc --noEmit", @@ -22,4 +22,4 @@ "nostr-tools": "^2.10.4", "prettier": "^3.4.2" } -} \ No newline at end of file +} diff --git a/src/nostr/announcer.ts b/src/nostr/announcer.ts index f20475e..ab8a3a0 100644 --- a/src/nostr/announcer.ts +++ b/src/nostr/announcer.ts @@ -17,7 +17,7 @@ export class NostrAnnouncer { about: CONFIG.mcp.about, }), tags: [ - ['d', Math.random().toString(36).substring(7)], + ['d', 'dvm-announcement'], ['k', '5000'], ['k', '5001'], ['capabilities', 'mcp-1.0'],