v0.138 components·React · Angular · Vue·MCP-native

38 copy-paste components.Multi-framework. MCP-native.

38 copy-paste components. Multi-framework. MCP-native. 7 MCP primitives nobody else ships — tool-call cards, OAuth consent, scope inspector and more — plus 24 base UI primitives to build on. React, Angular, Vue.

TerminalBash
IncludesForm·Display·Overlay·Navigation·AI·MCP
Servergithub-mcp
Connecting
unknown
idle

In production

What an MCP app looks like when you stop reinventing it.

Every visible pixel below is a real @mcp-elements/react component. No screenshots, no Figma.

studio
mcp-studio.app/workspace
Youjust now
Find recent TypeScript files changed this week.
Ask anything about your codebase…
McpServerStatusTop right
McpResourceBrowserLeft rail
McpToolCallConversation
McpScopeInspectorRight rail

Before / after

Less code. Same product.

The tool-call card alone is a week of work — state machine, accessibility, theme tokens, retry logic, six render states. You can hand-roll it, or you can drop in a component.

Without mcp-elementstsx
47 lines · still incomplete
// Build a tool-call card from scratch
import { useState, useEffect } from 'react'
import { ToolStateApi } from '@modelcontextprotocol/sdk'

type Status = 'idle' | 'pending' | 'running' | 'done' | 'error'

export function ToolCallCard({ tool, args, onRetry }: Props) {
  const [status, setStatus] = useState<Status>('idle')
  const [result, setResult] = useState<ToolResult>()
  const [error, setError] = useState<Error>()
  const [progress, setProgress] = useState(0)

  // …subscribe to the SDK, validate transitions, handle race
  // conditions, render 6 states, manage retry, accessibility,
  // theme tokens, keyboard nav, focus rings, ARIA live regions…

  return (
    <div role="region" aria-live="polite" className="…">
      <header>
        <span>{tool}</span>
        <StatusBadge status={status} />
      </header>
      {args && <ArgsBlock args={args} />}
      {status === 'running' && <Progress value={progress} />}
      {status === 'done' && <ResultBlock result={result} />}
      {status === 'error' && (
        <ErrorBlock error={error} onRetry={onRetry} />
      )}
    </div>
  )
}

// 47 lines later… and you still haven't shipped consent or scopes.
With mcp-elementstsx
7 lines · ready
// One component. Same flow.
import { McpToolCall } from '@mcp-elements/react'
import { createToolState } from '@mcp-elements/core'

const state = createToolState()
state.start({
  tool: 'search_files',
  args: { path: '/src' },
})

<McpToolCall state={state} onRetry={() => state.reset()} />
88%less code per component
7MCP components shipped, not rebuilt
0runtime dependencies — you own the source

New to MCP?

The 30-second explainer.

MCP is the protocol behind Claude, Cursor, Windsurf, and 9,400+ open-source servers. We give you the UI for the parts your users actually see.

Read the MCP spec

A protocol, not a framework

MCP is an open standard for connecting AI apps to tools, files, and services. Think USB-C for AI agents.

Servers expose, clients consume

Any app can run an MCP server (GitHub, Linear, your DB). Any AI client can plug in — Claude, Cursor, Windsurf, custom.

Built-in consent + scopes

MCP includes OAuth 2.1 with PKCE, scope grants, and a postMessage spec for sandboxed UI. mcp-elements gives you the UI pieces.

97M+monthly MCP downloads
9,652+open-source servers
3frameworks at launch
MITlicensed
0runtime dependencies

How it works

Three steps. No runtime. You own the code.

01

Pick a component

Browse 38 components across 7 categories — base UI, AI primitives, and the 7 MCP-specific ones.

browse

/components/mcp-tool-call
02

Copy it in

One command drops the source into your project. No runtime dep, no version lock-in. You own the file.

install

npx @mcp-elements/cli add mcp-tool-call
03

Wire it to state

Each component subscribes to a framework-free state machine from @mcp-elements/core. React, Angular, or Vue.

use

createToolState() → <McpToolCall state={…} />

One API · Three frameworks

Your framework. Same components.

React, Angular, and Vue — all supported at launch. Same state machine, same props, same accessibility behaviour.

app.tsxTSX
import { McpToolCall } from '@mcp-elements/react'
import { createToolState } from '@mcp-elements/core'

const state = createToolState()

export function App() {
  return (
    <McpToolCall
      toolName="search_files"
      args={{ path: '/src', pattern: '*.ts' }}
      state={state}
      onRetry={() => state.reset()}
    />
  )
}

Step 1 of 1

Own your code.

Run one command. The CLI copies source files into your project. No npm dependency for components — just code you control.

TerminalBash
css/components/mcp-tool-call.css
react/mcp/mcp-tool-call.tsx
core/mcp/tool-state.ts