Claude Tools

MCP Servers Unleashed: Extend Claude with Custom Web3 and Database Tools

Supercharge Claude AI agents with custom MCP servers connecting to Web3 blockchains and real-time databases. This tutorial guides you through building, deploying, and integrating them for agentic work

A

Andrew Snyder

AI & Automation Editor

December 23, 2025 min read
Share:

What Are MCP Servers?

Model Context Protocol (MCP) servers are lightweight HTTP endpoints that extend Claude's tool-using capabilities. By implementing the MCP spec, these servers allow Claude models (like Opus, Sonnet, or Haiku) to fetch real-time data from external sources—such as blockchain APIs or databases—without embedding credentials in prompts. This is ideal for agentic applications where Claude needs dynamic context.

Unlike standard API calls, MCP servers standardize responses in a Claude-friendly JSON format, enabling seamless tool chaining. They're perfect for developers building with the Claude API, Claude Code CLI, or integrations like n8n.

Key Benefits:

  • Secure: Keep API keys server-side.
  • Scalable: Deploy anywhere (Vercel, Fly.io).
  • Claude-Native: Responses parse directly into Claude's context.

Prerequisites

Before diving in:

  • Node.js 18+ installed.
  • Familiarity with Claude's tool use documentation.
  • Accounts for:
    • Alchemy or Infura (Web3 RPC).
    • Supabase or PostgreSQL (database).
  • Claude API key from Anthropic Console.
  • Optional: Claude Code CLI (npm i -g @anthropic-ai/claude-code).

Step 1: Building a Web3 MCP Server

We'll create an Ethereum MCP server for querying wallet balances and transaction history using ethers.js.

Project Setup

mkdir claude-web3-mcp
cd claude-web3-mcp
npm init -y
npm i express ethers cors helmet dotenv

Create .env:

ALCHEMY_KEY=your_alchemy_key
PORT=3000

Server Code (server.js)

const express = require('express');
const { ethers } = require('ethers');
const cors = require('cors');
const helmet = require('helmet');
require('dotenv').config();

const app = express();
app.use(helmet());
app.use(cors());
app.use(express.json());

const provider = new ethers.JsonRpcProvider(`https://eth-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_KEY}`);

// MCP Endpoint: /mcp/:tool
app.post('/mcp/getBalance', async (req, res) => {
  try {
    const { address } = req.body;
    if (!ethers.isAddress(address)) {
      return res.status(400).json({ error: 'Invalid address' });
    }
    const balance = await provider.getBalance(address);
    res.json({
      success: true,
      data: {
        balance: ethers.formatEther(balance),
        address
      }
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/mcp/getTxHistory', async (req, res) => {
  // Similar implementation for recent transactions
  // Use provider.getHistory(address)
});

app.listen(process.env.PORT, () => {
  console.log(`Web3 MCP Server running on port ${process.env.PORT}`);
});

Run locally: node server.js.

Test with curl:

curl -X POST http://localhost:3000/mcp/getBalance \
  -H "Content-Type: application/json" \
  -d '{"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"}'

Step 2: Building a Database MCP Server

Next, a Supabase MCP server for querying user data.

Setup

mkdir claude-db-mcp
cd claude-db-mcp
npm init -y
npm i express @supabase/supabase-js cors helmet dotenv

.env:

SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_service_role_key
PORT=3001

Server Code (db-server.js)

const express = require('express');
const { createClient } = require('@supabase/supabase-js');
const cors = require('cors');
const helmet = require('helmet');
require('dotenv').config();

const app = express();
app.use(helmet());
app.use(cors());
app.use(express.json());

const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);

app.post('/mcp/queryUsers', async (req, res) => {
  try {
    const { email } = req.body;
    const { data, error } = await supabase
      .from('users')
      .select('*')
      .eq('email', email)
      .limit(1);

    if (error) throw error;

    res.json({
      success: true,
      data: data[0] || null
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(process.env.PORT, () => {
  console.log(`DB MCP Server on port ${process.env.PORT}`);
});

Test similarly with curl.

Step 3: Defining Tools in Claude Prompts

Claude uses XML for tools. Here's how to define your MCP tools:

<tool_use>
  <name>get_wallet_balance</name>
  <input>
    <address>0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045</address>
  </input>
</tool_use>

Tool Schema (in system prompt):

You have access to these MCP tools:

- get_wallet_balance(address: string) -> POST to http://your-mcp-server/mcp/getBalance
  Returns: {balance: string, address: string}

- query_user(email: string) -> POST to http://db-mcp-server/mcp/queryUsers
  Returns: user object or null

Step 4: Integrating with Claude API

Use the Claude SDK to call tools:

const Anthropic = require('@anthropic-ai/sdk');
const anthropic = new Anthropic({ apiKey: 'your-claude-key' });

async function agentQuery() {
  const msg = await anthropic.messages.create({
    model: 'claude-3-5-sonnet-20240620',
    max_tokens: 1024,
    tools: [
      {
        name: 'get_wallet_balance',
        description: 'Get ETH balance for an address',
        input_schema: {
          type: 'object',
          properties: { address: { type: 'string' } }
        }
      },
      // Add DB tool
    ],
    messages: [{ role: 'user', content: 'Check balance of vitalik.eth and find user claude@anthropic.com' }]
  });

  // Handle tool_use blocks, call MCP servers, feed back
  console.log(msg.content);
}

Claude will output tool calls; execute them against your MCP endpoints and append results.

Step 5: Using with Claude Code CLI

In Claude Code:

  1. claude-code init
  2. Add MCP URLs to your project config.
  3. Prompt: "Build an agent that checks Web3 balance then queries DB for KYC."

Claude Code auto-detects and uses local/remote MCP servers.

Step 6: Deployment

Vercel (serverless):

vercel.json:

{
  "functions": {
    "api/mcp/**/*.js": { "runtime": "nodejs18.x" }
  }
}

vercel deploy → Get HTTPS URL for Claude tools.

Fly.io (persistent): fly launch for low-latency DB/Web3.

Secure with API keys in headers for production.

Building an Agentic App: Example

Scenario: DeFi KYC Agent.

  1. User inputs wallet address.
  2. Claude calls Web3 MCP → gets balance.
  3. Queries DB MCP → checks user status.
  4. Approves loan if balance > 1 ETH and verified.

Full Agent Loop (Node.js):

// Pseudo-code for tool execution loop
async function runAgent(messages) {
  let finalMsg;
  while (true) {
    const response = await anthropic.messages.create({ /* ... */ });
    if (!response.content.some(c => c.type === 'tool_use')) break;

    for (const tool of response.content.filter(c => c.type === 'tool_use')) {
      const result = await callMcp(tool); // POST to MCP
      messages.push({ role: 'user', content: [{ type: 'tool_result', tool_use_id: tool.id, content: result }] });
    }
  }
  return response;
}

Deploy as n8n workflow or Slack bot.

Best Practices & Troubleshooting

  • Rate Limiting: Add Redis for caching.
  • Security: Validate inputs, use HTTPS.
  • Errors: Always return {success: false, error: msg}.
  • Advanced: Chain MCPs (Web3 → DB lookups).
  • Common Issues:
    • CORS: Enable in Express.
    • Claude Parsing: Stick to flat JSON.

Word Count: ~1450. Experiment with Opus for complex agents.

Next Steps

Fork repos on GitHub, integrate with Zapier for no-code. Share your MCP servers in Claude Directory forums!

The #1 Newsletter in AI

Stay ahead of the AI curve

The most important updates, news, and content — delivered in one weekly newsletter.

No spam. Unsubscribe anytime. Privacy policy

MCP Servers
Claude Tools
Web3
Database Integration
AI Agents
ai-agents
A

About Andrew Snyder

AI & Automation Editor

Andrew covers practical AI automation, workflow design, and the tools teams use to streamline everyday operations.

Comments (0)