npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcp-web/app

v0.1.3

Published

Build tooling for MCP Apps - bundle React components into single HTML files for AI UI rendering

Readme

MCP Web App

Tooling for simplify creating MCP Apps from UI components. The packages bundles components into single HTML files that AI agents can render inline in chat interfaces like Claude Desktop.

[!IMPORTANT] We currently only support React. Support for more frameworks will be added in the future.

Overview

MCP Apps combine a tool (that AI can call) with a visual React component. When the AI calls the tool, the handler returns props which are passed to your component via the ext-apps protocol. A Vite plugin handles bundling each app into a self-contained HTML file.

Quick Start

Installation

npm install @mcp-web/app

1. Define an App

Create a file that exports your apps (e.g. src/mcp-apps.ts):

import { createApp } from '@mcp-web/app';
import { Statistics } from './components/Statistics';

export const statsApp = createApp({
  name: 'show_stats',
  description: 'Display statistics visualization',
  component: Statistics,
  handler: () => ({
    completionRate: 0.75,
    totalTasks: 100,
  }),
});

2. Add the Vite Build Config

Create a separate Vite config for building apps (e.g. vite.apps.config.ts):

import react from '@vitejs/plugin-react';
import { defineMCPAppsConfig } from '@mcp-web/app/vite';

export default defineMCPAppsConfig({
  plugins: [react()],
});

Build with:

vite build --config vite.apps.config.ts

This auto-discovers apps in src/mcp-apps.ts and outputs bundled HTML files to public/mcp-web-apps/.

3. Register with MCPWeb

In your web app, register the app so the AI agent can call it:

import { statsApp } from './mcp-apps';

mcp.addApp(statsApp);

Input Schemas

Apps can accept input from the AI agent using Zod schemas:

import { createApp } from '@mcp-web/app';
import { z } from 'zod';
import { Chart } from './components/Chart';

export const chartApp = createApp({
  name: 'show_chart',
  description: 'Display a chart with the given data',
  component: Chart,
  inputSchema: z.object({
    chartType: z.enum(['bar', 'line', 'pie']).describe('Type of chart'),
    title: z.string().describe('Chart title'),
  }),
  handler: ({ chartType, title }) => ({
    chartType,
    title,
    data: getChartData(),
  }),
});

Host Theming

MCP Apps automatically inherit the host's theme. Use these hooks to access it:

import { useMCPHostTheme, useMCPHostContext } from '@mcp-web/app';

function MyApp(props: MyProps) {
  const theme = useMCPHostTheme(); // "light" or "dark"
  const hostContext = useMCPHostContext(); // full context (theme, locale, display mode, etc.)

  return <div className={theme === 'dark' ? 'dark' : ''}>{/* ... */}</div>;
}

Receiving Props

Use the useMCPAppProps hook to receive props from the tool handler:

import { useMCPAppProps } from '@mcp-web/app';

function Statistics() {
  const props = useMCPAppProps<{ completionRate: number; totalTasks: number }>();

  if (!props) return <div>Loading...</div>;

  return (
    <div>
      <p>Completion: {Math.round(props.completionRate * 100)}%</p>
      <p>Total tasks: {props.totalTasks}</p>
    </div>
  );
}

Vite Plugin Options

defineMCPAppsConfig(
  { plugins: [react()] },
  {
    appsConfig: 'src/mcp-apps.ts',       // Path to apps config (auto-detected by default)
    outDir: 'public/mcp-web-apps',        // Output directory (default)
    silenceOverrideWarnings: false,        // Suppress build setting override warnings
  }
);

Exports

| Export | Description | |--------|-------------| | createApp | Define an app with a handler and component | | useMCPAppProps | React hook to receive props from the tool handler | | useMCPApp | Access the ext-apps App instance | | useMCPHostTheme | Get the current host theme ("light" or "dark") | | useMCPHostContext | Get the full host context | | renderMCPApp | Manually render a component (auto-generated by Vite plugin) | | MCPAppProvider | Context provider (set up automatically by renderMCPApp) | | defineMCPAppsConfig | Create a Vite config for building MCP Apps (via @mcp-web/app/vite) |

Learn More

For full documentation, guides, and examples, visit mcp-web.dev.