How to Build Your First MCP App: A Step-by-Step Tutorial
How to Build Your First MCP App: A Step-by-Step Tutorial
Published: February 16, 2026
Reading time: 12 minutes
Tags: #MCP #Tutorial #React #AI-Apps #Claude #ChatGPT
Introduction
Want to build interactive UI components that render directly inside Claude, ChatGPT, and VS Code? MCP Apps make it possible.
MCP (Model Context Protocol) Apps are self-contained, interactive components that AI assistants can render natively. Instead of describing a chart or dashboard with text, you can build a real React component that users interact with inside their AI chat.
In this tutorial, you'll build your first MCP App from scratch—a simple counter component that demonstrates the core concepts. By the end, you'll know how to:
- Set up an MCP App project
- Connect it to Claude Desktop
- Handle user interactions
- Deploy for others to use
Let's get started.
What You'll Build
A live counter app that Claude can render and control:
- Displays a counter value
- Has + and - buttons to adjust it
- Shows a reset button
- Updates in real-time as you interact
Simple? Yes. But this foundation scales to complex dashboards, data visualizations, and interactive tools.
Prerequisites
Before starting, ensure you have:
- Node.js 18+ installed (
node --version) - Claude Desktop (free version works)
- Basic knowledge of React and TypeScript
- A code editor (VS Code recommended)
Step 1: Initialize Your MCP App
The fastest way to start is with the official starter template.
# Clone the official React starter
npx degit github:modelcontextprotocol/ext-apps/basic-react my-counter-app
cd my-counter-app
# Install dependencies
npm install
This gives you a pre-configured project with:
- React + TypeScript setup
- MCP protocol handlers
- Development server with hot reload
- Production build scripts
Project Structure
my-counter-app/
├── src/
│ ├── App.tsx # Your main component
│ ├── main.tsx # Entry point
│ └── mcp-client.ts # MCP protocol client
├── public/
├── index.html
├── vite.config.ts # Vite dev server
└── package.json
Key file: src/App.tsx — this is where your UI lives.
Step 2: Build the Counter Component
Open src/App.tsx and replace the contents:
import { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md">
<h2 className="text-xl font-bold text-gray-800 mb-4">
Live Counter
</h2>
<div className="text-center mb-6">
<span className="text-5xl font-bold text-blue-600">
{count}
</span>
</div>
<div className="flex gap-2 justify-center">
<button
onClick={() => setCount(c => c - 1)}
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg font-semibold"
>
−
</button>
<button
onClick={() => setCount(0)}
className="px-4 py-2 bg-red-100 hover:bg-red-200 text-red-700 rounded-lg font-semibold"
>
Reset
</button>
<button
onClick={() => setCount(c => c + 1)}
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg font-semibold"
>
+
</button>
</div>
</div>
);
}
export default App;
What this does:
- Creates a centered card with a counter display
- Three buttons: decrement, reset, increment
- Uses React state for real-time updates
- Styled with Tailwind CSS classes
Step 3: Test Locally
Start the development server:
npm run dev
Your app runs at http://localhost:5173. Open it in your browser to verify the counter works.
But here's the magic: MCP Apps aren't just web pages. They're designed to render inside AI assistants.
Step 4: Connect to Claude Desktop
This is where MCP Apps shine. Let's wire your app to Claude.
4.1: Install the MCP CLI
npm install -g @anthropic-ai/mcp-cli
4.2: Register Your App
Create an mcp.json config file in your project root:
{
"name": "counter-app",
"version": "1.0.0",
"entrypoint": "http://localhost:5173",
"description": "A simple interactive counter",
"permissions": ["render"]
}
4.3: Add to Claude Desktop
Open Claude Desktop settings (Cmd/Ctrl + ,) and add your MCP server:
{
"mcpServers": {
"counter-app": {
"command": "npx",
"args": ["mcp-cli", "serve", "/path/to/my-counter-app/mcp.json"]
}
}
}
Restart Claude Desktop.
Step 5: Use Your App in Claude
Open a conversation in Claude Desktop and type:
"Show me the counter app"
Claude will recognize the request and render your app directly in the chat:
![Counter app rendering inside Claude chat interface]
Try it:
- Click the + and − buttons
- Watch the counter update live
- Ask Claude: "Set the counter to 42"
- Claude can call functions in your app to control it programmatically
Step 6: Add Two-Way Communication
Static apps are nice. Interactive apps are powerful. Let's add a function Claude can call.
Update src/App.tsx:
import { useState, useEffect } from 'react';
// Expose functions to MCP
declare global {
interface Window {
mcp?: {
registerFunction: (name: string, fn: Function) => void;
};
}
}
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
// Register function for Claude to call
if (window.mcp) {
window.mcp.registerFunction('setCounter', (value: number) => {
setCount(value);
return { success: true, newValue: value };
});
}
}, []);
return (
<div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md">
<h2 className="text-xl font-bold text-gray-800 mb-2">
Live Counter
</h2>
<p className="text-sm text-gray-600 mb-4">
Try saying: "Set counter to 100"
</p>
<div className="text-center mb-6">
<span className="text-5xl font-bold text-blue-600">
{count}
</span>
</div>
<div className="flex gap-2 justify-center">
<button
onClick={() => setCount(c => c - 1)}
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg font-semibold"
>
−
</button>
<button
onClick={() => setCount(0)}
className="px-4 py-2 bg-red-100 hover:bg-red-200 text-red-700 rounded-lg font-semibold"
>
Reset
</button>
<button
onClick={() => setCount(c => c + 1)}
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg font-semibold"
>
+
</button>
</div>
</div>
);
}
export default App;
Now Claude can:
- Render the app visually
- Call
setCounter(100)to set the value - Read the current state
- Combine app control with its reasoning
Step 7: Build for Production
Ready to share your app? Build the production bundle:
npm run build
This creates a dist/ folder with optimized assets.
Deployment Options
| Option | Best For | Complexity |
|---|---|---|
| Vercel | Quick sharing, automatic deploys | Low |
| Netlify | Generous free tier, simple config | Low |
| GitHub Pages | Open source projects | Low |
| Self-hosted | Enterprise, custom domains | Medium |
Deploy to Vercel (easiest):
npm i -g vercel
vercel --prod
Update your mcp.json with the production URL:
{
"name": "counter-app",
"version": "1.0.0",
"entrypoint": "https://my-counter-app.vercel.app",
"description": "A simple interactive counter",
"permissions": ["render"]
}
Common Issues & Solutions
| Problem | Cause | Solution |
|---|---|---|
| App doesn't render in Claude | MCP server not running | Check npx mcp-cli serve is active |
| CORS errors | Missing headers | Add cors: true to vite.config.ts |
| Functions not recognized | Window.mcp not available | Wait for DOM load, check registration |
| Styling looks wrong | CSS not loaded | Ensure Tailwind classes are correct |
| Hot reload not working | Vite config issue | Restart dev server, check port 5173 |
Next Steps: What to Build
Your counter app proves the concept. Now scale it:
Data Visualization
- Build charts with Recharts or D3
- Create interactive dashboards
- Display real-time metrics
Productivity Tools
- Form builders with validation
- Note-taking interfaces
- Task managers
Creative Apps
- Image editors with filters
- Music players
- Drawing canvases
Developer Tools
- API testers
- Database browsers
- Log viewers
Browse mcp-apps.co for inspiration—see how others have built cohort heatmaps, 3D renderers, PDF viewers, and more.
Conclusion
You now know how to build, test, and deploy MCP Apps. The counter app you created is small, but the pattern scales to complex, production-ready tools.
Key takeaways:
- MCP Apps are React components that render in AI assistants
- Two-way communication lets AI control your UI
- The development loop is fast: code → test in Claude → iterate
- Deployment is standard web hosting
Ready to build something bigger?
Check out our MCP Apps Directory for 28+ open-source examples you can study, fork, and extend. From data visualization to 3D renderers, there's a starting point for every use case.
Have questions? Join the MCP Community Discord or browse the official documentation.
Resources
- MCP Apps Directory — Curated collection of MCP Apps
- Official Examples — 21 starter templates
- Model Context Protocol Docs — Protocol specification
- Claude Desktop — Free MCP client
Want this tutorial as a video? Let us know on Twitter/X.
The team behind MCP Apps, curating the best interactive components for AI assistants.
Subscribe to our newsletter
Get the latest tutorials, showcases, and MCP Apps updates delivered to your inbox.