```
Requires payment before executing a tool. This function must be called before any paid tool logic.
The `requirePayment` function uses BigNumber for precise decimal arithmetic. Install it with `npm install bignumber.js` and import it as shown above.
**Arguments**
The price to charge in USDC. See [BigNumber](https://mikemcl.github.io/bignumber.js/) for BigNumber usage details.
A function that returns the ID of an existing payment for the tool call. If not provided, a new payment will be created.
**Example usage**
```typescript theme={null}
import { requirePayment } from '@atxp/server'
import BigNumber from 'bignumber.js'
server.tool(
"add",
"Use this tool to add two numbers together.",
{
a: z.number().describe("The first number to add"),
b: z.number().describe("The second number to add"),
},
async ({ a, b }) => {
// Require payment for the tool call
await requirePayment({price: BigNumber(0.01)});
return {
content: [
{
type: "text",
text: `${a + b}`,
},
],
};
}
);
```
# @atxp/solana
Source: https://docs.atxp.ai/developers/api-reference/solana
API reference for the @atxp/solana package
## Overview
The `@atxp/solana` package provides Solana account implementations for using ATXP on the Solana blockchain. This package was extracted from `@atxp/client` in v0.9.0 to create a modular architecture with reduced dependencies.
**New in v0.9.0**: Solana functionality has been moved to this dedicated package. Users must now install `@atxp/solana` separately along with required Solana dependencies.
## Installation
```bash theme={null}
npm install @atxp/solana
```
### Required Dependencies
You'll also need to install Solana's peer dependencies:
```bash theme={null}
npm install @solana/web3.js @solana/pay bs58
```
## SolanaAccount
The main class for managing Solana accounts with ATXP.
### Constructor
```typescript theme={null}
SolanaAccount(
solanaRpcUrl: string,
sourceSecretKey: string
): SolanaAccount
```
Creates a Solana account object that can be used with ATXP clients for making payments on the Solana blockchain.
**Arguments**
The Solana RPC endpoint URL (e.g., `https://api.mainnet-beta.solana.com` for mainnet or `https://api.devnet.solana.com` for devnet).
The private key for the Solana account in base58 format. This account will be used to sign transactions and pay for MCP server calls.
**Returns**
Returns a configured SolanaAccount instance ready for use with ATXP clients.
**Example Usage**
```typescript theme={null}
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a Solana account
const account = new SolanaAccount(solanaRpcUrl, solanaPrivateKey);
// Use with ATXP client
const client = await atxpClient({
mcpServer: 'https://search.mcp.atxp.ai/',
account,
});
// Make MCP calls
const result = await client.callTool({
name: 'search_search',
arguments: { query: 'Latest Solana news' }
});
```
## Migration from v0.8.x
If you're upgrading from ATXP SDK v0.8.x or earlier, follow these steps:
Install `@atxp/solana` and its peer dependencies:
```bash theme={null}
npm install @atxp/solana @solana/web3.js @solana/pay bs58
```
Change your imports from `@atxp/client` to `@atxp/solana`:
**Before (v0.8.x):**
```typescript theme={null}
import { atxpClient, SolanaAccount } from '@atxp/client';
```
**After (v0.9.0+):**
```typescript theme={null}
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
```
Test your application to ensure Solana payments work correctly with the new modular structure.
## Benefits of the Modular Architecture
The separation of Solana functionality into `@atxp/solana` provides several advantages:
Applications that don't use Solana no longer need to include Solana dependencies, significantly reducing bundle size.
The core `@atxp/client` package no longer includes the `bigint-buffer` vulnerability that was previously required for Solana support.
Users explicitly install only the blockchain packages they need, making dependency management more transparent and intentional.
Blockchain-specific code is isolated, making it easier to update Solana integrations without affecting the core package.
## See Also
Core ATXP client functionality
Base blockchain account support
# @atxp/sqlite
Source: https://docs.atxp.ai/developers/api-reference/sqlite
SQLite OAuth database implementation for persistent token storage in ATXP applications
## Overview
The [@atxp/sqlite](https://www.npmjs.com/package/@atxp/sqlite) package provides a SQLite-based OAuth database implementation for ATXP. It offers persistent OAuth token storage using SQLite, ensuring data retention across application restarts.
This package is designed to work seamlessly with `@atxp/client` and `@atxp/express` packages when you need persistent storage that survives application restarts. For high-scale applications, consider using [@atxp/redis](/developers/api-reference/redis) instead.
## Installation
```bash theme={null}
npm install @atxp/sqlite
```
The `@atxp/sqlite` package includes TypeScript definitions and requires Node.js 16 or higher. It automatically installs `@atxp/common` as a dependency.
## API Reference
### Classes
#### `SQLiteOAuthDatabase`
The main class for managing OAuth tokens in a SQLite database.
```typescript theme={null}
import { SQLiteOAuthDatabase } from '@atxp/sqlite'
```
**Constructor**
```typescript theme={null}
new SQLiteOAuthDatabase(options: SQLiteOAuthDatabaseOptions)
```
Configuration options for the SQLite database connection.
Path to the SQLite database file. If the file doesn't exist, it will be created automatically.
Whether to automatically create the required database tables on initialization.
Connection timeout in milliseconds.
**Methods**
Saves an OAuth access token in the database.
Unique identifier for the user associated with the access token.
The OAuth access token value to store.
URL associated with the access token.
Retrieves an OAuth access token from the database.
Unique identifier for the user associated with the access token.
URL associated with the access token.
Deletes an OAuth token from the database.
Unique identifier for the token to delete.
Checks if a token exists in the database.
Unique identifier for the token to check.
Lists all token keys stored in the database.
Closes the database connection and releases resources.
### Interfaces
#### `SQLiteOAuthDatabaseOptions`
Configuration options for the SQLite OAuth database.
```typescript theme={null}
interface SQLiteOAuthDatabaseOptions {
databasePath: string
autoCreateTables?: boolean
connectionTimeout?: number
}
```
Path to the SQLite database file. Can be a relative or absolute path.
Whether to automatically create the required database tables on initialization.
Connection timeout in milliseconds.
## Usage Examples
### Integration with ATXP Client
Use SQLite storage with the ATXP client for persistent token management:
```typescript theme={null}
import { atxpClient, ATXPAccount } from '@atxp/client'
import { SQLiteOAuthDatabase } from '@atxp/sqlite'
// Create OAuth database
const oauthDb = new SQLiteOAuthDatabase({
databasePath: './atxp-tokens.db'
})
// Create ATXP client with custom OAuth storage
const client = await atxpClient({
mcpServer: 'https://search.mcp.atxp.ai/',
account: new ATXPAccount(process.env.ATXP_CONNECTION),
oauthDatabase: oauthDb
})
// Use the client - tokens will be automatically stored in SQLite
const result = await client.callTool('search_search', {
query: 'example query'
})
```
### Integration with ATXP Server
Use SQLite storage with the ATXP server for persistent session management:
```typescript theme={null}
import { atxpExpress, ATXPAccount } from '@atxp/express'
import { SQLiteOAuthDatabase } from '@atxp/sqlite'
import express from 'express'
// Create OAuth database
const oauthDb = new SQLiteOAuthDatabase({
databasePath: './server-tokens.db'
})
const app = express()
// Use ATXP server with SQLite OAuth storage
app.use('/mcp', atxpExpress({
destination: new ATXPAccount(process.env.ATXP_CONNECTION),
payeeName: 'My MCP Server',
oauthDatabase: oauthDb
}))
app.listen(3000, () => {
console.log('Server running on port 3000')
})
```
## Configuration
### Database File Location
The SQLite database file can be placed anywhere on your filesystem:
```typescript theme={null}
// Relative path (creates file in current directory)
const oauthDb = new SQLiteOAuthDatabase({
databasePath: './tokens.db'
})
// Absolute path
const oauthDb = new SQLiteOAuthDatabase({
databasePath: '/var/lib/atxp/tokens.db'
})
// In-memory database (temporary, not persistent)
const oauthDb = new SQLiteOAuthDatabase({
databasePath: ':memory:'
})
```
### Environment Variables
Configure the database path using environment variables:
```bash theme={null}
# .env file
ATXP_SQLITE_DB_PATH=./oauth-tokens.db
ATXP_SQLITE_CONNECTION_TIMEOUT=10000
```
```typescript theme={null}
import { SQLiteOAuthDatabase } from '@atxp/sqlite'
const oauthDb = new SQLiteOAuthDatabase({
databasePath: process.env.ATXP_SQLITE_DB_PATH || './tokens.db',
connectionTimeout: parseInt(process.env.ATXP_SQLITE_CONNECTION_TIMEOUT || '5000')
})
```
### Database Schema
The package automatically creates the following table structure:
```sql theme={null}
CREATE TABLE oauth_tokens (
key TEXT PRIMARY KEY,
token TEXT NOT NULL,
expires_at INTEGER,
created_at INTEGER DEFAULT (strftime('%s', 'now')),
updated_at INTEGER DEFAULT (strftime('%s', 'now'))
)
```
The database schema is automatically created when `autoCreateTables` is set to `true` (default). You can disable this behavior if you want to manage the schema manually.
## Troubleshooting
### Common Issues
If you encounter permission errors when creating or accessing the database file:
* Ensure the directory exists and has write permissions
* Check that the user running the application has access to the database path
* Consider using an absolute path instead of a relative path
```typescript theme={null}
// Use absolute path to avoid permission issues
const oauthDb = new SQLiteOAuthDatabase({
databasePath: '/var/lib/atxp/tokens.db'
})
```
If you're experiencing connection timeouts:
* Increase the `connectionTimeout` value
* Check if the database file is locked by another process
* Ensure sufficient disk space is available
```typescript theme={null}
const oauthDb = new SQLiteOAuthDatabase({
databasePath: './tokens.db',
connectionTimeout: 30000 // 30 seconds
})
```
## Related Packages
Client-side integration for MCP clients with OAuth authentication.
Server-side middleware for MCP servers with payment processing.
Redis OAuth database for high-scale applications.
Shared utilities and types used across ATXP packages.
# Create an ATXP account
Source: https://docs.atxp.ai/developers/build-agents/create-account
Create an ATXP account to use the ATXP SDK
## Create an ATXP account
In order to use the ATXP SDK, you need to create an ATXP account.
Visit [ATXP Accounts](https://accounts.atxp.ai/) and sign in with your Google account. Your account will receive \$5.00 in credits as a welcome bonus.
Copy your connection string and save it in an environment variable. The best way to do this is to create a `.env` file in the root of your project and add the following line:
```bash .env lines theme={null}
ATXP_CONNECTION=https://accounts.atxp.ai?connection_token=
```
Never commit your `.env` file to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
You now have your connection string. This connection string is tied to your Google authenticated ATXP account. You can use this connection string to connect to the ATXP SDK.
```typescript theme={null}
// Import the ATXP SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: 'https://search.mcp.atxp.ai/',
account: new ATXPAccount(atxpConnectionString),
});
```
## Resources
Follow a complete tutorial to build your first ATXP‑powered agent that pays for MCP server tool calls.
Follow a complete tutorial to build your first paid MCP server with ATXP integration, from initial setup to live deployment.
# Agent quickstart
Source: https://docs.atxp.ai/developers/build-agents/index
Use ATXP to build agents that pay for tool calls
Build agents that can safely discover and use paid MCP (Model Context Protocol) tools without creating vendor accounts or managing API keys. With ATXP, your agent brings a wallet and pays per request, so you can start building immediately and ship faster.
## Why build with ATXP?
* **Reduced friction**: Try new tools in minutes—no signups, no keys, no billing setup.
* **Pay-as-you-go cost control**: Per-MCP-tool-call pricing; you only pay for what you use.
* **Better security**: Keep secrets out of your app; requests are authorized with signed payments instead of shared keys.
* **Composable tooling**: Combine multiple paid MCP servers behind a single client and consistent API.
## Build your first ATXP agent
Install the [ATXP client SDK](https://www.npmjs.com/package/@atxp/client) in your project:
```bash theme={null}
npm install @atxp/client
```
Create an ATXP account and set your account connection string in an environment variable. The best way to do this is to create a `.env` file in the root of your project and add the following line:
```bash .env lines theme={null}
ATXP_CONNECTION=https://accounts.atxp.ai?connection_token=
```
You can use ATXP to pay for MCP tool calls made from within a Base Mini App. This approach uses a paymaster to pay for gas on behalf of the Mini App's end-users.
In order to use a ATXP with a Base Mini App, you must have a Base Mini App API key from the [Coinbase Developer Portal](https://portal.cdp.coinbase.com/projects/api-keys/client-key). You then need to set the Base Mini App API key in an environment variable. The best way to do this is to create a `.env` file in the root of your project and add the following line:
```bash .env lines theme={null}
NEXT_PUBLIC_ONCHAINKIT_API_KEY=
```
If you already have a Base wallet, you can use it in your ATXP agent by setting the Base endpoint and your Base private key in environment variables. The best way to do this is to create a `.env` file in the root of your project and add the following lines:
```bash .env lines theme={null}
BASE_RPC_URL=
BASE_PRIVATE_KEY=
```
If you already have a Solana wallet, you can use it in your ATXP agent by setting the Solana endpoint and your Solana private key in environment variables. The best way to do this is to create a `.env` file in the root of your project and add the following lines:
```bash .env lines theme={null}
SOLANA_RPC_URL=
SOLANA_PRIVATE_KEY=
```
ATXP Worldchain is designed for World Chain Mini Apps using MiniKit. Users authenticate through World App, and transactions are signed via MiniKit's secure interface. No environment variables or private keys are needed - the integration uses World App's wallet functionality directly.
**For browser applications**: ATXP Polygon works with any EIP-1193 compatible wallet provider (e.g., MetaMask, Coinbase Wallet). Users will sign transactions directly with their wallet and pay gas fees in POL. No environment variables are needed.
**For server/CLI applications**: If you're building a backend service or CLI tool, set the Polygon endpoint and your Polygon private key in environment variables. The best way to do this is to create a `.env` file in the root of your project and add the following lines:
```bash .env lines theme={null}
POLYGON_RPC_URL=
POLYGON_PRIVATE_KEY=
```
ATXP is broadly compatible with (Ethereum Virtual Machine) EVM chains and wallets. Please contact us for more information.
Never commit your `.env` file to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
Define the services that you want to use in your client.
```typescript theme={null}
const searchService = {
mcpServer: 'https://search.mcp.atxp.ai/',
toolName: 'search_search',
description: 'search',
getArguments: (query: string) => ({ query }),
getResult: (result: any) => result.content[0].text
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base Mini App account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { useAccount } from "wagmi";
import { atxpClient } from '@atxp/client';
import { BaseAppAccount } from '@atxp/base';
// Read the Base mini app API key details from the environment variables
const apiKey = process.env.NEXT_PUBLIC_ONCHAINKIT_API_KEY;
const { address } = useAccount();
// Create a BaseAppAccount object using the mini app API key
const account = await BaseAppAccount.initialize({
walletAddress: address,
apiKey,
appName: 'Mini App with ATXP',
allowance: BigInt('10000000'), // 10 USDC
periodInDays: 30,
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: account,
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
Use the services in your agent.
```typescript theme={null}
const query = "latest news on the US financial sector";
try {
const result = await client.callTool({
name: searchService.toolName,
arguments: searchService.getArguments(query),
});
console.log(`${searchService.description} result successful!`);
console.log('Result:', searchService.getResult(result));
} catch (error) {
console.error(`Error with ${searchService.description}:`, error);
process.exit(1);
}
```
## Resources
Log in to manage your ATXP account, view usage, and add funds.
Follow a complete tutorial to build your first ATXP‑powered agent.
Get started monetizing your MCP server with ATXP.
# Build an agent with Cloudflare Agents
Source: https://docs.atxp.ai/developers/build-agents/integrations/cloudflare
Learn how to integrate ATXP's pay-per-use MCP tools with Cloudflare's Agent platform for building AI-powered chat agents
## Overview
Cloudflare Agents provides a platform for building AI-powered chat agents that run on Cloudflare's edge network. By combining Cloudflare Agents with ATXP's pay-per-use MCP tools, you can create AI applications that can generate images, search the web, crawl sites, and more - all with usage-based pricing and seamless deployment.
This guide will show you how to integrate ATXP's MCP tools with Cloudflare Agents to build a chat agent with image generation capabilities. You can find a full working example at [atxp-cloudflare-agent-example](https://github.com/atxp-dev/atxp-cloudflare-agent-example).
## Setup
If you don't have an ATXP account yet, create one and copy your ATXP connection string. It should look something like this:
```bash theme={null}
https://accounts.atxp.ai?connection_token=
```
If you've already created an ATXP account, you can visit the ATXP account dashboard to get your connection string.
Create a new Cloudflare Agent project:
```bash theme={null}
npx create-cloudflare@latest --template cloudflare/agents-starter my-atxp-agent
cd my-atxp-agent
```
Add the ATXP client to your project:
```bash theme={null}
npm install @atxp/client
```
The `@atxp/client` package provides the MCP transport that allows you to use ATXP's MCP tools in your Cloudflare Agent.
Create a `.dev.vars` file in your project root:
```bash theme={null}
OPENAI_API_KEY=your_openai_api_key_here
ATXP_CONNECTION_STRING=https://accounts.atxp.ai?connection_token=
```
Never commit your `.dev.vars` file to version control. Make sure it's included in your `.gitignore` file.
## Basic integration
Here's how to add ATXP image generation to your Cloudflare Agent:
```typescript src/tools/imageGeneration.ts theme={null}
import { tool } from "agents";
import { z } from "zod";
import { ATXPAccount, buildStreamableTransport, createMCPClient } from "@atxp/client";
export const generateImage = tool({
description: "Generate an image from a text prompt using ATXP",
parameters: z.object({
prompt: z.string().describe("The text prompt to generate an image from"),
}),
execute: async ({ prompt }, { env, agent }) => {
try {
// Initialize ATXP account
const account = new ATXPAccount(env.ATXP_CONNECTION_STRING);
// Create transport for ATXP image server
const transport = buildStreamableTransport({
mcpServer: 'https://image.mcp.atxp.ai',
account,
});
// Create MCP client
const client = await createMCPClient({ transport });
// Generate the image
const result = await client.callTool('generate_image', {
prompt: prompt,
size: '1024x1024'
});
if (result.toolResult.content[0].type === 'text') {
const response = JSON.parse(result.toolResult.content[0].text);
if (response.image_url) {
return `Image generated successfully! Here's your image: `;
} else {
return `Image generation started. Task ID: ${response.task_id}`;
}
}
return "Image generation request submitted successfully.";
} catch (error) {
console.error('Image generation error:', error);
return `Failed to generate image: ${error.message}`;
}
},
});
```
```typescript src/tools.ts theme={null}
import { generateImage } from "./tools/imageGeneration";
export const tools = {
generateImage,
// ... other tools
};
export const executions = {
// Add any tools that require confirmation here
};
```
```typescript src/server.ts theme={null}
import { createAgent } from "agents";
import { tools, executions } from "./tools";
export default {
async fetch(request: Request, env: Env): Promise {
const agent = createAgent({
model: openai("gpt-4o-mini", {
apiKey: env.OPENAI_API_KEY,
}),
tools,
executions,
// ... other configuration
});
return agent.fetch(request, { env });
},
};
```
## Deploy your agent
Configure your production environment variables:
```bash theme={null}
wrangler secret put OPENAI_API_KEY
wrangler secret put ATXP_CONNECTION_STRING
```
Deploy your agent:
```bash theme={null}
npm run deploy
```
Your agent will be available at your Cloudflare Workers subdomain.
## Test your agent
Once deployed, you can test your agent by asking it to generate images:
```
User: "Generate an image of a sunset over mountains"
Agent: "I'll generate an image of a sunset over mountains for you..."
[Image appears in the chat when complete]
```
## Next steps
Now that you have a working Cloudflare Agent with ATXP integration, you can explore more:
Learn about other ATXP tools like web search and file storage.
Try building a CLI agent.
# Build an agent with Vercel AI
Source: https://docs.atxp.ai/developers/build-agents/integrations/vercel-ai
Learn how to integrate ATXP's pay-per-use MCP tools with Vercel AI SDK for streaming AI applications
## Overview
The Vercel AI SDK provides powerful tools for building AI applications with streaming responses, while ATXP offers pay-per-use access to various MCP (Model Context Protocol) tools. By combining them, you can create AI applications that can search the web, generate images, crawl sites, and more - all with usage-based pricing. This guide will show you how to integrate ATXP's MCP tools with the Vercel AI SDK for streaming responses and real-time interactions.
You can find a full example of integrating ATXP's SDK with the Vercel AI SDK in the [ATXP Vercel AI SDK demo](https://github.com/atxp-dev/atxp-vercel-demo).
## Prerequisites
#### Create an ATXP account
If you don't have an ATXP account yet, create one and copy your ATXP connection string. It should look something like this:
```bash theme={null}
https://accounts.atxp.ai?connection_token=
```
If you've already created an ATXP account, you visit the ATXP account dashboard to get your connection string.
## Usage
ATXP provides a [LLM Gateway](/agents/llm-gateway) that allows you to use *any model from any provider* and pay per use using only your ATXP account's connection string.
Install the required packages in your project:
```bash theme={null}
npm install @atxp/client ai @ai-sdk/openai @ai-sdk/openai-compatible
```
Create a `.env` file with your connection string:
```bash .env lines theme={null}
# ATXP connection string from your ATXP account dashboard (https://accounts.atxp.ai)
ATXP_CONNECTION=https://accounts.atxp.ai?connection_token=&account_id=
```
Never commit your `.env` file to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
To use ATXP with the Vercel AI SDK, you need to import a few things from the Vercel AI SDK and the ATXP client SDK. The Vercel AI SDK supports OpenAI-compatible models through the `createOpenAICompatible` function, which we need in order to use the LLM Gateway.
```typescript Import libraries theme={null}
import { buildStreamableTransport, ATXPAccount } from '@atxp/client';
import { generateText, experimental_createMCPClient } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
```
Initialize the ATXP account by creating a new `ATXPAccount` object with your ATXP connection string.
```typescript Initialize ATXP account theme={null}
const account = new ATXPAccount(process.env.ATXP_CONNECTION!);
```
Create a streamable transport for a specific ATXP MCP server by using the `buildStreamableTransport` function.
```typescript Create a streamable transport theme={null}
const transport = buildStreamableTransport({
mcpServer: 'https://search.mcp.atxp.ai',
account,
});
```
Create an MCP client using the `experimental_createMCPClient` function.
```typescript Create an MCP client theme={null}
const mcpClient = await experimental_createMCPClient({ transport });
```
Get available tools from the MCP client by using the `tools` function.
```typescript Get available tools theme={null}
const tools = await mcpClient.tools();
```
Create an OpenAI-compatible client using the `createOpenAICompatible` function.
```typescript Create an OpenAI-compatible client theme={null}
const atxp = createOpenAICompatible({
name: 'atxp-llm',
apiKey: process.env.ATXP_CONNECTION,
baseURL: 'https://llm.atxp.ai/v1',
});
```
Use the LLM Gateway to call the specific model with the tools available from the MCP server.
Your ATXP Account will be used to pay for the tokens used by the specified model. See [the docs](/agents/llm-gateway/models) for more information on available models and pricing.
```typescript Use the tools with the LLM Gateway theme={null}
const response = await generateText({
model: atxp("gpt-4.1"),
tools,
messages: [
...systemPrompt,
{
role: "user",
content: prompt,
},
],
});
console.log(JSON.stringify(response, null, 2));
```
If you have your own OpenAI key, you can use it directly with the Vercel AI SDK and ATXP.
If you don't have an OpenAI key, you can use the [ATXP LLM Gateway](/agents/llm-gateway) to use your ATXP account to pay-per-use for any OpenAI-compatible model.
Install the required packages in your project:
```bash theme={null}
npm install @atxp/client ai @ai-sdk/openai
```
The `@atxp/client` package provides the MCP transport that allows you to use ATXP's MCP tools in your Vercel AI SDK application, while `ai` and `@ai-sdk/openai` are from Vercel's AI SDK.
Create a `.env` file with your ATXP connection string and OpenAI API key:
```bash .env lines theme={null}
# ATXP connection string from https://accounts.atxp.ai
ATXP_CONNECTION=https://accounts.atxp.ai?connection_token=&account_id=
# Required for the OpenAI client
OPENAI_API_KEY=your_openai_api_key_here
```
Never commit your `.env` file to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
To use ATXP with the Vercel AI SDK, you need to import a few things from the Vercel AI SDK and the ATXP client SDK. The Vercel AI SDK supports OpenAI models through the `openai` function, which we need in order to use your own OpenAI key.
```typescript Import libraries theme={null}
import { buildStreamableTransport, ATXPAccount } from '@atxp/client';
import { generateText, experimental_createMCPClient } from 'ai';
import { openai } from '@ai-sdk/openai';
```
Initialize the ATXP account by creating a new `ATXPAccount` object with your ATXP connection string.
```typescript Initialize ATXP account theme={null}
const account = new ATXPAccount(process.env.ATXP_CONNECTION!);
```
Create a streamable transport for a specific ATXP MCP server by using the `buildStreamableTransport` function.
```typescript Create a streamable transport theme={null}
const transport = buildStreamableTransport({
mcpServer: 'https://search.mcp.atxp.ai',
account,
});
```
Create an MCP client using the `experimental_createMCPClient` function.
```typescript Create an MCP client theme={null}
const mcpClient = await experimental_createMCPClient({ transport });
```
Get available tools from the MCP client by using the `tools` function.
```typescript Get available tools theme={null}
const tools = await mcpClient.tools();
```
Use the OpenAI client to call the LLM with the tools available from the MCP server.
```typescript Call the LLM theme={null}
const response = await generateText({
model: openai('gpt-4o-mini'),
tools,
messages: [
...systemPrompt,
{
role: "user",
content: prompt,
},
],
});
console.log(JSON.stringify(response, null, 2));
```
You can find a full example of integrating ATXP's SDK with the Vercel AI SDK in the [ATXP Vercel AI SDK demo](https://github.com/atxp-dev/atxp-vercel-demo).
## Next steps
Now that you have the basics, you're ready to start building your own applications. You can explore the following topics to learn more:
Learn about specific tools and capabilities available in each ATXP MCP server.
Follow a complete tutorial to build your first ATXP-powered agent.
# Build a simple CLI client
Source: https://docs.atxp.ai/developers/build-agents/tutorial
Follow a step-by-step tutorial to build your first ATXP client from scratch.
## Overview
In this tutorial, you'll build a simple command-line client that uses ATXP to search the web. Starting from an empty directory, you'll learn how to set up a project, install dependencies, configure authentication, and make your first MCP server call.
By the end of this tutorial, you'll have a working CLI that can search the web using the [Search MCP server](/tools/search).
## Prerequisites
* Node.js installed (version 18 or higher recommended)
* An ATXP account with a connection string (learn how to [create an account](/developers/build-agents/create-account))
* A terminal or command prompt
## Step 1: Create your project
First, let's create a new directory for your project and navigate into it:
```bash theme={null}
mkdir my-atxp-cli
cd my-atxp-cli
```
Now initialize a new Node.js project:
```bash theme={null}
npm init -y
```
This creates a `package.json` file with default values.
## Step 2: Install dependencies
Install the ATXP client SDK and dotenv for managing environment variables:
```bash theme={null}
npm install @atxp/client dotenv
```
The `@atxp/client` package provides everything you need to connect to MCP servers and make tool calls. The `dotenv` package helps you securely manage your connection string.
## Step 3: Set up your environment variables
Create a `.env` file in your project directory to store your ATXP connection string:
```bash theme={null}
touch .env
```
Open the `.env` file in your text editor and add your ATXP connection string:
```bash .env theme={null}
ATXP_CONNECTION=https://accounts.atxp.ai?connection_token=
```
If you don't have an ATXP connection string yet, follow the [account creation guide](/developers/build-agents/create-account) to get one.
Never commit your `.env` file to version control. Add it to your `.gitignore` file:
```bash theme={null}
echo .env >> .gitignore
```
## Step 4: Write your CLI script
Create a new file called `index.js`:
```bash theme={null}
touch index.js
```
Now let's build the script step by step. Open `index.js` in your text editor.
### Step 4a: Load dependencies and create an account
Add the imports and create an ATXP account from your connection string:
```javascript index.js theme={null}
const { atxpClient, ATXPAccount } = require('@atxp/client');
require('dotenv/config');
const account = new ATXPAccount(process.env.ATXP_CONNECTION);
```
### Step 4b: Connect to the Search MCP server
Create a client that connects to the Search MCP server:
```javascript index.js theme={null}
const client = await atxpClient({
mcpServer: 'https://search.mcp.atxp.ai',
account: account,
});
```
### Step 4c: Call the search tool and display results
Call the search tool and output the results:
```javascript index.js theme={null}
const result = await client.callTool({
name: 'search_search',
arguments: { query: 'latest news on artificial intelligence' }
});
const searchResult = JSON.parse(result.content[0].text);
searchResult.results.forEach((item, index) => {
console.log(`${index + 1}. ${item.title}`);
console.log(` ${item.url}\n`);
});
```
### Complete code
Your full `index.js` file should look like this:
```javascript index.js theme={null}
const { atxpClient, ATXPAccount } = require('@atxp/client');
require('dotenv/config');
async function main() {
const account = new ATXPAccount(process.env.ATXP_CONNECTION);
const client = await atxpClient({
mcpServer: 'https://search.mcp.atxp.ai',
account: account,
});
const result = await client.callTool({
name: 'search_search',
arguments: { query: 'latest news on artificial intelligence' }
});
const searchResult = JSON.parse(result.content[0].text);
searchResult.results.forEach((item, index) => {
console.log(`${index + 1}. ${item.title}`);
console.log(` ${item.url}\n`);
});
}
main();
```
## Step 5: Run your CLI
Now you're ready to run your CLI! Execute the following command:
```bash theme={null}
node index.js
```
You should see output similar to this:
```
Creating ATXP client...
Client created successfully!
Searching the web...
Found 10 results:
1. AI Breakthrough: New Language Model Achieves...
URL: https://example.com/ai-news
Recent developments in artificial intelligence have led to significant breakthroughs in natural language processing...
Published: 2 days ago
2. Tech Giants Invest Billions in AI Research
URL: https://example.com/tech-investment
Major technology companies announced record investments in artificial intelligence research and development...
Published: 3 days ago
...
```
Congratulations! You've successfully built a working ATXP client that can search the web using MCP servers.
## Understanding the code
Let's break down what your CLI does:
1. **Import dependencies**: You import the ATXP client SDK and load environment variables
2. **Create account**: You create an `ATXPAccount` instance using your connection string
3. **Create client**: You use `atxpClient()` to create a client connected to the Search MCP server
4. **Call tool**: You use `client.callTool()` to invoke the `search_search` tool with a query
5. **Parse results**: You parse the JSON response and display the search results
## Customizing your CLI
Now that you have a working CLI, try customizing it:
### Change the search query
Modify the `query` argument in the `callTool()` call:
```javascript theme={null}
arguments: { query: 'your custom search query here' }
```
### Accept command-line arguments
Make your CLI accept a search query as a command-line argument:
```javascript theme={null}
// Get query from command line or use default
const query = process.argv[2] || 'latest news on artificial intelligence';
const result = await client.callTool({
name: 'search_search',
arguments: { query: query }
});
```
Then run it with:
```bash theme={null}
node index.js "your search query"
```
### Try different MCP servers
Explore other MCP servers by changing the `mcpServer` URL. Check out the [MCP Servers documentation](/tools) to see what's available.
## Next steps
Discover other MCP servers you can use in your applications, from image generation to file storage.
Learn how to build and monetize your own MCP server with ATXP integration.
Dive deeper into the ATXP Client SDK documentation and learn about advanced features.
# ATXP CLI
Source: https://docs.atxp.ai/developers/cli
Command-line tool for creating ATXP projects and running demos
# ATXP CLI
The [ATXP CLI](https://www.npmjs.com/package/atxp) is a command-line tool that helps you create ATXP projects, run demos, and manage your ATXP development workflow. It provides a streamlined way to bootstrap new projects and explore ATXP functionality.
## Installation
The recommended way to use the ATXP CLI is to run it directly using `npx atxp`.
As an alternative, you can install the ATXP CLI globally using npm:
```bash theme={null}
npm install -g atxp
```
Verify installation by running `atxp help` to confirm the CLI is properly installed.
## Quickstart
### Run a demo
Run a demo ATXP project in seconds.
```bash theme={null}
npx atxp demo
```
```bash theme={null}
atxp demo
```
### Create a new project
The ATXP CLI offers several project templates to get you started quickly:
Perfect for building AI agents that use paid MCP tools.
**Features:**
* Pre-configured ATXP client
* Example agent implementation
* Wallet integration setup
* MCP server connection examples
**Usage:**
```bash theme={null}
npx atxp create my-agent --template agent
```
```bash theme={null}
atxp create my-agent --template agent
```
Ideal for creating monetized MCP servers.
**Features:**
* Express.js server setup
* ATXP middleware integration
* Payment requirement examples
* OAuth configuration
**Usage:**
```bash theme={null}
npx atxp create my-server --template server
```
```bash theme={null}
atxp create my-server --template server
```
Complete solution with both agent and server components.
**Features:**
* Client and server implementations
* End-to-end payment flow
* Development and production configs
* Testing setup
**Usage:**
```bash theme={null}
npx atxp create my-app --template fullstack
```
```bash theme={null}
atxp create my-app --template fullstack
```
## Available commands
### `atxp create `
Creates a new ATXP project with a complete development setup.
The name of your new ATXP project. This will be used as the directory name and package name.
**Example:**
```bash theme={null}
npx atxp create my-agent --template agent
```
```bash theme={null}
atxp create my-agent --template agent
```
**What it creates:**
* Project directory with your specified name
* `package.json` with ATXP dependencies
* Basic project structure for agents or servers
* Configuration files for development
* Example code to get you started
### `atxp demo`
Runs interactive demos to showcase ATXP functionality.
**Available demos:**
* **Agent demo**: Shows how to connect an agent to paid MCP servers
* **Server demo**: Demonstrates creating a monetized MCP server
* **Payment flow**: Interactive walkthrough of ATXP payment processing
**Example:**
```bash theme={null}
npx atxp demo
```
```bash theme={null}
atxp demo
```
Choose from available demo options when prompted.
The CLI will guide you through each step of the demo.
See ATXP in action with real examples and outputs.
### `atxp help`
Display help information and available commands.
```bash theme={null}
npx atxp help
```
```bash theme={null}
atxp help
```
### `atxp agent create`
Create a new agent account under your developer account. Requires login (`npx atxp login`).
Each agent receives:
* A unique email address (`{agentId}@atxp.email`)
* An Ethereum wallet
* \$5 in credits to start
* A connection token for SDK/CLI access
```bash theme={null}
npx atxp agent create
```
After creation, authenticate as the agent using its connection token:
```bash theme={null}
CONNECTION_TOKEN= npx atxp email inbox
```
### `atxp agent list`
List all agents you've created, with their email, account ID, connection token, wallet address, balance, and creation date.
```bash theme={null}
npx atxp agent list
```
### `atxp agent register`
Self-register as an agent without requiring a human developer's login. A single command creates a fully funded account instantly.
```bash theme={null}
npx atxp agent register
```
On success, the CLI prints your agent's connection token, email, wallet address, and connection string. Authenticate as the agent:
```bash theme={null}
npx atxp login --token ""
```
**Options:**
| Flag | Description |
| ---------------- | --------------------------------------------------------- |
| `--server ` | Accounts server URL (default: `https://accounts.atxp.ai`) |
### `atxp fund`
Show all available funding options for your account. Returns crypto deposit addresses (USDC on supported chains) and, for agent accounts, a Stripe payment link that can be shared with anyone.
```bash theme={null}
npx atxp fund
```
**Options:**
| Flag | Description |
| -------------- | ------------------------------------------------- |
| `--amount ` | Suggested amount in USD ($1–$1000, default: \$10) |
| `--open` | Open the payment link in your browser |
**Example output:**
```
Fund via USDC:
Base: 0x59e6...4a62
World: 0x59e6...4a62
Polygon: 0x59e6...4a62
Fund via payment link:
Suggested: $10.00
Range: $1 - $1000
URL: https://buy.stripe.com/...
```
Agents can choose which funding method to use based on context — share the payment link with a human owner via email, or use crypto addresses for agent-to-agent transfers.
### `atxp balance`
Check your ATXP account balance across all chains.
```bash theme={null}
npx atxp balance
```
### `atxp whoami`
Show your account info including account ID, email, and wallet address.
```bash theme={null}
npx atxp whoami
```
### `atxp transactions`
View recent transaction history for your account.
```bash theme={null}
npx atxp transactions
```
**Options:**
| Flag | Description |
| ------------- | -------------------------------------------- |
| `--limit ` | Number of transactions to show (default: 10) |
### `atxp email`
Send and receive emails using your ATXP email address (`{agentId}@atxp.email`).
```bash theme={null}
npx atxp email inbox # Check your inbox
npx atxp email read # Read a specific message
npx atxp email send --to user@example.com --subject "Hi" --body "Hello!"
npx atxp email reply --body "Thanks!"
npx atxp email search "invoice" # Search emails
```
### `atxp memory`
Manage, search, and back up agent memory files with local vector search.
```bash theme={null}
npx atxp memory push --path ~/.openclaw/workspace-abc/
npx atxp memory pull --path ~/.openclaw/workspace-abc/
npx atxp memory index --path ~/.openclaw/workspace-abc/
npx atxp memory search "auth flow" --path ~/.openclaw/workspace-abc/
npx atxp memory status --path ~/.openclaw/workspace-abc/
```
## Development workflow
```bash theme={null}
npx atxp create my-project
cd my-project
```
```bash theme={null}
atxp create my-project
cd my-project
```
Copy `.env.example` to `.env` and fill in your credentials.
Never commit your `.env` file to version control. Add it to your `.gitignore`.
```bash theme={null}
npm install
```
```bash theme={null}
npm run dev
```
```bash theme={null}
npm test
```
## Next steps
Learn how to create AI agents that use paid MCP tools with ATXP.
Add payment requirements to your MCP servers and start earning.
## Support
Need help with the ATXP CLI? [Contact support](mailto:devrel@circuitandchisel.com).
# For Developers
Source: https://docs.atxp.ai/developers/index
Build agents or monetize MCP tools with ATXP — the Agent Transaction Protocol.
# For Developers
Building AI agents or monetizing your MCP tools with [ATXP](https://atxp.ai)? You're in the right place.
Create agents that can discover and pay for MCP tools without managing API keys or vendor accounts.
Add per-use pricing to your MCP servers with minimal integration. Get paid for every tool call.
## Developer resources
Log in to manage your ATXP account, view usage, configure wallets, and add funds.
Command-line tool for creating ATXP projects, running demos, and managing your development workflow.
Use paid MCP servers from clients that don't support payments natively.
Complete SDK documentation for @atxp/client, @atxp/express, and platform adapters.
## Quick links
| Task | Documentation |
| ----------------------------------- | ------------------------------------------------------------------------ |
| Create an agent that pays for tools | [Build agents quickstart](/developers/build-agents) |
| Add payments to your MCP server | [Monetize quickstart](/developers/monetize) |
| Use with Vercel AI SDK | [Vercel AI integration](/developers/build-agents/integrations/vercel-ai) |
| Deploy to Cloudflare Workers | [Cloudflare deployment](/developers/monetize/cloudflare-deploy) |
| Batch payment processing | [Batch payments guide](/developers/monetize/batch-payments) |
# Batch Payments
Source: https://docs.atxp.ai/developers/monetize/batch-payments
Learn how to use batch payments to pay for MCP server tool calls
## Overview
Batch payments let your users pre-pay a larger amount once and draw down across multiple tool calls. You configure a minimum upfront charge and continue to require a per-call price; the middleware handles balance tracking so users are not prompted on every call.
## When to use batch payments
* If your tool is called repeatedly in a workflow and per-call prompts are disruptive
* If you want to reduce payment-approval friction while keeping per-call pricing
* If you want to amortize network fees over several calls
Pick a minimum payment that covers several calls (e.g., 10× your tool's per-call price) to reduce prompts without overcharging.
## How it works
1. You set `minimumPayment` in the `atxpExpress` middleware.
2. Each tool still calls `requirePayment({ price })` for its per-call charge.
3. On the first call, the user pays the larger of `minimumPayment` and `price`.
4. Subsequent calls deduct `price` from the remaining balance until depleted.
## Prerequisites
* ATXP account and connection string
* Existing Express-based MCP server using the [ATXP Express SDK](/developers/api-reference/express).
```bash theme={null}
npm install @atxp/express bignumber.js
```
Add `minimumPayment` to your ATXP middleware and keep per-call pricing with `requirePayment`.
```typescript server.ts theme={null}
import express from 'express'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
import { atxpExpress, requirePayment, ATXPAccount } from '@atxp/express'
import BigNumber from 'bignumber.js'
import { z } from 'zod'
const app = express()
app.use(express.json())
const ATXP_CONNECTION = process.env.ATXP_CONNECTION
// Require an upfront prepayment of $0.50 USDC (or higher if per-call price is larger)
app.use(
atxpExpress({
destination: new ATXPAccount(ATXP_CONNECTION),
payeeName: 'My Batch-Paid Tool',
minimumPayment: new BigNumber(0.50),
})
)
const server = new McpServer({ name: 'my-batch-server', version: '1.0.0' })
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined })
// Charge $0.05 USDC per call; draws down from the prepaid balance
server.tool(
'process_text',
'Process a text string with batch-paid pricing',
{ text: z.string().describe('Text to process') },
async ({ text }) => {
await requirePayment({ price: new BigNumber(0.05) })
return {
content: [{ type: 'text', text: text.toUpperCase() }],
}
}
)
const setupServer = async () => {
await server.connect(transport)
}
app.post('/', async (req, res) => {
try {
await transport.handleRequest(req, res, req.body)
} catch (err) {
if (!res.headersSent) res.status(500).json({ error: 'Internal server error' })
}
})
const PORT = process.env.PORT || 3000
setupServer().then(() => app.listen(PORT))
```
Ensure `minimumPayment` is a `BigNumber` instance. If you pass a number, amounts may be imprecise.
The first tool call will request the larger amount. You can implement approval logic to auto‑approve reasonable prepayments.
```typescript client.ts theme={null}
import { atxpClient } from '@atxp/client'
import { Account } from '@atxp/common'
const account = new Account(process.env.ATXP_CONNECTION_STRING!)
const client = await atxpClient({
mcpServer: 'https://your-server.example.com',
account,
onPayment: async (pmt) => {
console.log(`Payment succeeded: ${pmt.amount} ${pmt.currency}`)
},
onPaymentFailure: async (err) => {
console.error('Payment failed', err)
},
})
const result = await client.callTool({
name: 'process_text',
arguments: { text: 'hello world' },
})
```
To persist balances across restarts or scale-out, configure an OAuth database in `atxpExpress` (SQLite or Redis).
* First call prompts for the larger `minimumPayment` (e.g., \$0.50)
* Next several calls are not prompted until the prepaid balance is depleted
* Once depleted, the next call will prompt again for at least `minimumPayment`
You should see only a single payment approval across multiple calls, then another prompt once the balance runs out.
# Build a paid MCP server on Cloudflare
Source: https://docs.atxp.ai/developers/monetize/cloudflare-deploy
Learn how to build a complete MCP server that charges for tool usage using ATXP payments on Cloudflare Workers
## Overview
This page provides a complete, working example of a basic MCP server that uses ATXP to charge for tool calls and is deployed on Cloudflare Workers. The code for this example implementation can be found at [atxp-dev/atxp-cloudflare-mcp-server-example](https://github.com/atxp-dev/atxp-cloudflare-mcp-server-example).
## Project setup
In this tutorial, we'll build a TypeScript MCP server that exposes tools that can only be called after a successful payment is made using ATXP. We'll use [Cloudflare Workers](https://workers.cloudflare.com/) to build and deploy a scalable MCP server that can be accessed from [Goose](https://block.github.io/goose/) or other MCP clients.
Our MCP server will expose a simple hello\_world tool that provides a personalized message, with each call costing 0.01 USDC.
### Initialize the project
First, we need to create a new Cloudflare Workers project using the MCP template. We'll use the Cloudflare CLI to initialize the project.
```bash theme={null}
npm create cloudflare@latest atxp-mcp-cloudflare-server -- --template cloudflare/ai/demos/remote-mcp-authless
cd atxp-mcp-cloudflare-server
```
This will create a new project with the basic structure for an MCP server on Cloudflare Workers.
### Install ATXP dependencies
We need to install the ATXP Cloudflare package to add payment capabilities:
```bash theme={null}
npm install @atxp/cloudflare bignumber.js --save
```
### Configure the project
The project comes pre-configured with TypeScript and Cloudflare Workers settings. You should verify that your `package.json` includes the necessary scripts and dependencies:
```json package.json lines theme={null}
{
"name": "atxp-mcp-cloudflare-server",
"version": "0.0.0",
"private": true,
"scripts": {
"deploy": "wrangler deploy",
"dev": "wrangler dev",
"start": "wrangler dev",
"test": "vitest",
"cf-typegen": "wrangler types"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"@atxp/cloudflare": "^0.4.0", // [!code ++]
"bignumber.js": "^9.1.2", // [!code ++]
"zod": "^3.23.8"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241112.0",
"typescript": "^5.5.2",
"vitest": "2.0.5",
"wrangler": "^3.86.1"
}
}
```
### Configure environment variables
Create your local environment configuration
```bash theme={null}
touch .dev.vars
```
## Set up how you will receive payments
In order to receive payments, you will need to set up a payment destination.
You can do this by creating a free ATXP account OR by specifying a wallet address and network.
### Create an ATXP account
If you don't have an ATXP account yet, create one and copy your wallet address.
Once you have set up your account, you should add the environment variable
```bash theme={null}
echo 'ATXP_CONNECTION_STRING=your_connection_string' >> .dev.vars
```
For production deployments, set `ALLOW_INSECURE_HTTP_REQUESTS_DEV_ONLY_PLEASE` to `"false"` and use `wrangler secret put` for sensitive values like wallet addresses instead of storing them in `wrangler.jsonc`.
## Develop the MCP server
We're ready to start coding our MCP server now. The template provides a basic structure, but we need to modify it to integrate ATXP payments.
### Set up the MCP Agent with ATXP
Replace the contents of `src/index.ts` with the following code that integrates ATXP payments:
```typescript index.ts lines theme={null}
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { BigNumber } from "bignumber.js";
// Import ATXP code
import {
requirePayment,
atxpCloudflare,
type ATXPMCPAgentProps,
type ATXPCloudflareOptions,
} from "@atxp/cloudflare";
import { ATXPAccount } from "@atxp/server";
const createOptions = (env: Env) => {
const destination = new ATXPAccount(
env.ATXP_CONNECTION_STRING,
);
destination.destination =
destination.destination.bind(destination);
return {
mcpAgent: MyMCP,
payeeName: "ATXP MCP Server Demo",
allowHttp: env.ALLOW_INSECURE_HTTP_REQUESTS_DEV_ONLY_PLEASE === "true",
// Don't create the payment destination here - create it when needed
destination,
} as ATXPCloudflareOptions;
};
// Define our MCP agent with ATXP payment integration
export class MyMCP extends McpAgent {
server = new McpServer({
name: "ATXP-Protected Hello World MCP Server",
version: "1.0.0",
});
async init() {
// This method will be called when the agent is initialized
// We'll define our tools here
}
}
// Use the ATXP Cloudflare Worker wrapper as the default export
export default {
async fetch(request: Request, env: any, ctx: ExecutionContext): Promise {
// Create the handler with environment-based configuration
const cloudflareOptions = createOptions(env);
const handler = atxpCloudflare(cloudflareOptions);
return handler.fetch(request, env, ctx);
}
};
```
At this point, we should be able to build our MCP server without errors by running `npm run dev`. However, we haven't defined any tools yet, so it won't be very useful.
### Define the MCP tools
Now let's add a hello\_world tool that requires payment. This tool will take an optional name parameter and return a personalized greeting.
```typescript index.ts lines theme={null}
// Define our MCP agent with ATXP payment integration
export class MyMCP extends McpAgent {
server = new McpServer({
name: "ATXP-Protected Hello World MCP Server",
version: "1.0.0",
});
async init() {
// Payment-protected hello_world tool
this.server.tool(
"hello_world",
{ name: z.string().optional() },
async ({ name }) => {
if (!this.props) {
throw new Error("ATXP props are not initialized");
}
const options = createOptions(this.env);
await requirePayment(
{
price: new BigNumber(0.01),
},
options,
this.props,
);
const greeting = name ? `Hello, ${name}!` : "Hello, World!";
const userInfo = this.props.tokenCheck?.data?.sub || "anonymous user";
const message = `${greeting} Thanks for your 0.01 USDC payment, ${userInfo}! 💰`;
return {
content: [{ type: "text", text: message }],
};
},
);
}
}
```
Our MCP server is now ready to be used and will require a payment of \$0.01 USDC for each call to the `hello_world` tool. Now let's test the payment integration by running the MCP server locally and then deploying it to Cloudflare.
## Testing the MCP server locally
You can test your MCP server locally before deploying it to Cloudflare.
### Run the MCP server locally
Start the development server using Wrangler:
```bash theme={null}
npm run dev
```
This will start your MCP server locally, typically on `http://localhost:8788/sse`.
### Test with MCP Inspector
You can use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to test your server:
1. Open the MCP Inspector in your browser at `http://localhost:5173`
2. Connect to your local server using the URL `http://localhost:8788/sse`
3. Test the `hello_world` tool to verify it works correctly
## Deploying to Cloudflare
Once your MCP server is working locally, you can deploy it to Cloudflare Workers.
### Deploy the server
Deploy your MCP server using Wrangler:
```bash theme={null}
npm run deploy
```
This will deploy your server to Cloudflare Workers and provide you with a URL like `https://atxp-mcp-cloudflare-server..workers.dev/sse`.
### Configure production environment
For production deployment, follow these steps:
1. Set environment variables in `wrangler.jsonc` or use `wrangler secret put` for sensitive values:
```bash theme={null}
# For sensitive data like wallet addresses, use secrets:
wrangler secret put FUNDING_DESTINATION
# For non-sensitive configuration, update wrangler.jsonc:
# Set ALLOW_INSECURE_HTTP_REQUESTS_DEV_ONLY_PLEASE to "false"
```
2. Update your `wrangler.jsonc` for production settings:
* Set `ALLOW_INSECURE_HTTP_REQUESTS_DEV_ONLY_PLEASE` to `"false"`
* Consider using `wrangler secret put` for sensitive values instead of storing them directly in the config
## Connect to MCP clients
Now that your MCP server is deployed, you can connect it to MCP clients like [Goose](https://block.github.io/goose/).
### Connect to Goose
To connect your deployed MCP server to Goose:
1. Go to **Extensions** in the Goose sidebar
2. Click **Add custom extension**
3. Provide a name for your extension (e.g., "ATXP Greeting Server")
4. Select **Streamable HTTP** as the type
5. Enter your Cloudflare Worker URL: `https://atxp-mcp-cloudflare-server..workers.dev/sse`
6. Click **Add Extension**
Your browser will open a new tab where you must authorize an ATXP wallet to pay for using your MCP server's tools.
### Test the payment flow
Once connected to Goose, test the payment flow:
1. Send a message like "Greet me with the name Alice"
2. Goose will show that payment is required
3. Click the payment URL to complete the payment
4. Return to Goose and confirm the tool call was successful
Congratulations! You've successfully built and deployed a paid MCP server on Cloudflare Workers using ATXP. Your server can now handle payments and scale automatically with Cloudflare's infrastructure.
## Key differences from Express
This Cloudflare approach offers several advantages over Express:
* **Serverless scaling**: No need to manage server infrastructure
* **Global edge deployment**: Reduced latency for users worldwide
* **Simplified deployment**: Single command deployment with Wrangler
* **Built-in HTTPS**: Secure connections by default
* **Environment management**: Integrated secrets and environment variables
The ATXP Cloudflare package (`@atxp/cloudflare`) handles the complexity of integrating payments into your Cloudflare Worker, providing the same `requirePayment` functionality as the Express version but optimized for the Workers runtime.
## Resources
Explore the complete API documentation with examples.
Learn more about Cloudflare Workers development and deployment.
# Create an ATXP account
Source: https://docs.atxp.ai/developers/monetize/create-account
Create an ATXP account to receive payments
## Create an ATXP account
In order to receive payments from ATXP agents, you need to create an ATXP account.
Visit [ATXP Accounts](https://accounts.atxp.ai/) and sign in with your Google account. Your account will receive \$5.00 in credits as a welcome bonus.
You now have your ATXP account's wallet address. This wallet is tied to your Google authenticated ATXP account. If you are an agent using an MCP server that has integrated ATXP payments, when you authentice with ATXP in order to make a payment, the payment will be made using funds in this wallet.
If you are building an MCP server and want to charge for each use of an exposed tool, you can use this address as the `destination` that [payments will be made to](/developers/monetize/tutorial#add-payment-requirements-to-tools).
## Resources
Follow a complete tutorial to build your first ATXP‑powered agent that pays for MCP server tool calls.
Follow a complete tutorial to build your first paid MCP server with ATXP integration, from initial setup to live deployment.
# MCP server quickstart
Source: https://docs.atxp.ai/developers/monetize/index
Monetize your MCP tools in minutes with ATXP
Turn your MCP tools into a revenue stream with pay-per-call pricing without building billing, authentication, or account management. ATXP lets you require payment before execution, so you get predictable income with minimal overhead.
## Why use ATXP for MCP servers?
* **Earn per-use**: Charge per tool call with flexible pricing.
* **Programmatic enforcement**: Require payment before execution with a single router and helper.
* **No user accounts or API keys**: Agents pay from their own wallets; you don't manage users, keys, or invoices.
* **Works everywhere**: Compatible with major hosts (e.g., Claude, Goose), local dev, and your own infrastructure.
## Build your first monetized MCP server
Install the [ATXP express SDK](https://www.npmjs.com/package/@atxp/express) in your project:
```bash theme={null}
npm install @atxp/express
```
Create an ATXP account and set your wallet address in an environment variable. The best way to do this is to create a `.env` file in the root of your project and add the following line:
```bash .env lines theme={null}
ATXP_CONNECTION=
```
Never commit wallet address to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
Add the ATXP Express router to your MCP server:
```typescript theme={null}
// Import the ATXP SDK and other dependencies
import { atxpExpress, requirePayment, ATXPAccount } from '@atxp/express'; // [!code ++]
import BigNumber from "bignumber.js"; // [!code ++]
// Create your MCP server
const server = new McpServer();
// Define your MCP tools...
// server.tool(...);
// Create and configure your Express server
const app = express()
app.use(express.json())
// Read your wallet ID from the environment variable
const ATXP_CONNECTION = process.env.ATXP_CONNECTION // [!code ++]
// Add the ATXP payment router // [!code ++]
app.use(atxpExpress({ // [!code ++]
destination: new ATXPAccount(ATXP_CONNECTION), // Your connection string // [!code ++]
payeeName: 'Your Server Name', // The name of your MCP server // [!code ++]
})) // [!code ++]
// Other MCP server configuration...
```
In each MCP tool exposed by your server that you want to charge per-use for, require payment before tool execution:
```typescript theme={null}
server.tool(
"upcase",
"Convert the provided string to uppercase",
{
text: z.string().describe("The text to convert to uppercase"),
},
async ({ text }) => {
// Require payment (in USDC) for the tool call // [!code ++]
await requirePayment({price: BigNumber(0.01)}); // [!code ++]
// Your tool's logic
const result = text.toUpperCase();
// Return the result of the tool call
return {
content: [
{
type: "text",
text: result,
},
],
};
}
);
```
Deploy your changes and connect to your MCP server with a host such as [Goose](https://block.github.io/goose/) or [Claude](https://claude.ai) to start paying for tool calls.
Running your MCP server locally? See on [how to connect to a local MCP server](/developers/monetize/tutorial#run-the-mcp-server).
## Resources
Log in to manage your ATXP account, configure your wallet, and view earnings.
Follow a complete tutorial to build your first paid MCP server with ATXP integration, from initial setup to live deployment.
Get started building an ATXP‑powered agent that pays for MCP server tool calls.
# Build a paid MCP server
Source: https://docs.atxp.ai/developers/monetize/tutorial
Learn how to build a complete MCP server that charges for tool usage using ATXP payments
## Overview
This page provides a complete, working example of a basic MCP server that uses ATXP to charge for tool calls. This code for this example implementation can be found at [circuitandchisel/atxp-minimal-demo](https://github.com/circuitandchisel/atxp-minimal-demo).
## Project setup
In this tutorial, we'll build a TypeScript MCP server that exposes two tools that can only be called after a successful payment is made using ATXP. We'll use [Express](https://expressjs.com/) to build a streamable HTTP MCP server and run it locally using [ngrok](https://ngrok.com/) to enable us to connect to it from [Goose](https://block.github.io/goose/).
Our MCP server will expose a simple addition tool that adds two numbers together, with each calculation costing 0.01 USDC.
### Initialize the project
First, we need to initialize a new project. We'll call it `atxp-math-server` and intialize a new Node.js project.
```bash theme={null}
mkdir atxp-math-server
cd atxp-math-server
npm init -y
```
### Install dependencies
We need to install a few dependencies:
```bash theme={null}
npm install express @modelcontextprotocol/sdk zod dotenv bignumber --save
```
We also need to install the [ATXP express SDK](https://npmjs.com/package/@atxp/express):
```bash theme={null}
npm install @atxp/express --save
```
Because we're using TypeScript, we need to install a few extra development dependencies:
```bash theme={null}
npm install typescript tsx @types/express @types/node --save-dev
```
### Configure the project
Before we can start writing code, we need to configure our project.
First, we need to create a `tsconfig.json` file with the following content at the root of our project to configure the TypeScript compiler.
```json tsconfig.json lines theme={null}
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
```
We also need to modify our project's `package.json` file. We'll add a few scripts to make it easier to build and run our project and set some project build settings.
```json package.json lines theme={null}
{
"name": "atxp-math-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc && chmod 755 build/index.js", // [!code ++]
"start": "node build/index.js", // [!code ++]
"dev": "tsx --watch src/index.ts", // [!code ++]
"test": "echo \"Error: no test specified\" && exit 1"
},
"files": [ // [!code ++]
"build" // [!code ++]
], // [!code ++]
"bin": { // [!code ++]
"atxp-math-server": "build/index.js" // [!code ++]
}, // [!code ++]
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs", // [!code --]
"type": "module", // [!code ++]
"dependencies": {
"@modelcontextprotocol/sdk": "^1.17.1",
"express": "^5.1.0",
"zod": "^3.25.76",
"dotenv": "^17.2.1",
"@atxp/express": "^0.6.4"
},
"devDependencies": {
"@types/express": "^5.0.3",
"@types/node": "^24.2.0",
"typescript": "^5.9.2"
}
}
```
## Set up your ATXP account
In order to receive payments, you need to create an ATXP account. This account will be used to receive payments in USDC when your MCP server's tools are called.
### Create an ATXP account
If you don't have an ATXP account yet, create one and copy your wallet address.
### Store wallet address in an environment variable
In order to use your wallet address in your MCP server, you need to set it in an environment variable. The best way to do this is to create a `.env` file in the root of your project and add the following line:
```bash .env lines theme={null}
ATXP_CONNECTION=
```
Never commit your wallet address to version control. It is a good idea to add your `.env` to your `.gitignore` file to prevent it from being committed.
```bash theme={null}
echo .env >> .gitignore
```
## Develop the MCP server
We're ready to start coding our MCP server now. Let's start by creating our source code directory and server code file.
```bash theme={null}
mkdir src
touch src/index.ts
```
### Set up Express
We'll use Express to build a streamable HTTP MCP server. To do this, we'll need the following code in our `index.ts` file:
```typescript index.ts lines theme={null}
import express, { Request, Response } from "express";
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import dotenv from 'dotenv';
// Load environment variables from .env file
dotenv.config();
// Create our McpServer instance with the appropriate name and version
const server = new McpServer({
name: "atxp-math-server",
version: "1.0.0",
});
// Create our Express application
const app = express();
// Configure our Express application to parse JSON bodies
app.use(express.json());
// Create our transport instance
const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // set to undefined for stateless servers
});
// Setup routes for the server
const setupServer = async () => {
await server.connect(transport);
};
// Setup the URL endpoint that will handle MCP requests
app.post('/', async (req: Request, res: Response) => {
console.log('Received MCP request:', req.body);
try {
await transport.handleRequest(req, res, req.body);
} catch (error) {
console.error('Error handling MCP request:', error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: 'Internal server error',
},
id: null,
});
}
}
});
// Start the server
const PORT = process.env.PORT || 3000;
setupServer().then(() => {
app.listen(PORT, () => {
console.log(`MCP Streamable HTTP Server listening on port ${PORT}`);
});
}).catch(error => {
console.error('Failed to set up the server:', error);
process.exit(1);
});
```
At this point, we should be able to build our MCP server without errors by running `npm run build`. We can even start it locally by running `npm run start` (after running `npm run build`) or `npm run dev` to start it in development mode. However, we haven't defined any tools yet, so it won't be very useful.
### Define the MCP tools
The first tool we'll add to our MCP server is the *addition* tool. This tool will take two numbers and return their sum.
```typescript index.ts lines theme={null}
// Create our McpServer instance with the appropriate name and version
const server = new McpServer({
name: "atxp-math-server",
version: "1.0.0",
});
// Create our addition tool // [!code ++]
server.tool( // [!code ++]
"add", // [!code ++]
"Use this tool to add two numbers together.", // [!code ++]
{ // [!code ++]
a: z.number().describe("The first number to add"), // [!code ++]
b: z.number().describe("The second number to add"), // [!code ++]
}, // [!code ++]
async ({ a, b }) => { // [!code ++]
return { // [!code ++]
content: [ // [!code ++]
{ // [!code ++]
type: "text", // [!code ++]
text: `${a + b}`, // [!code ++]
}, // [!code ++]
], // [!code ++]
}; // [!code ++]
} // [!code ++]
); // [!code ++]
// Create our Express application
const app = express();
```
We can now build our MCP server using `npm run build` to verify that it compiles without errors. At this point, we *could* connect a client like [Goose](https://block.github.io/goose/) to it and test that our tool does in fact add two numbers together, but it will be more exciting to see it in action after we've integrated payments. [Skip forward a few steps](/server/guides/tutorial#testing-the-mcp-server) to see how to connect to our MCP server and test it out if you want to try it out without payments.
### Add payment requirements to tools
We've already installed the ATXP server SDK, so we can use it to add payment requirements to our tools. First, we need to import the necessary functions from the SDK.
```typescript index.ts lines theme={null}
import express, { Request, Response } from "express";
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { atxpExpress, requirePayment, ATXPAccount } from '@atxp/express'; // [!code ++]
import BigNumber from "bignumber.js"; // [!code ++]
// Create our McpServer instance with the appropriate name and version
const server = new McpServer({
name: "atxp-math-server",
version: "1.0.0",
});
```
We'll also need to set our wallet address in an environment variable. This is the wallet that payments to use the tool will be sent to.
```bash theme={null}
export ATXP_CONNECTION=
```
In our MCP server code, we'll read this wallet address from the environment variable.
```typescript index.ts lines theme={null}
// Create our Express application
const app = express();
// Configure our Express application to parse JSON bodies
app.use(express.json());
// Read your wallet address from the environment variable // [!code ++]
const ATXP_CONNECTION = process.env.ATXP_CONNECTION // [!code ++]
// Create our transport instance
const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // set to undefined for stateless servers
});
```
The ATXP server SDK provides an Express router that must be used to add payment capabilities to our MCP server. We need to configure our Express application to use this router.
```typescript index.ts lines theme={null}
// Create our Express application
const app = express();
// Configure our Express application to parse JSON bodies
app.use(express.json());
// Read your wallet address from the environment variable
const ATXP_CONNECTION = process.env.ATXP_CONNECTION
// Configure our Express application to use the ATXP router
app.use(atxpExpress({ // [!code ++]
destination: new ATXPAccount(ATXP_CONNECTION), // [!code ++]
payeeName: 'Add', // [!code ++]
}))
// Create our transport instance
const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // set to undefined for stateless servers
});
```
Finally, we need to modify our tool definition to require a payment before the tool is executed. We will do this by the `requirePayment` function from the ATXP server SDK. This function takes a `price` parameter that specifies the amount of USDC to charge for the tool call.
```typescript index.ts lines theme={null}
// Create our addition tool
server.tool(
"add",
"Use this tool to add two numbers together.",
{
a: z.number().describe("The first number to add"),
b: z.number().describe("The second number to add"),
},
async ({ a, b }) => {
// Require payment (in USDC) for the tool call // [!code ++]
await requirePayment({price: BigNumber(0.01)}); // [!code ++]
return {
content: [
{
type: "text",
text: `${a + b}`,
},
],
};
}
);
```
Our MCP server is now ready to be used and will require a payment of \$0.01 USDC for each call to the `add` tool. Now let's test the payment integration by running the MCP server locally and connecting to it using [Goose](https://block.github.io/goose/).
## Testing the MCP server
In order to test our MCP server locally, we need to run it and expose it to the internet. We'll use [ngrok](https://ngrok.com/) to do this. ngrok is a tool that creates a secure tunnel to your local server so that it can be accessed from the internet. This is useful for testing local development servers before deploying them to a production environment. If you don't have ngrok installed, you can install it and use it for free by following [these instructions](https://ngrok.com/docs/getting-started/#2-install-the-ngrok-agent-cli).
### Run the MCP server
We will need two terminal sessions; one to run the MCP server and one to use ngrok to expose the MCP server to the internet.
In the first terminal session, we'll build and run the MCP server, which will start listening on port 3000.
```bash theme={null}
npm run build
npm run start
```
In the second terminal session, we'll use ngrok to expose the MCP server to the internet so that we can connect to it using [Goose](https://block.github.io/goose/). We'll use the `http` protocol and the port that the MCP server is listening on (3000).
```bash theme={null}
ngrok http http://127.0.0.1:3000
```
This ngrok command will open a secure tunnel to your local MCP server and print out a URL that you can use to connect to it. The URL you are looking for is the `https` URL. If you are using a free ngrok account (or are not authenticated with ngrok), the URL you are looking for will be something like `https://.ngrok-free.app`.
### Connect to the MCP server
Now that we have the MCP server running and ngrok has exposed it to the internet, we can connect to it using [Goose](https://block.github.io/goose/).
After you've set up Goose, you can connect to your local MCP server through the ngrok tunnel URL by going to **Extensions** in the Goose sidebar and clicking **Add custom extension**.
Provide a name for your Goose extension (e.g. "ATXP Math Server"), select **Streamable HTTP** as the type of extension, and paste the ngrok tunnel URL into the **Endpoint** field.
Then click **Add Extension** to save your new extension. Your browser will open a new tab in which you must authorize an ATXP wallet to pay for using your MCP server's tool. Once you've authorized the wallet, you are ready to have your configured LLM use, and pay for, your MCP server's tool.
### Go through the payment flow
Now that you've connected Goose to your locally running MCP server, you can test the payment flow by sending a message in Goose such as "Add 1 and 2".
Goose will show you a message that the tool is being called and that you need to pay make a payment at the supplied URL in order to use the tool.
Click on the URL to open the payment page in a new tab. Complete the payment in your browser and then return to Goose. Upon succesful payment, your browser will show you the details of the transaction.
Send another message to your configured LLM such as "I have completed the payment. Try again." and you'll see that the tool call is successful.
Congratulations! You've successfully built and tested a paid MCP server using ATXP. You can now charge for tool usage in your own MCP servers.
## Resources
Explore the complete API documentation with examples.
# MCP Proxy
Source: https://docs.atxp.ai/developers/proxy
Use paid MCP servers from clients that don't support payments
Use a paid MCP server from applications or clients that don't natively support payments by using your ATXP connection string as an MCP server that makes payments directly from your ATXP account.
For security, only ATXP-provided MCP servers are currently supported in the MCP Proxy. If you have a use-case for other MCP servers, come talk to us!
## How it Works
The client calling an MCP server that requires payment with ATXP needs to be able to pay for that tool. Usually that means the client is using the [@atxp/client SDK](https://www.npmjs.com/package/@atxp/client) to make payments automatically, or an application like Goose is directing the user to a payment URL.
Using your ATXP connection string, you can use ATXP's MCP Proxy to proxy MCP calls to the paid server, and ATXP will automatically make payments to that server from your ATXP account. The client using the proxy never sees any payment requests, because they are paid automatically by the proxy.
## Why use ATXP MCP Proxy?
MCP Proxy is useful if you want to work in a client like Goose using paid MCP servers like [https://image.mcp.atxp.ai](https://image.mcp.atxp.ai) without being prompted for payment links.
The MCP Proxy is not for publishing your paid MCP server for others to use and pay you. Each end user must use their own ATXP connection string (their own proxy URL), because payments are charged to the account tied to that connection string.
Never share an MCP Proxy URL or your ATXP connection string.
## Get started with the ATXP MCP Proxy
Create an ATXP account and copy your connection string.
```
https://accounts.atxp.ai?connection_token=&account_id=
```
Add the URL of the paid server you want to use to the end of the connection string as a `server` parameter (eg `&server=image.mcp.atxp.ai`). The `https://` portion is not required - it will be assumed.
```
https://accounts.atxp.ai?connection_token=&account_id=&server=image.mcp.atxp.ai
```
Anyone with your proxy URL can use the configured paid MCP server, with costs paid from *your* ATXP account. Keep your proxy URLs secure, just as you would with your regular ATXP connection string.
* In Goose, select Extensions, then click "+ Add custom extension"
* Select 'Streamable HTTP\` from the Type dropdown
* Enter a name and description
* Enter the MCP Proxy URL as the Endpoint
* Click 'Add extension'
Now you can use your tool from your Goose chat sessions.
# Code
Source: https://docs.atxp.ai/tools/code
Write and execute code
## Overview
Use the Code MCP server from your ATXP-powered agent to run code in a variety of languages in a sandboxed environment.
## Example prompts
* "Run the following python code: print('Hello, world!')"
* "What is the result of this javascript code: console.log('Hello, world!');"
* "What is the result of this Scheme code: (display 'Hello, world!)"
## Tools
Take in code and execute it in a sandbox. The output will be the result of the code execution. An example of how it can be used would be to run code generated by a LLM in a safe environment.
### Arguments
Accepts a JSON object with the following properties:
The code to execute. It will be executed in a sandbox.
The programming language to use for execution (e.g., javascript, python, typescript, etc.). Default is typescript.
### Response
Returns a JSON object with the following properties:
The status of the code execution. Returns "success" when the code is executed successfully.
The output of the code execution.
The exit code of the code execution.
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Code tools in a consistent manner.
```typescript theme={null}
const codeService = {
mcpServer: 'https://code.mcp.atxp.ai/',
executeCodeToolName: 'code_execute_code',
description: 'ATXP Code MCP server',
getArguments: (code: string, language: string) => ({ code, language }),
getResult: (result: any) => {
const jsonResult = result.content[0].text
return JSON.parse(jsonResult);
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: codeService.mcpServer,
account,
});
```
Call the Code tool by passing your natural‑language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const code = "print('Hello, world!')";
const language = "python";
try {
const result = await client.callTool({
name: codeService.executeCodeToolName,
arguments: codeService.getArguments(code, language),
});
const result = codeService.getResult(result);
console.log('Status:', result.status);
console.log('Output:', result.output);
console.log('Exit code:', result.exitCode);
} catch (error) {
console.error(`Error with ${codeService.description}:`, error);
process.exit(1);
}
```
You should see the result of the code printed in your console.
# Looking for something else?
Source: https://docs.atxp.ai/tools/contact
Contact the ATXP team to suggest new MCP servers
## Need a different MCP server?
Can't find the MCP server you're looking for in our current collection? We'd love to hear from you! The [ATXP](https://atxp.ai) team is actively building new MCP servers based on user feedback and needs.
## Share your ideas
We're committed to building MCP servers that our users actually want to use. Whether you have a specific tool in mind or just a general use case, we want to hear about it.
Reach us at **[support@atxp.ai](mailto:support@atxp.ai)** with the MCP server you'd like to see. Include your use case, requirements, and any specific tools you're looking for.
## What to include in your suggestion
When reaching out with an MCP server idea, consider including:
* **Use case description**: What problem are you trying to solve?
* **Target tools/services**: What APIs or services should the MCP server integrate with?
* **Expected functionality**: What specific tools or capabilities do you need?
* **Integration requirements**: How should it work with your existing ATXP agent?
* **Priority level**: How important is this for your current project?
## Current MCP server roadmap
We're actively working on expanding our MCP server collection. Some areas we're exploring include:
* **Data analysis tools**: Statistical analysis, data visualization, and reporting
* **Creative tools**: Image generation, audio processing, and content creation
* **Business tools**: CRM integrations, project management, and analytics
* **Developer tools**: Code analysis, testing, and deployment automation
Your feedback directly influences our development priorities. We prioritize building MCP servers that solve real problems for our users.
# Crawl
Source: https://docs.atxp.ai/tools/crawl
Crawl the web
## Overview
Use the Crawl MCP server from your ATXP-powered agent to search and extract information from the web. The Crawl MCP server can be used to:
* crawl up to a specificied maximum number of pages
* extract information from websites
## Example prompts
* "Scrape [https://docs.atxp.ai](https://docs.atxp.ai) and give me the text from the page."
* "Crawl [https://www.baseball-reference.com/teams/NYM/](https://www.baseball-reference.com/teams/NYM/) and give me the details on the Mets."
## Cloudflare pay per crawl
The Crawl MCP server is compatible with Cloudflare's [pay per crawl](https://blog.cloudflare.com/introducing-pay-per-crawl/) scheme. If you instruct the service to crawl a website with pay per crawl enabled, the cost of the tool call will include the added fee imposed by the content provider.
## Tools
Scrape a website and return the text content. It is useful if you need a single page of text from a website.
### Arguments
Accepts a JSON object with the following properties:
The URL of the website to scrape.
### Response
A JSON object with the following properties:
The status of the scrape operation. The `status` key will have the value "success" when the scrape is complete and HTML content was found. If the scrape fails to find any HTML content, the `status` key will have a value of "error".
The HTML content scraped from the specified URL.
Crawl a website and return the text content. It is useful if you need to crawl a website and get all the text content.
### Arguments
Accepts a JSON object with the following properties:
The URL of the website to crawl.
The maximum number of pages to crawl. The default value is 10.
### Response
Returns a JSON object with the following properties:
The status of the crawl operation. The `status` key will have the value "success" when the crawl is complete.
The text content crawled from the specified URL.
The ID of the crawl task.
The estimated time in seconds until the crawl is complete.
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Crawl tools in a consistent manner.
```typescript theme={null}
const crawlService = {
mcpServer: 'https://crawl.mcp.atxp.ai/',
scrapeToolName: 'crawl_scrape',
description: 'ATXP Crawl MCP server',
getArguments: (url: string) => ({ url }),
getResult: (result: any) => {
const jsonResult = result.content[0].text
return JSON.parse(jsonResult);
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: crawlService.mcpServer,
account,
});
```
Call the Crawl tool by passing your natural‑language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const url = "https://docs.atxp.ai";
try {
const result = await client.callTool({
name: crawlService.scrapeToolName,
arguments: crawlService.getArguments(url),
});
const result = crawlService.getResult(result);
console.log('Status:', result.status);
console.log('HTML:', result.html);
} catch (error) {
console.error(`Error with ${crawlService.description}:`, error);
process.exit(1);
}
```
You should see the content of the crawled pages printed in your console.
# Email
Source: https://docs.atxp.ai/tools/email
Send and receive emails
## Overview
Use the Email MCP server from your ATXP-powered agent to send and receive emails. Each ATXP user gets a unique email address in the format `{user_id}@atxp.email`.
## Example prompts
* "Check my email inbox and summarize any new messages."
* "Send an email to [jane@example.com](mailto:jane@example.com) letting her know the meeting has been rescheduled to 3pm."
* "Read the latest message from [support@company.com](mailto:support@company.com)."
## Pricing
| Operation | Cost |
| ------------ | ---------------- |
| Check inbox | Free |
| Read message | Free |
| Send email | \$0.01 per email |
## Tools
Check your email inbox for new messages. Returns a list of message summaries with sender, subject, and date.
### Arguments
This tool takes no arguments.
### Response
Returns a JSON object with the following properties:
The status of the operation. Returns "success" when completed successfully, otherwise returns "error".
The error message if the operation fails. Only returned when `status === "error"`.
Your unique ATXP email address. Only returned when `status === "success"`.
List of messages in your inbox. Only returned when `status === "success"`.
Unique identifier for the message. Use this with `email_get_message` to read the full message.
The sender's email address.
The email subject line.
The date and time the message was received.
Read the full content of a specific email message.
### Arguments
Accepts a JSON object with the following properties:
The unique identifier of the message to read. Get this from `email_check_inbox`.
### Response
Returns a JSON object with the following properties:
The status of the operation. Returns "success" when completed successfully, otherwise returns "error".
The error message if the operation fails. Only returned when `status === "error"`.
Your unique ATXP email address.
The full message content. Only returned when `status === "success"`.
The sender's email address.
The recipient email address(es).
The email subject line.
The date and time the message was received.
The plain text content of the email.
The HTML content of the email, if available.
Send an email from your ATXP email address.
### Arguments
Accepts a JSON object with the following properties:
The recipient's email address.
The email subject line.
The email body content.
### Response
Returns a JSON object with the following properties:
The status of the operation. Returns "success" when the email is sent, otherwise returns "error".
The error message if the operation fails. Only returned when `status === "error"`.
Your ATXP email address (the sender address).
Unique identifier for the sent message.
## Usage
Create a reusable service configuration that points to the MCP server.
```typescript theme={null}
const emailService = {
mcpServer: 'https://email.mcp.atxp.ai/',
tools: {
checkInbox: 'email_check_inbox',
getMessage: 'email_get_message',
sendEmail: 'email_send_email'
},
description: 'ATXP Email MCP server',
getResult: (result: any) => JSON.parse(result.content[0].text)
};
```
Create a client using an ATXP account.
```typescript theme={null}
import { atxpClient, ATXPAccount } from '@atxp/client';
const atxpConnectionString = process.env.ATXP_CONNECTION;
const client = await atxpClient({
mcpServer: emailService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account.
```typescript theme={null}
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
const client = await atxpClient({
mcpServer: emailService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Call the inbox tool to see your messages.
```typescript theme={null}
const result = await client.callTool({
name: emailService.tools.checkInbox,
arguments: {},
});
const inbox = emailService.getResult(result);
console.log('Your email:', inbox.inboxAddress);
console.log('Messages:', inbox.messages);
```
Get the full content of a specific message.
```typescript theme={null}
const result = await client.callTool({
name: emailService.tools.getMessage,
arguments: { messageId: 'msg_abc123' },
});
const email = emailService.getResult(result);
console.log('From:', email.message.from);
console.log('Subject:', email.message.subject);
console.log('Body:', email.message.text);
```
Send an email to any recipient.
```typescript theme={null}
const result = await client.callTool({
name: emailService.tools.sendEmail,
arguments: {
to: 'recipient@example.com',
subject: 'Hello from my agent',
body: 'This email was sent by an AI agent using ATXP!'
},
});
const response = emailService.getResult(result);
if (response.status === 'success') {
console.log('Email sent! Message ID:', response.messageId);
}
```
Your email will be sent from your unique ATXP email address.
# Filestore
Source: https://docs.atxp.ai/tools/filestore
Store and retrieve files
## Overview
Use the Filestore MCP server from your ATXP-powered agent to store, retrieve, and delete files.
## Example prompts
* "Upload the file `example.txt` to the filestore."
* "Download the file `example.txt` from the filestore."
* "Delete the file `example.txt` from the filestore."
## Tools
Takes file data and saves it to the file store. For example, if you need to save a file between conversations, you can use this tool.
### Arguments
Accepts a JSON object with the following properties:
The base64 encoded content of the file to save.
The URL of a file to copy contents from.
The content type of the file to save
The file extension of the file to save
Whether to make the file public.
### Response
Returns a JSON object with the following properties:
The status of the save file operation. The `status` key will have the value "success" when the file is saved successfully.
The name of the file that was saved.
The URL that the file is accessible at.
Returns the contents of a file from the file store. For example, if you need to read a file between conversations, you can use this tool.
### Arguments
Accepts a JSON object with the following properties:
The ID of the file to read.
### Response
Returns a JSON object with the following properties:
The status of the read file operation. The `status` key will have the value "success" when the file is read successfully.
The name of the file that was read.
The base64 encoded content of the file that was read.
Deletes a file from the file store. For example, if you need to delete a file between conversations, you can use this tool.
### Arguments
Accepts a JSON object with the following properties:
The name of the file to delete.
### Response
Returns a JSON object with the following properties:
The status of the delete file operation. The `status` key will have the value "success" when the file is deleted successfully.
The name of the file that was deleted.
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Filestore tools in a consistent manner.
```typescript theme={null}
const filestoreService = {
mcpServer: 'https://filestore.mcp.atxp.ai/',
writeFileToolName: 'filestore_write',
description: 'ATXP Filestore MCP server',
getArguments: (sourceURL: string) => ({ sourceURL }),
getResult: (result: any) => {
const jsonResult = result.content[0].text
return JSON.parse(jsonResult);
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: filestoreService.mcpServer,
account,
});
```
Call the Filestore tool by passing your natural-language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const sourceURL = "https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExN3FycXEzcnVpeDJiZnZlMThoc3R2aDdnM2NrY2hxY3J3eHFqaG92cyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/DYH297XiCS2Ck/giphy.gif"
try {
const writeResult = await client.callTool({
name: filestoreService.writeFileToolName,
arguments: filestoreService.getArguments(sourceURL),
});
const writeResult = filestoreService.getResult(writeResult);
console.log('Status:', writeResult.status);
console.log('Filename:', writeResult.filename);
console.log('URL:', writeResult.url);
} catch (error) {
console.error(`Error with ${filestoreService.description}:`, error);
process.exit(1);
}
```
You should see the result of the filestore operation printed in your console.
# Image
Source: https://docs.atxp.ai/tools/image
Create and edit images
## Overview
Use the Image MCP server from your ATXP-powered agent to create images based on a prompt.
## Example prompts
* "Create an image of a cat riding a horse. Use a realistic style."
* "Create a coloring page of a child and a puppy."
## Tools
Takes in a prompt, optional model, optional aspect ratio, and optional reference images. The output will be a URL to an image generated from the prompt. The image will be stored in the cloud and will expire in 180 days.
### Arguments
Accepts a JSON object with the following properties:
The natural-language prompt to use to generate the image.
Optional model to use for image generation. If not specified, uses the default model from environment variables.
**OpenAI models:** `gpt-4o`, `gpt-4o-mini`, `gpt-image-1`, `dall-e-3`
**Gemini models:** `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`, `imagen-3.0-generate-002`, `gemini-3-pro-image-preview`
Optional aspect ratio for the generated image. Defaults to `1:1` if not specified.
**OpenAI supported ratios:** `1:1` (square), `16:9` (landscape), `9:16` (portrait)
**Gemini supported ratios:** `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`
Optional array of reference images to incorporate into the generation. Images will be fetched from the provided URLs.
URL of the reference image.
Optional description of how to use this image (for example, "use as logo", "apply this style").
### Response
Returns a JSON object with the following properties:
The status of the image generation operation. Returns "success" when the image is generated successfully.
The URL that the image is accessible at for 1 day.
Takes in a prompt, optional model, optional aspect ratio, and optional reference images, then starts asynchronous image generation. Returns a task ID that can be used to check status and retrieve the result. The image will be stored in the cloud and will expire in 180 days.
### Arguments
Accepts a JSON object with the following properties:
The natural-language prompt to use to generate the image.
Optional model to use for image generation. If not specified, uses the default model from environment variables.
**OpenAI models:** `gpt-4o`, `gpt-4o-mini`, `gpt-image-1`, `dall-e-3`
**Gemini models:** `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`, `imagen-3.0-generate-002`, `gemini-3-pro-image-preview`
Optional aspect ratio for the generated image. Defaults to `1:1` if not specified.
**OpenAI supported ratios:** `1:1` (square), `16:9` (landscape), `9:16` (portrait)
**Gemini supported ratios:** `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`
Optional array of reference images to incorporate into the generation. Images will be fetched from the provided URLs.
URL of the reference image.
Optional description of how to use this image (for example, "use as logo", "apply this style").
### Response
Returns a JSON object with the following properties:
A unique task identifier that can be used with `image_get_image_async` to check the status and retrieve the result.
Retrieves the status and result of an asynchronous image generation task using the task ID. Tasks expire after 12 hours.
### Arguments
Accepts a JSON object with the following properties:
The task ID returned from `image_create_image_async`.
### Response
Returns a JSON object with the following properties:
The current status of the task. Can be "pending", "processing", "completed", or "failed".
The URL that the image is accessible at for 180 days. Only present when status is "completed".
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Image tools in a consistent manner.
```typescript theme={null}
const imageService = {
mcpServer: 'https://image.mcp.atxp.ai/',
createImageToolName: 'image_create_image',
createImageAsyncToolName: 'image_create_image_async',
getImageAsyncToolName: 'image_get_image_async',
description: 'ATXP Image MCP server',
getArguments: (
prompt: string,
options?: {
model?: string;
aspectRatio?: string;
referenceImages?: Array<{ url: string; description?: string }>;
}
) => ({
prompt,
...(options?.model && { model: options.model }),
...(options?.aspectRatio && { aspectRatio: options.aspectRatio }),
...(options?.referenceImages && { referenceImages: options.referenceImages })
}),
getResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { status: parsed.status, url: parsed.url };
},
getAsyncCreateResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { taskId: parsed.taskId };
},
getAsyncStatusResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { status: parsed.status, url: parsed.url };
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: imageService.mcpServer,
account,
});
```
Call the Image tool by passing your natural-language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const prompt = "Create an image of a cat riding a horse. Use a realistic style.";
try {
const result = await client.callTool({
name: imageService.createImageToolName,
arguments: imageService.getArguments(prompt),
});
const { status, url } = imageService.getResult(result);
console.log('Status:', status);
console.log('URL:', url);
} catch (error) {
console.error(`Error with ${imageService.description}:`, error);
process.exit(1);
}
```
You should see the result of the image creation printed in your console.
**Using model and aspect ratio:**
```typescript theme={null}
const prompt = "A panoramic landscape with mountains";
try {
const result = await client.callTool({
name: imageService.createImageToolName,
arguments: imageService.getArguments(prompt, {
model: 'gpt-4o',
aspectRatio: '16:9'
}),
});
const { status, url } = imageService.getResult(result);
console.log('Status:', status);
console.log('URL:', url);
} catch (error) {
console.error(`Error with ${imageService.description}:`, error);
process.exit(1);
}
```
**Using reference images:**
```typescript theme={null}
const prompt = "Create a product photo with this logo";
try {
const result = await client.callTool({
name: imageService.createImageToolName,
arguments: imageService.getArguments(prompt, {
referenceImages: [
{
url: 'https://example.com/logo.png',
description: 'use as logo in corner'
}
]
}),
});
const { status, url } = imageService.getResult(result);
console.log('Status:', status);
console.log('URL:', url);
} catch (error) {
console.error(`Error with ${imageService.description}:`, error);
process.exit(1);
}
```
For longer image generation tasks, use the async tools to avoid blocking your application. Start the generation and poll for completion.
```typescript theme={null}
const prompt = "Create an image of a cat riding a horse. Use a realistic style.";
try {
// Start async image generation
const asyncResult = await client.callTool({
name: imageService.createImageAsyncToolName,
arguments: imageService.getArguments(prompt),
});
const { taskId } = imageService.getAsyncCreateResult(asyncResult);
console.log('Task started with ID:', taskId);
// Poll for completion
let completed = false;
while (!completed) {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
const statusResult = await client.callTool({
name: imageService.getImageAsyncToolName,
arguments: { taskId },
});
const { status, url } = imageService.getAsyncStatusResult(statusResult);
console.log('Status:', status);
if (status === 'completed') {
console.log('URL:', url);
completed = true;
} else if (status === 'failed') {
console.error('Image generation failed');
completed = true;
}
}
} catch (error) {
console.error(`Error with ${imageService.description}:`, error);
process.exit(1);
}
```
You should see the task ID printed first, followed by status updates, and finally the image URL when generation completes.
# Available Tools
Source: https://docs.atxp.ai/tools/index
Pay-per-use tools for AI agents, powered by ATXP.
# Tools you can use
[ATXP](https://atxp.ai) provides a collection of paid tools via MCP (Model Context Protocol) servers. Each tool handles specific tasks, from web browsing and search to creative content generation.
## How to use these tools
Install the ATXP plugin and use tools directly:
```text Claude Code theme={null}
/plugin marketplace add atxp-dev/claude
/setup
```
Then ask naturally: "Search the web for..." or "Generate an image of..."
Connect via the [@atxp/client](https://www.npmjs.com/package/@atxp/client) SDK. Each tool page shows the MCP server URL and usage examples.
## Web and Data Services
Scrape and crawl websites to extract text content from single or multiple pages.
Execute web searches and get structured results with titles, URLs, and content.
Search X (Twitter) with filters for handles, engagement metrics, and date ranges.
Send and receive emails with your own ATXP email address.
## Data Storage and Management
Store, retrieve, and delete files with base64, URL sources, and access controls.
## Creative Content Generation
Generate images from text prompts with sync and async options.
Create music from lyrics and style prompts across various genres.
Generate videos from text prompts with realistic styles.
## Development and Code
Execute code in a sandboxed environment (JavaScript, Python, TypeScript).
## Need a different tool?
Can't find what you need? We build new tools based on feedback.
# Music
Source: https://docs.atxp.ai/tools/music
Create and edit music
## Overview
Use the Music MCP server from your ATXP-powered agent to create music from a natural-language prompt.
## Example prompts
* "Create a modern country song about a cat riding a horse."
* "Create an electronic dance music song about a child and a puppy."
## Tools
Take in lyrics and prompt and produce a hex encoded MP3 file. An example prompt would be "polka, upbeat, fast". Example lyrics would be "\[intro]Hey there cowboy\[verse]That's a mighty fine horse you got\[outro]". The output will contain a URL to the MP3 file.
### Arguments
Accepts a JSON object with the following properties:
The prompt for the music. For example, what style of music to create. Example: "blues, melancholic, raw, lonely bar, heartbreak"
The lyrics you would like to include in the music. You can use new lines to separate verses. You can use \[intro]\[verse]\[chorus]\[bridge]\[outro] to specify the structure of the song. Defaults to "\[instrumental]" for instrumental music.
### Response
Returns a JSON object with the following properties:
The status of the music generation operation. Returns "success" when the music is generated successfully.
The URL that the generated MP3 file is accessible at.
Takes in lyrics and prompt and starts asynchronous music generation. Returns a task ID that can be used to check status and retrieve the result. Use this for longer music generation tasks to avoid timeouts.
### Arguments
Accepts a JSON object with the following properties:
The prompt for the music. For example, what style of music to create. Example: "blues, melancholic, raw, lonely bar, heartbreak"
The lyrics you would like to include in the music. You can use new lines to separate verses. You can use \[intro]\[verse]\[chorus]\[bridge]\[outro] to specify the structure of the song. Defaults to "\[instrumental]" for instrumental music.
### Response
Returns a JSON object with the following properties:
A unique task identifier that can be used with `music_get_async` to check the status and retrieve the result.
Retrieves the status and result of an asynchronous music generation task using the task ID. Tasks expire after 12 hours.
### Arguments
Accepts a JSON object with the following properties:
The task ID returned from `music_create_async`.
### Response
Returns a JSON object with the following properties:
The current status of the task. Can be "pending", "running", "completed", or "error".
The URL that the generated MP3 file is accessible at. Only present when status is "completed".
Timestamp when the task was created.
Timestamp when the task was completed. Only present when status is "completed" or "error".
Error message if the task failed. Only present when status is "error".
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Music tools in a consistent manner.
```typescript theme={null}
const musicService = {
mcpServer: 'https://music.mcp.atxp.ai/',
createMusicToolName: 'music_create',
createMusicAsyncToolName: 'music_create_async',
getMusicAsyncToolName: 'music_get_async',
description: 'ATXP Music MCP server',
getArguments: (prompt: string, lyrics: string) => ({ prompt, lyrics }),
getResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { status: parsed.status, url: parsed.url };
},
getAsyncCreateResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { taskId: parsed.taskId };
},
getAsyncStatusResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { status: parsed.status, url: parsed.url, createdAt: parsed.createdAt, completedAt: parsed.completedAt, errorMessage: parsed.errorMessage };
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: musicService.mcpServer,
account,
});
```
Call the Music tool by passing your natural-language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const prompt = "polka, upbeat, fast";
const lyrics = "[intro]Hey there cowboy[verse]That's a mighty fine horse you got[outro]";
try {
const result = await client.callTool({
name: musicService.createMusicToolName,
arguments: musicService.getArguments(prompt, lyrics),
});
const { status, url } = musicService.getResult(result);
console.log('Status:', status);
console.log('URL:', url);
} catch (error) {
console.error(`Error with ${musicService.description}:`, error);
process.exit(1);
}
```
You should see the result of the music creation printed in your console.
For longer music generation tasks (which can take 1-3 minutes), use the async tools to avoid blocking your application. Start the generation and poll for completion.
```typescript theme={null}
const prompt = "polka, upbeat, fast";
const lyrics = "[intro]Hey there cowboy[verse]That's a mighty fine horse you got[outro]";
try {
// Start async music generation
const asyncResult = await client.callTool({
name: musicService.createMusicAsyncToolName,
arguments: musicService.getArguments(prompt, lyrics),
});
const { taskId } = musicService.getAsyncCreateResult(asyncResult);
console.log('Task started with ID:', taskId);
// Poll for completion
let completed = false;
while (!completed) {
await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds
const statusResult = await client.callTool({
name: musicService.getMusicAsyncToolName,
arguments: { taskId },
});
const { status, url, errorMessage } = musicService.getAsyncStatusResult(statusResult);
console.log('Status:', status);
if (status === 'completed') {
console.log('URL:', url);
completed = true;
} else if (status === 'error') {
console.error('Music generation failed:', errorMessage);
completed = true;
}
}
} catch (error) {
console.error(`Error with ${musicService.description}:`, error);
process.exit(1);
}
```
You should see the task ID printed first, followed by status updates, and finally the music URL when generation completes.
# Search
Source: https://docs.atxp.ai/tools/search
Search the web
## Overview
Use the Search MCP server from your ATXP-powered agent to search the web and extract information.
## Example prompts
* "Search the web for the latest news on the US financial sector and its impact on the stock market."
* "Search for MCP servers that can be used with an ATXP agent."
## Tools
Executes a search query against the internet. An example of how it would be used is if you want to find the latest news on a topic.
### Arguments
Accepts a JSON object with the following properties:
The search query to execute.
### Response
Returns a JSON object with the following properties:
The status of the search operation. Returns "success" when the search is completed successfully, otherwise returns "error".
The error message if the search operation fails. This is only returned when `status === "error"`.
The results of the search query. This is only returned when `status === "success"`.
The title of the result.
The URL of the result.
The text of the result.
The date at which the result was published.
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Search tools in a consistent manner.
```typescript theme={null}
const searchService = {
mcpServer: 'https://search.mcp.atxp.ai/',
searchToolName: 'search_search',
description: 'ATXP Search MCP server',
getArguments: (query: string) => ({ query }),
getResult: (result: any) => JSON.parse(result.content[0].text)
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: searchService.mcpServer,
account,
});
```
Call the Search tool by passing your natural‑language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const prompt = "Search for MCP servers that can be used with an ATXP agent.";
try {
const result = await client.callTool({
name: searchService.searchToolName,
arguments: searchService.getArguments(prompt),
});
const searchResult = searchService.getResult(result);
console.log('Status:', searchResult.status);
if (searchResult.status === "success") {
console.log('Results:', searchResult.results);
} else {
console.log('Error Message:', searchResult.errorMessage);
}
} catch (error) {
console.error(`Error with ${searchService.description}:`, error);
process.exit(1);
}
```
You should see the result of the search printed in your console.
# Video
Source: https://docs.atxp.ai/tools/video
Create and edit videos
## Overview
Use the Video MCP server from your ATXP-powered agent to create videos based on a prompt.
## Example prompts
* "Create a video of a cat riding a horse. Use a realistic style."
* "Create a video of a child and a puppy."
## Tools
Request text-to-video generation based on the given user prompt. After requesting the video, use the waitForVideo tool to wait for completion and get the resulting video. The status will be "success" and the task ID will be returned.
### Arguments
Accepts a JSON object with the following properties:
The natural language description of the video to generate
### Response
Returns a JSON object with the following properties:
The status of the video generation operation. Returns "success" when the video is generated successfully.
The task ID of the video generation operation.
Wait for a previously requested video to be generated and return the video URL. When the video generation is complete, the status will be "success" and the video URL will be returned. If the video is not generated within the timeout, it will return status "in\_progress" to indicate the video is still processing.
### Arguments
Accepts a JSON object with the following properties:
The ID of the video generation task to wait for.
Maximum time to wait for task completion in seconds.
### Response
Returns a JSON object with the following properties:
The status of the video generation operation. Returns "success" when the video is generated successfully, "in\_progress" if the timeout is reached before completion, or "error" if the generation failed.
The URL that the generated video is accessible at (only present when status is "success").
Error message describing what went wrong (only present when status is "error").
If the timeout is reached before the video completes, the tool will return `status: "in_progress"` instead of throwing an error. This allows clients to handle the timeout gracefully and check again later if needed.
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the Video tools in a consistent manner.
```typescript theme={null}
const videoService = {
mcpServer: 'https://video.mcp.atxp.ai/',
createVideoToolName: 'create_video',
waitForVideoToolName: 'wait_for_video',
description: 'ATXP Video MCP server',
getCreateVideoArguments: (prompt: string) => ({ userPrompt: prompt }),
getWaitForVideoArguments: (taskId: string) => ({ taskId, timeoutSeconds: 300 }),
getCreateVideoResult: (result: any) => JSON.parse(result.content[0].text),
getWaitForVideoResult: (result: any) => JSON.parse(result.content[0].text)
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: videoService.mcpServer,
account,
});
```
Call the Video tool by passing your natural-language instruction as the argument the `getArguments` method.
Read the response using the `getResult` method.
```typescript theme={null}
const prompt = "Create a video of a cat riding a horse. Use a realistic style.";
try {
const result = await client.callTool({
name: videoService.createVideoToolName,
arguments: videoService.getCreateVideoArguments(prompt),
});
const createVideoResult = videoService.getCreateVideoResult(result);
console.log('Status:', createVideoResult.status);
console.log('Task ID:', createVideoResult.taskId);
const pollInterval = 15000; // 15 seconds
while (true) {
const result = await client.callTool({
name: videoService.waitForVideoToolName,
arguments: videoService.getWaitForVideoArguments(createVideoResult.taskId),
});
const waitForVideoResult = videoService.getWaitForVideoResult(result);
console.log('Status:', waitForVideoResult.status);
// Check if task is complete
if (waitForVideoResult.status === 'success') {
console.log(`${videoService.description} has generated a video!`);
console.log('URL:', waitForVideoResult.url);
break;
}
// Check if there was an error
if (waitForVideoResult.status === 'error') {
console.error(`${videoService.description} error:`, waitForVideoResult.errorMessage);
process.exit(1);
}
// Status is 'in_progress', continue polling
console.log(`${videoService.description} result pending (in_progress).`);
await new Promise(resolve => setTimeout(resolve, pollInterval));
}
} catch (error) {
console.error(`Error with ${videoService.description}:`, error);
process.exit(1);
}
```
You should see the result of the video creation printed in your console.
# X Live Search
Source: https://docs.atxp.ai/tools/x-live-search
Search X (formerly Twitter) for posts and conversations
## Overview
Use the X Live Search MCP server from your ATXP-powered agent to search X (formerly Twitter) for posts and conversations using xAI's Grok models. Powered by xAI's Agentic Search Tools API, the server uses AI agents that autonomously explore and make follow-up queries to provide comprehensive search results with citations.
## Example prompts
* "What are the latest updates from Stripe?"
* "Find popular tweets about AI from the last week with at least 100 likes"
* "Search for posts from @elonmusk about SpaceX"
## Tools
Searches X (formerly Twitter) for posts matching the query and optional filters using xAI's Agentic Search Tools API. The AI agent autonomously explores and makes follow-up queries to provide comprehensive results with citations to source posts.
### Arguments
Accepts a JSON object with the following properties:
The search query to execute on X (formerly Twitter). Natural language queries work best with the agentic search API.
List of X handles to include in search (up to 10). Format without @ symbol, e.g., \["elonmusk", "OpenAI"].
List of X handles to exclude from search (up to 10). Format without @ symbol.
Start date for posts in ISO8601 format (YYYY-MM-DD).
End date for posts in ISO8601 format (YYYY-MM-DD).
Enable AI analysis of images in posts. Increases token usage.
Enable AI analysis of videos in X posts. Increases token usage.
Enable web search beyond X to find additional context and information.
When web search is enabled, limit results to these domains (e.g., \["arxiv.org", "openai.com"]).
Minimum number of likes/favorites. Only returns posts with at least this many likes.
Minimum number of retweets. Only returns posts with at least this many retweets.
Minimum number of replies. Only returns posts with at least this many replies.
### Response
Returns a JSON object with the following properties:
The status of the search operation. Returns "success" when the search completes successfully, or "error" on failure.
The original search query that was executed.
AI-generated summary of the search findings. Only present when status is "success".
Array of X post URLs used as sources for the summary. Only present when status is "success".
Array of tool calls made by the AI agent during search, showing what searches were performed. Each object contains function name and arguments. Only present when status is "success".
Error details if the search failed. Only present when status is "error".
Starts an asynchronous search of X (formerly Twitter) for posts matching the query and optional filters using xAI's Agentic Search Tools API. Returns a task ID immediately that can be used to check status and retrieve results. This is useful for avoiding timeouts on long-running searches.
### Arguments
Accepts a JSON object with the following properties:
The search query to execute on X (formerly Twitter). Natural language queries work best with the agentic search API.
List of X handles to include in search (up to 10). Format without @ symbol, e.g., \["elonmusk", "OpenAI"].
List of X handles to exclude from search (up to 10). Format without @ symbol.
Start date for posts in ISO8601 format (YYYY-MM-DD).
End date for posts in ISO8601 format (YYYY-MM-DD).
Enable AI analysis of images in posts. Increases token usage.
Enable AI analysis of videos in X posts. Increases token usage.
Enable web search beyond X to find additional context and information.
When web search is enabled, limit results to these domains (e.g., \["arxiv.org", "openai.com"]).
Minimum number of likes/favorites. Only returns posts with at least this many likes.
Minimum number of retweets. Only returns posts with at least this many retweets.
Minimum number of replies. Only returns posts with at least this many replies.
### Response
Returns a JSON object with the following properties:
A unique task identifier that can be used with `x_get_search_async` to check the status and retrieve the result.
Retrieves the status and result of an asynchronous X search task using the task ID. Tasks expire after 12 hours.
### Arguments
Accepts a JSON object with the following properties:
The task ID returned from `x_live_search_async`.
### Response
Returns a JSON object with the following properties:
The current status of the task. Can be "pending", "in\_progress", "completed", or "error".
The search result object. Only present when status is "completed". Contains the same fields as the `x_live_search` response (status, query, message, citations, toolCalls).
Error details if the search failed. Only present when status is "error".
Unix timestamp (in milliseconds) when the task was created.
Unix timestamp (in milliseconds) when the task completed. Only present when status is "completed" or "error".
## Usage
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the X Live Search tool in a consistent manner.
```typescript theme={null}
const xLiveSearchService = {
mcpServer: 'https://x-live-search.mcp.atxp.ai/',
toolName: 'x_live_search',
asyncSearchToolName: 'x_live_search_async',
getSearchAsyncToolName: 'x_get_search_async',
description: 'ATXP X Live Search MCP server',
getArguments: (params: {
query: string,
allowed_x_handles?: string[],
excluded_x_handles?: string[],
from_date?: string,
to_date?: string,
enable_image_understanding?: boolean,
enable_video_understanding?: boolean,
enable_web_search?: boolean,
allowed_domains?: string[],
min_likes?: number,
min_retweets?: number,
min_replies?: number
}) => params,
getResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return {
status: parsed.status,
query: parsed.query,
message: parsed.message,
citations: parsed.citations,
toolCalls: parsed.toolCalls,
errorMessage: parsed.errorMessage
};
},
getAsyncCreateResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return { taskId: parsed.taskId };
},
getAsyncStatusResult: (result: any) => {
const jsonResult = result.content[0].text;
const parsed = JSON.parse(jsonResult);
return {
status: parsed.status,
result: parsed.result,
error: parsed.error,
createdAt: parsed.createdAt,
completedAt: parsed.completedAt
};
}
};
```
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK
import { atxpClient, ATXPAccount } from '@atxp/client';
// Read the ATXP account details from environment variables
const atxpConnectionString = process.env.ATXP_CONNECTION;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account: new ATXPAccount(atxpConnectionString),
});
```
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Base account
import { atxpClient } from '@atxp/client';
import { BaseAccount } from '@atxp/base';
// Read the Base account details from the environment variables
const baseRpcUrl = process.env.BASE_RPC_URL;
const basePrivateKey = process.env.BASE_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account: new BaseAccount(baseRpcUrl, basePrivateKey),
});
```
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
```typescript theme={null}
// Import the ATXP client SDK and Solana account
import { atxpClient } from '@atxp/client';
import { SolanaAccount } from '@atxp/solana';
// Read the Solana account details from the environment variables
const solanaRpcUrl = process.env.SOLANA_RPC_URL;
const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),
});
```
Create a client using a Worldchain account with MiniKit integration.
```typescript theme={null}
// Import the ATXP client SDK and Worldchain account creator
import { atxpClient } from '@atxp/client';
import { createMiniKitWorldchainAccount } from '@atxp/worldchain';
import { MiniKit } from '@worldcoin/minikit-js';
// Create a Worldchain account using MiniKit
const account = await createMiniKitWorldchainAccount({
walletAddress: '0x1234...', // User's wallet address
miniKit: MiniKit
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account,
});
```
**Browser applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon browser account
import { atxpClient } from '@atxp/client';
import { PolygonBrowserAccount } from '@atxp/polygon';
// Initialize the Polygon browser account with wallet provider
const account = await PolygonBrowserAccount.initialize({
provider: window.ethereum, // or any EIP-1193 provider
walletAddress: '0x1234...', // User's wallet address
});
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account,
});
```
**Server/CLI applications:**
```typescript theme={null}
// Import the ATXP client SDK and Polygon server account
import { atxpClient } from '@atxp/client';
import { PolygonServerAccount } from '@atxp/polygon';
// Read the Polygon account details from the environment variables
const polygonRpcUrl = process.env.POLYGON_RPC_URL;
const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;
// Create a Polygon server account
const account = new PolygonServerAccount(
polygonRpcUrl,
polygonPrivateKey,
137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet
);
// Create a client using the `atxpClient` function
const client = await atxpClient({
mcpServer: xLiveSearchService.mcpServer,
account,
});
```
Call the X Live Search tool by passing your search query and optional filters as arguments.
Read the response using the `getResult` method.
```typescript theme={null}
const searchParams = {
query: "What are the latest updates from Stripe?",
allowed_x_handles: ["stripe"],
from_date: "2024-01-01",
min_likes: 100 // Only show posts with at least 100 likes
};
try {
const result = await client.callTool({
name: xLiveSearchService.toolName,
arguments: xLiveSearchService.getArguments(searchParams),
});
const { status, query, message, citations, toolCalls, errorMessage } = xLiveSearchService.getResult(result);
if (status === 'success') {
console.log('Query:', query);
console.log('Summary:', message);
console.log('Citations:', citations);
console.log('Tool Calls:', toolCalls); // See what the agent did
} else {
console.error('Search failed:', errorMessage);
}
} catch (error) {
console.error(`Error with ${xLiveSearchService.description}:`, error);
process.exit(1);
}
```
You should see the search summary and citations printed in your console.
For longer search tasks or to avoid timeouts, use the async tools to start the search and poll for completion.
```typescript theme={null}
const searchParams = {
query: "What are the latest updates from Stripe?",
allowed_x_handles: ["stripe"],
from_date: "2024-01-01",
min_likes: 100 // Only show posts with at least 100 likes
};
try {
// Start async search
const asyncResult = await client.callTool({
name: xLiveSearchService.asyncSearchToolName,
arguments: xLiveSearchService.getArguments(searchParams),
});
const { taskId } = xLiveSearchService.getAsyncCreateResult(asyncResult);
console.log('Search started with task ID:', taskId);
// Poll for completion
let completed = false;
while (!completed) {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
const statusResult = await client.callTool({
name: xLiveSearchService.getSearchAsyncToolName,
arguments: { taskId },
});
const { status, result, error } = xLiveSearchService.getAsyncStatusResult(statusResult);
console.log('Status:', status);
if (status === 'completed') {
console.log('Query:', result.query);
console.log('Summary:', result.message);
console.log('Citations:', result.citations);
console.log('Tool Calls:', result.toolCalls); // See what the agent did
completed = true;
} else if (status === 'error') {
console.error('Search failed:', error);
completed = true;
}
}
} catch (error) {
console.error(`Error with ${xLiveSearchService.description}:`, error);
process.exit(1);
}
```
You should see the task ID printed first, followed by status updates, and finally the search summary and citations when the search completes.
# x402 MCP servers
Source: https://docs.atxp.ai/tools/x402
ATXP clients may access x402 MCP servers by using an adapter
If you’d like your agent to access the [x402 ecosystem](https://www.x402.org/ecosystem) in addition to [ATXP MCP servers](/tools), there is an adapter available.
To install it, run:
```bash theme={null}
npm i -S @atxp/x402
```
Then import it:
```typescript theme={null}
import { wrapWithX402 } from "@atxp/x402";
```
And use it in your application:
```typescript theme={null}
const mcpClient = await atxpClient({
...config,
fetchFn: wrapWithX402(config) // [!code ++]
});
```
Now your agent can access x402-compatible MCP servers!