Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
14 changes: 9 additions & 5 deletions src/examples/xmtp/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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



53 changes: 45 additions & 8 deletions src/examples/xmtp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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=<your_wallet_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.

---

Expand Down
46 changes: 20 additions & 26 deletions src/examples/xmtp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string | null> {
console.log(message);
Expand Down Expand Up @@ -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)"}`,
);
Comment thread
levalleux-ludo marked this conversation as resolved.

const bosonTools = await getOnChainTools({
wallet: viem(walletClient),
plugins: [
bosonProtocolPlugin({ url: bosonMcpUrl }),
bosonProtocolXmtpPlugin({
privateKey,
http: true,
url: xmtpBosonMcpUrl,
}),
bosonProtocolXmtpPlugin(xmtpPluginOptions),
],
});

Expand Down
Loading