What you’ll build
This guide creates a local server with:- an MCP endpoint at
http://localhost:3000/mcp - an Inspector at
http://localhost:3000/mcp/inspector - a
show-apptool that returns a view - a
say-hellotool that the view calls - a React view at
views/my-view/view.tsx
Prerequisites
- Node.js 22.22.2 or higher
- Basic TypeScript and React knowledge
Create the project
Run the MCP Apps template and install its dependencies:--template, the scaffolder does not prompt, and it installs dependencies only with --install. If you omit --install, run npm install in the project before you start the server. The scaffolder also installs the mcp-apps-builder coding-agent skill, which requires Git. Pass --no-skills to skip it.
The template also creates README.md, .gitignore, and the installed coding-agent skills. These are the files you edit most often:
public/icon.svg is the server icon declared in index.ts. The view renders public/logo-mcp-use.svg with the Image component from mcp-use/react, which resolves root-relative paths against the public/ folder.
Run the server
Start the development server:Inspect the view tool
Openindex.ts and find the show-app tool. The template also configures server branding and registers a second tool, say-hello, without a view. This excerpt shows the view-bound path you need to understand first.
view.name must match the folder under views/. In this template, my-view maps to views/my-view/view.tsx.
A view-bound tool must declare an outputSchema. The structuredContent object becomes view rendering data via useToolContext(). The content array is the short text result the model can read.
view.csp allows the Google Fonts stylesheet that view.css imports. See Content Security Policy for the other domain categories.
The say-hello tool returns { greeting } in structuredContent and has no view. The view calls it with useCallTool().
Both tools are assigned to exported constants. The generated mcp-env.d.ts reads these exports to type useToolContext<"show-app">() and useCallTool("say-hello") in the view.
Inspect the React view
Openviews/my-view/view.tsx. The view reads the tool invocation with useToolContext() and wraps its content in ThemeProvider, which applies the host theme.
The generated view also shows host context, display-mode buttons, external links, a follow-up message button, and a set-counter tool that the host can call while the view is mounted. This condensed excerpt keeps the template’s data access and the Update State and Say Hello controls, without styling and decorative markup.
status is "pending", toolInput can hold partial arguments, so the heading reads appName from it. The starter view does not render the tool output. After you check status === "ready", view.toolOutput.message holds the message from structuredContent.
ModelContext describes the current counter to the model. See Model context for the available channels.
Verify in the Inspector
Use the Inspector to confirm that the server and view work.- Open
http://localhost:3000/mcp/inspector. - Go to the Tools tab.
- Select
show-app. - Run the tool with
{ "appName": "My App" }. WithoutappName, the result message containsundefined. - Confirm that the view renders below the tool result and its heading shows “My App”. The handler waits 1.5 seconds, so the view can show a loading skeleton first.
- Select Say Hello in the view. Confirm that it shows
Tool Response: Hello, mcp-use!.
view.name exactly matches the folder under views/ and that the handler returns structuredContent.
Next steps
- Use
useToolContext()to read tool input, output, and lifecycle status. - Use
useCallTool()when a view needs to call another MCP tool. See Interactivity for follow-up messages, external links, display modes, and view tools. - Configure Content Security Policy before loading external APIs, images, scripts, embeds, or static assets.