Skip to main content
We’re going to create a simple Reservation MCP App for a restaurant called Jammy Wammy!

Setting up your environment

Initialize the project

Install dependencies

Configure package.json

Add the following to your package.json:

Create tsconfig.json

Create vite.config.ts

Creating your first View

Now let’s create the HTML file and React component that will be displayed when the MCP tool is called.

Create reservation-app.html

First, create the HTML file that will serve as the entry point for your app:
This is a standard HTML file with a few important elements:
  • A root div where React will mount your app
  • A module script that imports your React component
  • Color scheme meta tag for light/dark mode support

Create src/reservation.tsx

Understanding the MCP App features

The useApp hook

The useApp hook is the foundation of your MCP App. It establishes the connection between your UI and the MCP host.
  • appInfo: Identifies your app with a name and version
  • capabilities: Declares what features your app supports (empty for this simple example)
  • app: The app instance you’ll use to interact with the MCP host
  • error: Contains any connection errors

Sending messages with app.sendMessage()

The sendMessage method lets your app send follow-up messages to the LLM, enabling interactive conversations:
This is powerful because it allows your UI to trigger additional LLM interactions. When the user clicks “What’s on the menu?”, the message is sent back to the LLM, which can then call another MCP tool (like get-menu) to respond.

What else can your app do?

The app object provides several methods to interact with the MCP host:
  • app.sendMessage() - Send messages to the LLM (as shown above)
  • app.callServerTool() - Call other MCP tools on your server directly
  • app.sendLog() - Send log messages to the host for debugging
  • app.openLink() - Request the host to open a URL (only http and https URLs are allowed; other schemes resolve { isError: true })
  • app.getHostContext() - Get information about the host environment (safe area insets, theme, etc.)
For a complete reference of all available methods and capabilities, see the MCP Apps API documentation.

Mounting the React app

Don’t forget to mount your app to the DOM:

Setting up the MCP Server

Now let’s create the server that will register your tools and serve the UI.

Create server.ts

Understanding the server components

Creating the MCP Server

This initializes your MCP server with a name and version.

Registering the App Resource

registerAppResource allows us to easily register a resource with UI metadata so the host knows where the assets are to serve it to the host.

Registering an App Tool (with UI)

This is the tool that will be directly called by the LLM to render your tool. We give it our resourceUri in the _meta field allowing us to have multiple tools to render different UI. We can also return text content to the LLM as well to give it more context about our View.

Registering a Regular Tool (without UI)

Regular tools work just like standard MCP tools - they return text content without any UI.

Starting the Server

This connects your server to STDIO transport, allowing it to communicate with MCP clients.

Building and Running Your App

Now that everything is set up, let’s build and run your MCP App!

Build the app

The build process uses Vite to bundle your React component and the HTML file into a single, self-contained HTML file:
This will create a dist/reservation-app.html file with all your JavaScript and CSS inlined - perfect for serving through MCP.

Run the server

Start your MCP server:
Your server is now running and communicating via STDIO. It’s ready to be connected to an MCP client like MCPJam Inspector!

Testing with MCPJam Inspector

The easiest way to test your app is using MCPJam Inspector:
On first launch MCPJam auto-connects a sample Excalidraw server — open the Servers tab and add your own. Then head to the Playground to render widgets, debug CSP/device behavior, and drive your app with an LLM — test it all in one place!

What’s next?

Now that your server is running, you can:
  1. Test the flow - Call the get-reservation tool to see your UI
  2. Try the menu button - Click “What’s on the menu?” and watch the LLM call the get-menu tool
  3. Iterate and expand - Add more tools, improve the UI, or build something completely new!
Congratulations! You’ve built your first MCP App! 🎉