Learn how to rapidly build an AI-powered chatbot that demonstrates the BatchData MCP server using Replit's coding agent and AI-assisted development best practices.
Overview
This guide walks you through creating a demo application that showcases the BatchData MCP (Model Context Protocol) server. The app provides a simple AI chatbot interface where users can query property data using natural language—making it an excellent tool for exploring MCP capabilities before integrating them into production applications.
What You'll Build: - A real-time chatbot interface - Natural language queries for property lookups, skip tracing, and comparable properties - Dual response display: human-readable summaries and raw JSON data - WebSocket-based communication with the BatchData MCP server
Time to Build: ~15-30 minutes with Replit Agent
Prerequisites
A Replit account
A BatchData API key (get one here)
Basic familiarity with web applications
The AI-Assisted Development Approach
Why Start with Planning?
When using AI coding assistants like Replit Agent, the quality of your output directly correlates with the quality of your input. Rather than jumping straight into code, we followed established best practices for AI-assisted development:
Define the goal clearly - What exactly should the app do?
Capture requirements - What features, tools, and behaviors are needed?
Create a structured prompt - Translate requirements into actionable instructions
Iterate and refine - Test and adjust based on results
How We Built This Prompt
We used Claude to help compile requirements and create the Replit Agent prompt. Here's how the process worked:
Starting Point:
"I want to create a demo app that could be built in Replit that would create a simple AI chatbot that makes use of the BatchData MCP server."
Key Decisions Made During Planning:
Reference Property - We chose a specific address for all examples:
632 W Palmaire Ave, Phoenix, AZ 85021
Coordinates: 33.541474, -112.081784
Response Display - We specified that the app should show both:
A formatted, human-readable summary of key data points
The complete raw JSON response for transparency and debugging
Tool Selection - We identified which BatchData MCP tools to support and how to map natural language queries to them
API Response Structure - We documented the actual response format from testing to ensure the app parses data correctly
This planning process with Claude produced a comprehensive prompt that Replit Agent can use to build the complete application.
Step-by-Step Guide
Step 1: Create a New Replit Project
Go to replit.com and sign in
Click Projects in the left sidebar
Click Create Project
Name your project (e.g., "BatchData-MCP-Demo")
Click Create Project to confirm
Step 2: Create an App with Replit Agent
Inside your new project, click Create App (or use the + button)
Select Agent to use the AI coding assistant
Copy the entire prompt from the The Prompt section below
Paste it into the Replit Agent chat
Let the agent build your application
The agent will: - Set up the Express server with WebSocket support - Implement the MCP client integration - Create the React frontend with the chat interface - Build the ResponseCard component for formatting responses - Configure the build system
Step 3: Add Your API Key
After the agent creates your app, add your BatchData API key as a secret:
In your Replit app workspace, use the Search bar (magnifying glass icon) and type "Secrets"
Select Secrets from the search results
Click New Secret
Set the Key as
BATCHDATA_API_KEYPaste your BatchData API key as the Value
Click Add Secret
Note: Secrets are encrypted and injected as environment variables when your app runs. They are not committed to version control.
Step 4: Test Your App
Once the agent finishes, click Run to start the application. Try these example queries:
Query | What It Does |
"Verify the address 632 W Palmaire Ave, Phoenix, AZ 85021" | Validates and standardizes the address |
"Lookup property details for 632 W Palmaire Ave, Phoenix, AZ 85021" | Returns property characteristics, valuation, and owner info |
"Find comparable properties to 632 W Palmaire Ave, Phoenix, AZ 85021" | Finds similar properties with pricing metrics |
"Geocode 632 W Palmaire Ave, Phoenix, AZ 85021" | Converts address to latitude/longitude |
"Reverse geocode 33.541474, -112.081784" | Converts coordinates to an address |
"Skip trace the owner at 632 W Palmaire Ave, Phoenix, AZ 85021" | Finds owner contact information |
Step 5: Deploy (Optional)
To share your demo app:
Click Publish in the top-right corner
Choose your deployment settings
Click Publish to make it live
Understanding the App Architecture
How It Works
┌─────────────────┐ WebSocket ┌─────────────────┐
│ React Frontend │◄──────────────────►│ Express Server │
│ (Chat UI) │ │ (Node.js) │
└─────────────────┘ └────────┬────────┘
│
│ HTTP + Bearer Auth
▼
┌─────────────────┐
│ BatchData MCP │
│ Server │
│ mcp.batchdata.com│
└─────────────────┘
User enters a query in the chat interface
Frontend sends query via WebSocket to the Express server
Server parses the query to determine intent and extract parameters
Server calls the appropriate MCP tool via the Vercel AI SDK
Response is formatted and sent back to the frontend
Frontend displays both formatted summary and raw JSON
Supported MCP Tools
Tool | Description | Example Query |
| Validate and standardize addresses | "Verify 123 Main St, Phoenix, AZ" |
| Get property details and valuation | "Lookup property at 123 Main St" |
| Convert address to coordinates | "Geocode 123 Main St, Phoenix, AZ" |
| Convert coordinates to address | "Reverse geocode 33.45, -112.07" |
| Find comparable properties | "Find comps for 123 Main St" |
| Find owner contact info | "Skip trace owner at 123 Main St" |
| Validate phone numbers | "Verify phone 6025551234" |
| Check Do Not Call registry | "Check DNC for 6025551234" |
| Check TCPA compliance | "Check TCPA for 6025551234" |
Response Display
Each response shows two views:
Formatted Summary - Human-readable card highlighting key information:
✅ Address Verified632 W Palmaire Ave Phoenix, AZ 85021-8767County: Maricopa Congressional District: 01 Time Zone: Mountain (UTC-7) Vacant: No📍 Coordinates: 33.541180, -112.081990
Raw JSON - Collapsible section with the complete API response for debugging and integration planning.
The Prompt
Copy the entire prompt below and paste it into Replit Agent to build your demo app.
Create a real-time chatbot application that demonstrates the BatchData MCP (Model Context Protocol) server for property intelligence. The app should let users query real estate data using natural language.## Tech Stack
- **Frontend**: React, TypeScript, TailwindCSS
- **Backend**: Express.js with WebSocket support
- **MCP Integration**: Vercel AI SDK (@ai-sdk/mcp)
- **Build**: Vite for frontend, esbuild for server bundling## Environment Variables
BATCHDATA_API_KEY=<user's BatchData API key>## Key Dependencies
{
"dependencies": {
"@ai-sdk/mcp": "^0.0.12",
"@modelcontextprotocol/sdk": "^1.25.1",
"express": "^4.21.2",
"ws": "^8.18.0",
"react": "^19.2.0",
"react-dom": "^19.2.0"
}
}---## SERVER IMPLEMENTATION### MCP Client Integrationimport { experimental_createMCPClient as createMCPClient } from "@ai-sdk/mcp";const MCP_SERVER_URL = "https://mcp.batchdata.com";export async function connectToMCP(serverUrl: string, apiKey: string) {
const mcpClient = await createMCPClient({
transport: {
type: "http",
url: serverUrl,
headers: {
Authorization: `Bearer ${apiKey}`,
},
},
});
const toolSet = await mcpClient.tools();
return { mcpClient, toolSet };
}export async function callMCPTool(toolName: string, args: Record<string, any>) {
const tool = cachedToolSet[toolName];
return await tool.execute(args, { toolCallId: `call_${Date.now()}` });
}### Available BatchData MCP Tools
- verify_address: Verify and standardize an address
- lookup_property: Get property details
- geocode_address: Convert address to coordinates
- reverse_geocode_address: Convert coordinates to address
- comparable_property_preview: Find comparable properties (use this for "find comps" queries)
- skip_trace_property: Find owner contact info
- verify_phone: Validate phone numbers
- check_dnc_status: Check Do Not Call registry
- check_tcpa_status: Check TCPA complianceIMPORTANT: Do NOT use the deprecated `comparable_property` tool. Use `comparable_property_preview` instead.### Query-to-Tool Mapping
Parse natural language queries and map to BatchData MCP tools:
- "verify address..." → verify_address
- "lookup property..." → lookup_property
- "geocode..." → geocode_address
- "reverse geocode..." → reverse_geocode_address
- "comparable properties..." or "find comps..." → comparable_property_preview
- "skip trace..." → skip_trace_property
- "verify phone..." → verify_phone
- "check dnc..." → check_dnc_status
- "check tcpa..." → check_tcpa_status### Tool Parameter Naming
BatchData MCP uses specific parameter prefixes:
- Property lookups: property_street, property_city, property_state, property_zip
- Comparables: subject_property_street, subject_property_city, subject_property_state, subject_property_zip
- Address verification: street, city, state, zip
- Geocoding: property_address (full address string)
- Phone tools: phone_number (10-digit string, no formatting)---## FRONTEND REQUIREMENTS### Core Functionality
1. Chat interface for natural language queries
2. Real-time WebSocket communication with the server
3. Connection status indicator
4. Example queries users can click to try### Response Display (CRITICAL)
Each response MUST display BOTH:
1. **Formatted Summary** - Human-readable display of key data points from the response
2. **Raw JSON** - Collapsible section showing the complete API response (for debugging/transparency)### API Response Structure
MCP tool responses come wrapped in this structure:
{
"content": [{ "type": "text", "text": "<stringified JSON>" }],
"structuredContent": { /* actual data object */ },
"isError": false
}ALWAYS parse from `structuredContent` - this contains the actual data object.
Do NOT parse from `content[0].text` as that's just a stringified version.### Data Parsing HelpersOwner names in responses can be either strings OR objects with {first, last, full} properties.
Use a helper function to safely display names: function getDisplayName(name: any): string {
if (!name) return 'Unknown';
if (typeof name === 'string') return name;
if (typeof name === 'object') {
if (name.full) return name.full;
if (name.first || name.last) {
return ((name.first || '') + ' ' + (name.last || '')).trim();
}
}
return 'Unknown';
}Use this helper for: lookup_property (owner names), skip_trace_property (owner/contact names).Geocode responses may have nested coordinates. Check these paths:
- structuredContent.results[0].latitude/longitude
- structuredContent.result.latitude/longitude
- structuredContent.location.latitude/longitude
- structuredContent.latitude/longitude (direct)### Key Data Points by Tool**verify_address** - structuredContent.address:
- Standardized address (street, city, state, zip, zipPlus4)
- addressValidity field indicates if valid
- County, coordinates, time zone info**lookup_property** - structuredContent.property:
- Address, building info (beds, baths, sqft, year built)
- Valuation (estimatedValue)
- Owner names (use getDisplayName helper)
- Lot size**comparable_property_preview** - structuredContent:
- comparableCount, aggregatedMetrics (averagePrice, pricePerSqFt)
- comparableProperties[] array with address, salePrice, squareFeet, distance**skip_trace_property** - structuredContent:
- Owner/contact names (use getDisplayName helper - names can be objects!)
- Phone numbers with lineType
- Email addresses**geocode_address / reverse_geocode_address**:
- Coordinates (latitude, longitude) - may be nested in results[0] or location
- Formatted address**verify_phone** - structuredContent:
- Valid/invalid status
- Line type, carrier, location**check_dnc_status** - structuredContent:
- Whether phone is on Do Not Call list**check_tcpa_status** - structuredContent:
- Litigator status and compliance info---## BUILD CONFIGURATIONIMPORTANT: Bundle ALL dependencies for reliable deployments. Do NOT mark packages as external.esbuild external setting should be empty or only include Node.js built-ins.
Bundle these packages (required for deployment):
- @ai-sdk/mcp
- @modelcontextprotocol/sdk
- express, ws, and all other dependenciesThis prevents MODULE_NOT_FOUND errors in deployment.### .replit Configuration
modules = ["nodejs-20"]
[deployment]
deploymentTarget = "autoscale"
run = ["npm", "run", "start"]
build = ["npm", "run", "build"]
[[ports]]
localPort = 5000
externalPort = 80---## EXAMPLE QUERIES TO SUPPORTUse this reference address for testing: 632 W Palmaire Ave, Phoenix, AZ 85021
Coordinates: 33.541474, -112.081784- "Verify the address 632 W Palmaire Ave, Phoenix, AZ 85021"
- "Lookup property details for 632 W Palmaire Ave, Phoenix, AZ 85021"
- "Find comparable properties to 632 W Palmaire Ave, Phoenix, AZ 85021"
- "Geocode 632 W Palmaire Ave, Phoenix, AZ 85021"
- "Reverse geocode 33.541474, -112.081784"
- "Skip trace the owner at 632 W Palmaire Ave, Phoenix, AZ 85021"---## DEMO/FALLBACK MODEIf MCP connection fails (e.g., missing API key), show a demo mode that:
- Indicates the app is in demo mode
- Prompts user to add BATCHDATA_API_KEY to secrets
- Explains what each tool would return---Create this application with a clean, modern UI. Focus on making the tool responses easy to read while also providing access to the raw JSON data.
Customizing Your Demo
Once you have the basic app running, consider these enhancements:
Add More Example Queries
Edit the "Try These" section in the sidebar to include queries relevant to your use case.
Customize the UI
The app uses TailwindCSS and Shadcn/UI components. Modify colors, layouts, and branding in: - client/src/index.css - Global styles - client/src/pages/home.tsx - Main layout
Extend Tool Support
To support additional BatchData MCP tools: 1. Add the query pattern in server/routes.ts 2. Create a formatter in client/src/components/ResponseCard.tsx
Troubleshooting
"Connection failed" error - Verify BATCHDATA_API_KEY is set in Replit Secrets - Check that your API key is valid at batchdata.com
"Tool not found" error - The app discovers tools dynamically on connection - Try disconnecting and reconnecting
WebSocket disconnects - The app auto-reconnects after 3 seconds - Check the System Logs panel for error details
Comparables showing "0 found" - Ensure the app uses comparable_property_preview (not the deprecated comparable_property)
App crashes when displaying skip trace results - Owner names in skip trace responses can be objects ({first, last, full}) instead of plain strings - Use the getDisplayName() helper function to safely handle both formats
Deployment crash loops with MODULE_NOT_FOUND - This happens when dependencies are marked as "external" in esbuild but not available at runtime - Fix: In script/build.ts, ensure esbuild does NOT externalize @ai-sdk/mcp or @modelcontextprotocol/sdk - All dependencies should be bundled into dist/index.cjs
Best Practices for AI-Assisted Development
Based on our experience building this demo, here are key takeaways:
Start with clear requirements - Define what you want before engaging the AI
Use a reference example - Concrete examples (like our Phoenix address) help the AI understand expected behavior
Specify output formats - We explicitly requested both JSON and human-readable formats
Document API structures - Include actual response formats to ensure correct parsing
Iterate incrementally - Test each feature before moving to the next
Keep prompts structured - Use headings, lists, and code blocks for clarity
Next Steps
Now that you have a working demo app, explore these resources:
Support
For technical support, questions, or integration assistance:
Email: support@batchservice.com
Documentation: https://developer.batchdata.com
Knowledge Base: https://help.batchdata.io
When contacting support, please include: - BatchData Account name - Tool name and parameters used - Error messages or unexpected behavior
