diff --git a/README.md b/README.md index e6cde1a..9d1111c 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,9 @@ BOSON_MCP_URL=https://mcp-staging.bosonprotocol.io/mcp # Platform-specific TG_BOT_TOKEN=your_telegram_bot_token # For Telegram examples -XMTP_BOSON_MCP_URL=your_xmtp_mcp_server_url # For XMTP examples - MCP server URL for XMTP interactions +# XMTP_BOSON_MCP_URL is OPTIONAL: only set it to your own self-hosted XMTP MCP +# server URL. Leave it unset to run the server locally over stdio (the default). +# XMTP_BOSON_MCP_URL=http://127.0.0.1:3000/mcp # For XMTP examples - self-hosted HTTP server ``` ## Documentation diff --git a/package-lock.json b/package-lock.json index 8e3bd28..eda7bde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ ], "dependencies": { "@bosonprotocol/agentic-commerce": "1.2.5", - "@bosonprotocol/chat-sdk": "1.4.5", + "@bosonprotocol/chat-sdk": "2.0.0", "@bosonprotocol/common": "1.32.2", "dotenv": "^17.2.1", "grammy": "^1.38.1", @@ -538,9 +538,9 @@ "license": "MIT" }, "node_modules/@bosonprotocol/chat-sdk": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@bosonprotocol/chat-sdk/-/chat-sdk-1.4.5.tgz", - "integrity": "sha512-EjeaSRay3SGQJUMzPPfewk3bP13rleumoLbBD7L03i+u3Pv2NiF7z1gotTNMiYuDUitmttowakXcjNL9zjg1mQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bosonprotocol/chat-sdk/-/chat-sdk-2.0.0.tgz", + "integrity": "sha512-bXSH6bksSlDj9Kv+Vh7uEk5/aTqnMUctqHVmXWnwl3m+epdMxjyfaPy8nK49MY7S2E5zSqEBw40MgY9LDGrD+g==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 005c38e..faccbaa 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ }, "dependencies": { "@bosonprotocol/agentic-commerce": "1.2.5", - "@bosonprotocol/chat-sdk": "1.4.5", + "@bosonprotocol/chat-sdk": "2.0.0", "@bosonprotocol/common": "1.32.2", "dotenv": "^17.2.1", "grammy": "^1.38.1", diff --git a/src/examples/xmtp/.env.example b/src/examples/xmtp/.env.example index fd74609..7d93bf0 100644 --- a/src/examples/xmtp/.env.example +++ b/src/examples/xmtp/.env.example @@ -32,11 +32,15 @@ BOSON_MCP_URL=https://mcp-staging.bosonprotocol.io/mcp # =============================== # 🛠 Boson XMTP MCP Server Config # =============================== - -# For testing with staging MCP server -XMTP_BOSON_MCP_URL=https://boson-xmtp-mcp-server-staging-408914412794.europe-west2.run.app/mcp -# or this url for production -# XMTP_BOSON_MCP_URL=https://boson-xmtp-mcp-server-production-408914412794.europe-west2.run.app/mcp +# The XMTP MCP server is no longer publicly hosted — you deploy it yourself. +# +# Default (stdio): leave XMTP_BOSON_MCP_URL UNSET. The example spawns +# `npx boson-xmtp-mcp-server` locally and forwards PRIVATE_KEY to it as +# BOSON_XMTP_PRIVATE_KEY automatically. +# +# Optional (self-hosted HTTP): run your own server (see README.md), then point +# the example at your PRIVATE url: +# XMTP_BOSON_MCP_URL=http://127.0.0.1:3000/mcp diff --git a/src/examples/xmtp/README.md b/src/examples/xmtp/README.md index 8187ef2..6af3735 100644 --- a/src/examples/xmtp/README.md +++ b/src/examples/xmtp/README.md @@ -9,19 +9,56 @@ This project demonstrates how to interact with the Boson MCP Server plugin and s Copy the example environment file and fill in your secrets: You'll need to set: -- `PRIVATE_KEY` → Your blockchain wallet private key (for Boson MCP tools). +- `PRIVATE_KEY` → Your blockchain wallet private key (for Boson MCP tools). In + stdio mode this key is also handed to the local XMTP MCP server. - `ANTHROPIC_API_KEY` → API key from Anthropic Console. - `BOSON_MCP_URL` → MCP server endpoint (staging or production). - `CHAIN_ID` → Chain ID matching chainId from configId. -- `XMTP_BOSON_MCP_URL` → XMTP MCP server endpoint. +- `XMTP_BOSON_MCP_URL` → _Optional._ URL of **your own** self-hosted XMTP MCP + HTTP server. Leave it unset to run the server locally over stdio (the default). -👉 **XMTP Environment Setup**: -The system validates your XMTP MCP URL environment: +--- + +## 🚀 Deploy the XMTP MCP Server + +As of [chat-sdk #103](https://github.com/bosonprotocol/chat-sdk/pull/103) the +XMTP MCP server is **no longer publicly hosted** — you must run it yourself. The +server acts on behalf of a wallet and needs its private key, so never expose it +to unauthenticated access or point clients at a shared/public instance. + +There are two ways to run it: + +### Stdio (default, recommended) + +Nothing extra to configure. Leave `XMTP_BOSON_MCP_URL` **unset** and the example +spawns the server as a local subprocess via `npx boson-xmtp-mcp-server`, passing +your `PRIVATE_KEY` to it as `BOSON_XMTP_PRIVATE_KEY` automatically. + +The `boson-xmtp-mcp-server` binary (and the Playwright browsers it needs at +runtime) ship with `@bosonprotocol/chat-sdk`, which is already installed as a +dependency of this repo — so no separate install is required. + +### HTTP (optional, self-hosted) + +Run your own long-running server, bound to localhost, with the wallet key +supplied as a secret in its environment: + +```bash +PORT=3000 START=true BOSON_XMTP_PRIVATE_KEY= npx boson-xmtp-mcp-server --http +``` + +You can also run it via the `docker-compose.yml` shipped in the chat-sdk repo. +Then point this example at your private URL: + +```env +XMTP_BOSON_MCP_URL=http://127.0.0.1:3000/mcp +``` -Production: Must include "production" in the URL -Staging: Must include "staging" in the URL -Testing: https://chat-sdk-408914412794.europe-west1.run.app/mcp -Local: URLs containing "localhost" or "127.0.0.1" +See chat-sdk's +[docs/mcp-self-hosting.md](https://github.com/bosonprotocol/chat-sdk/blob/v2.0.0/docs/mcp-self-hosting.md) +and +[SECURITY.md](https://github.com/bosonprotocol/chat-sdk/blob/v2.0.0/SECURITY.md) +for the authoritative run instructions and security guidance. --- diff --git a/src/examples/xmtp/index.ts b/src/examples/xmtp/index.ts index dffb040..df83a1d 100644 --- a/src/examples/xmtp/index.ts +++ b/src/examples/xmtp/index.ts @@ -11,28 +11,12 @@ import { privateKeyToAccount } from "viem/accounts"; import { BOSON_MCP_URL, CHAIN_MAP } from "#common/chains.js"; +// The XMTP MCP server is no longer publicly hosted: you deploy it yourself. +// Leave XMTP_BOSON_MCP_URL unset to run the server locally over stdio (the +// plugin spawns `npx boson-xmtp-mcp-server` and forwards your PRIVATE_KEY to it +// as BOSON_XMTP_PRIVATE_KEY). Set it to the URL of your own self-hosted HTTP +// server to use HTTP transport instead. const xmtpBosonMcpUrl = process.env.XMTP_BOSON_MCP_URL; -const isStagingXMTP = xmtpBosonMcpUrl?.includes("staging"); -const isTestingXMTP = - xmtpBosonMcpUrl === "https://chat-sdk-408914412794.europe-west1.run.app/mcp"; -const isLocalXMTP = - xmtpBosonMcpUrl?.includes("localhost") || - xmtpBosonMcpUrl?.includes("127.0.0.1"); - -if (!xmtpBosonMcpUrl) { - throw new Error("XMTP_BOSON_MCP_URL environment variable is required"); -} - -if ( - !isTestingXMTP && - !isLocalXMTP && - !isStagingXMTP && - !xmtpBosonMcpUrl?.includes("production") -) { - throw new Error( - "XMTP_BOSON_MCP_URL must include 'production' for production environment or 'staging' for staging environment", - ); -} async function multilineInput(message: string): Promise { console.log(message); @@ -137,15 +121,25 @@ async function main() { process.exit(1); } + // Select the XMTP MCP transport: a self-hosted HTTP server when + // XMTP_BOSON_MCP_URL is provided, otherwise spawn the server locally over + // stdio. In stdio mode the plugin forwards `privateKey` to the spawned server + // as BOSON_XMTP_PRIVATE_KEY; in HTTP mode the self-hosted server holds its own + // key, so none is passed here. + const xmtpPluginOptions = xmtpBosonMcpUrl + ? ({ http: true, url: xmtpBosonMcpUrl } as const) + : ({ stdio: true, privateKey } as const); + // Log only the transport type — never the URL, which may carry credentials, + // signed query params, or internal hostnames. + console.log( + `XMTP MCP transport: ${xmtpBosonMcpUrl ? "http (self-hosted)" : "stdio (local subprocess)"}`, + ); + const bosonTools = await getOnChainTools({ wallet: viem(walletClient), plugins: [ bosonProtocolPlugin({ url: bosonMcpUrl }), - bosonProtocolXmtpPlugin({ - privateKey, - http: true, - url: xmtpBosonMcpUrl, - }), + bosonProtocolXmtpPlugin(xmtpPluginOptions), ], });