Loading...
Loading...
Build MCP servers that expose capabilities over the Nostr network using ContextVM. Use when creating new servers, converting existing MCP servers to ContextVM, configuring server transports, implementing access control, or setting up public server announcements.
npx skill4agent add contextvm/cvmi server-dev@contextvm/sdkimport { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { NostrServerTransport } from "@contextvm/sdk";
import { PrivateKeySigner } from "@contextvm/sdk";
import { ApplesauceRelayPool } from "@contextvm/sdk";
const signer = new PrivateKeySigner(process.env.SERVER_PRIVATE_KEY!);
const relayPool = new ApplesauceRelayPool([
"wss://relay.contextvm.org",
"wss://cvm.otherstuff.ai",
]);
const server = new McpServer({
name: "my-server",
version: "1.0.0",
});
// Register tools
server.registerTool(
"echo",
{ description: "Echo back the input" },
async ({ message }) => ({
content: [{ type: "text", text: `Echo: ${message}` }],
}),
);
const transport = new NostrServerTransport({
signer,
relayHandler: relayPool,
serverInfo: {
name: "My ContextVM Server",
website: "https://example.com",
},
});
await server.connect(transport);
console.log("Server running on Nostr");| Option | Type | Description |
|---|---|---|
| | Required. Signs all Nostr events |
| | Required. Relay connection manager. |
| | Optional. Metadata for announcements |
| | Publish server announcements. Default: |
| | Whitelist client public keys |
| | Bypass whitelist for specific methods |
| | Inject client pubkey into |
| | |
const transport = new NostrServerTransport({
signer,
relayHandler: relayPool,
allowedPublicKeys: ["client1-pubkey-hex", "client2-pubkey-hex"],
});const transport = new NostrServerTransport({
signer,
relayHandler: relayPool,
allowedPublicKeys: ["trusted-client"],
excludedCapabilities: [
{ method: "tools/list" }, // Anyone can list tools
{ method: "tools/call", name: "public_tool" }, // Specific tool is public
],
});const transport = new NostrServerTransport({
signer,
relayHandler: relayPool,
isPublicServer: true,
serverInfo: {
name: "Weather Service",
about: "Get weather data worldwide",
website: "https://weather.example.com",
},
});const transport = new NostrServerTransport({
signer,
relayHandler: relayPool,
injectClientPubkey: true,
});
// In your tool handler, access _meta.clientPubkey
server.registerTool("personalized", {...}, async (args, extra) => {
const clientPubkey = extra._meta?.clientPubkey;
// Use pubkey for personalization, rate limiting, etc.
});assets/server-template.tsnpxnpx @modelcontextprotocol/inspector <command>NostrServerTransportreferences/debugging-inspector.mdreferences/transport-config.mdreferences/security-patterns.mdreferences/gateway-pattern.md