From 8f7afc1273b33739addbb010baa5856a0bb4d8a3 Mon Sep 17 00:00:00 2001 From: Ludovic Levalleux Date: Fri, 5 Jun 2026 09:46:00 +0100 Subject: [PATCH 1/4] feat(xmtp)!: adopt self-deployed XMTP MCP server (chat-sdk v2) chat-sdk PR #103 removes the publicly hosted XMTP MCP deployment and sources the wallet key from the server's BOSON_XMTP_PRIVATE_KEY env instead of tool args. The plugin options are now a discriminated union: { stdio: true; privateKey } | { http: true; url }. - Bump @bosonprotocol/chat-sdk 1.4.5 -> 2.0.0 - src/examples/xmtp/index.ts: drop the hosted-URL (staging/production) validation; XMTP_BOSON_MCP_URL is now optional and selects transport - stdio by default (spawns `npx boson-xmtp-mcp-server` locally, forwarding PRIVATE_KEY as BOSON_XMTP_PRIVATE_KEY) or self-hosted HTTP when set - .env.example, example README, root README: document the self-deploy model (stdio default + optional HTTP self-host) and remove the Cloud Run URLs Co-Authored-By: Claude Opus 4.8 --- README.md | 4 ++- package-lock.json | 8 +++--- package.json | 2 +- src/examples/xmtp/.env.example | 14 ++++++---- src/examples/xmtp/README.md | 50 ++++++++++++++++++++++++++++------ src/examples/xmtp/index.ts | 44 ++++++++++++------------------ 6 files changed, 77 insertions(+), 45 deletions(-) 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..b03f4f7 100644 --- a/src/examples/xmtp/README.md +++ b/src/examples/xmtp/README.md @@ -9,19 +9,53 @@ 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 +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` and `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..67eee26 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,23 @@ 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); + console.log( + `XMTP MCP transport: ${xmtpBosonMcpUrl ? `http (${xmtpBosonMcpUrl})` : "stdio (local subprocess)"}`, + ); + const bosonTools = await getOnChainTools({ wallet: viem(walletClient), plugins: [ bosonProtocolPlugin({ url: bosonMcpUrl }), - bosonProtocolXmtpPlugin({ - privateKey, - http: true, - url: xmtpBosonMcpUrl, - }), + bosonProtocolXmtpPlugin(xmtpPluginOptions), ], }); From 915881464d809f276adc9a01066dc229b5efef25 Mon Sep 17 00:00:00 2001 From: Ludovic Levalleux Date: Fri, 5 Jun 2026 09:54:44 +0100 Subject: [PATCH 2/4] fix(xmtp): log XMTP MCP transport type only, not the URL Printing the full XMTP_BOSON_MCP_URL could leak credentials (basic auth, signed query params) or internal hostnames into logs/CI output. Log only the transport type instead. Addresses PR #49 review comment r3361515213. Co-Authored-By: Claude Opus 4.8 --- src/examples/xmtp/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/examples/xmtp/index.ts b/src/examples/xmtp/index.ts index 67eee26..df83a1d 100644 --- a/src/examples/xmtp/index.ts +++ b/src/examples/xmtp/index.ts @@ -129,8 +129,10 @@ async function main() { 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 (${xmtpBosonMcpUrl})` : "stdio (local subprocess)"}`, + `XMTP MCP transport: ${xmtpBosonMcpUrl ? "http (self-hosted)" : "stdio (local subprocess)"}`, ); const bosonTools = await getOnChainTools({ From 89103b1febd9d29ee862296f3a4bf235b5ad7bfb Mon Sep 17 00:00:00 2001 From: Ludovic Levalleux Date: Fri, 5 Jun 2026 10:00:50 +0100 Subject: [PATCH 3/4] docs(xmtp): link chat-sdk self-hosting and security docs The references to docs/mcp-self-hosting.md and SECURITY.md were bare paths; those files live in the chat-sdk repo, not here, so readers got stuck. Link them directly to the pinned v2.0.0 tag (the version this example depends on). Addresses PR #49 review comment r3361515246. Co-Authored-By: Claude Opus 4.8 --- src/examples/xmtp/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/examples/xmtp/README.md b/src/examples/xmtp/README.md index b03f4f7..da3ad79 100644 --- a/src/examples/xmtp/README.md +++ b/src/examples/xmtp/README.md @@ -54,8 +54,11 @@ Then point this example at your private URL: XMTP_BOSON_MCP_URL=http://127.0.0.1:3000/mcp ``` -See chat-sdk's `docs/mcp-self-hosting.md` and `SECURITY.md` for the authoritative -run instructions and security guidance. +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. --- From 5f1ffc9d21eb7fe3b11839e3570611e5316b0dde Mon Sep 17 00:00:00 2001 From: "Ludo Levalleux (LX Foundry)" Date: Fri, 5 Jun 2026 10:36:03 +0100 Subject: [PATCH 4/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/examples/xmtp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples/xmtp/README.md b/src/examples/xmtp/README.md index da3ad79..6af3735 100644 --- a/src/examples/xmtp/README.md +++ b/src/examples/xmtp/README.md @@ -44,7 +44,7 @@ Run your own long-running server, bound to localhost, with the wallet key supplied as a secret in its environment: ```bash -BOSON_XMTP_PRIVATE_KEY= npx boson-xmtp-mcp-server --http +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.