> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-b-sync-npm-packages-docs-bf03420.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Live WebMCP Prompt Examples

> Interactive examples of WebMCP prompts that AI agents can retrieve in real-time. Working demonstrations of greeting and code review prompts.

export const PolyfillSetup = () => {
  const {useState, useEffect} = React;
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const checkPolyfill = () => {
      if (window.navigator?.modelContext) {
        setIsLoaded(true);
      }
    };
    checkPolyfill();
    window.addEventListener('load', checkPolyfill);
    window.addEventListener('webmcp-loaded', checkPolyfill);
    return () => {
      window.removeEventListener('load', checkPolyfill);
      window.removeEventListener('webmcp-loaded', checkPolyfill);
    };
  }, []);
  const copyScript = () => {
    const scriptTag = '<script src="https://unpkg.com/@mcp-b/global@latest/dist/index.iife.js"></script>';
    navigator.clipboard.writeText(scriptTag);
  };
  return <div className="not-prose border dark:border-white/10 rounded-xl p-6 space-y-4">
      <h3 className="text-lg font-semibold text-zinc-950 dark:text-white mb-4">
        WebMCP Polyfill Status
      </h3>

      <div className="space-y-3">
        <div className="flex items-center justify-between p-4 rounded-lg bg-zinc-50 dark:bg-zinc-900">
          <div className="flex items-center gap-3">
            <div className={`w-3 h-3 rounded-full ${isLoaded ? 'bg-green-500' : 'bg-zinc-400'}`} />
            <div>
              <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">
                navigator.modelContext API
              </p>
              <p className="text-xs text-zinc-600 dark:text-zinc-400">
                {isLoaded ? 'Loaded and ready' : 'Not detected'}
              </p>
            </div>
          </div>
          {isLoaded && <span className="text-xs px-2 py-1 rounded bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400">
              Active
            </span>}
        </div>
      </div>

      {!isLoaded && <div className="p-4 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800">
          <p className="text-sm font-semibold text-amber-900 dark:text-amber-200 mb-2">
            Polyfill Not Detected
          </p>
          <p className="text-sm text-amber-800 dark:text-amber-300 mb-3">
            Add the WebMCP polyfill to enable the API. Add this script tag to your HTML:
          </p>
          <div className="relative">
            <pre className="text-xs bg-white dark:bg-zinc-950 p-3 rounded border border-amber-300 dark:border-amber-700 overflow-x-auto">
              <code className="text-amber-900 dark:text-amber-100">
                {`<script src="https://unpkg.com/@mcp-b/global@latest/dist/index.iife.js"></script>`}
              </code>
            </pre>
            <button onClick={copyScript} className="absolute top-2 right-2 px-2 py-1 text-xs bg-amber-200 dark:bg-amber-800 hover:bg-amber-300 dark:hover:bg-amber-700 text-amber-900 dark:text-amber-100 rounded transition-colors">
              Copy
            </button>
          </div>
        </div>}

      <div className="p-4 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800">
        <p className="text-sm font-semibold text-blue-900 dark:text-blue-200 mb-2">
          Installation Options
        </p>
        <div className="space-y-2 text-sm text-blue-800 dark:text-blue-300">
          <div>
            <strong>Via CDN (Easiest):</strong>
            <pre className="text-xs mt-1 bg-white dark:bg-blue-950 p-2 rounded border border-blue-200 dark:border-blue-700 overflow-x-auto">
              <code>{`<script src="https://unpkg.com/@mcp-b/global@latest/dist/index.iife.js"></script>`}</code>
            </pre>
          </div>
          <div>
            <strong>Via NPM:</strong>
            <pre className="text-xs mt-1 bg-white dark:bg-blue-950 p-2 rounded border border-blue-200 dark:border-blue-700 overflow-x-auto">
              <code>{`npm install @mcp-b/global
import '@mcp-b/global';`}</code>
            </pre>
          </div>
        </div>
      </div>
    </div>;
};

export const CodeReviewPrompt = () => {
  const [isRegistered, setIsRegistered] = useState(false);
  const [promptCalls, setPromptCalls] = useState([]);
  const [executionPhase, setExecutionPhase] = useState(null);
  const [lastMessages, setLastMessages] = useState(null);
  const [lastArgs, setLastArgs] = useState(null);
  const containerRef = useRef(null);
  const showPageEffect = (color = '#8B5CF6') => {
    const overlay = document.createElement('div');
    overlay.id = 'webmcp-code-review-effect';
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      background: ${color};
      opacity: 0;
      pointer-events: none;
      z-index: 9999;
      transition: opacity 0.3s ease;
    `;
    document.body.appendChild(overlay);
    requestAnimationFrame(() => {
      overlay.style.opacity = '0.08';
    });
    return overlay;
  };
  const hidePageEffect = () => {
    const overlay = document.getElementById('webmcp-code-review-effect');
    if (overlay) {
      overlay.style.opacity = '0';
      setTimeout(() => overlay.remove(), 300);
    }
  };
  const startExecution = async onExecute => {
    setExecutionPhase('executing');
    showPageEffect('#8B5CF6');
    if (containerRef.current) {
      containerRef.current.scrollIntoView({
        behavior: 'smooth',
        block: 'center'
      });
    }
    await new Promise(resolve => setTimeout(resolve, 1000));
    const result = await onExecute();
    setExecutionPhase('complete');
    hidePageEffect();
    await new Promise(resolve => setTimeout(resolve, 2000));
    setExecutionPhase(null);
    return result;
  };
  useEffect(() => {
    const registerPrompt = async () => {
      if (typeof window === 'undefined' || !window.navigator?.modelContext) {
        return;
      }
      try {
        await window.navigator.modelContext.registerPrompt({
          name: 'code-review',
          description: 'Generate a code review request with syntax-highlighted code block',
          argsSchema: {
            type: 'object',
            properties: {
              code: {
                type: 'string',
                description: 'The code to review'
              },
              language: {
                type: 'string',
                description: 'Programming language (e.g., javascript, python, typescript)',
                default: 'javascript'
              }
            },
            required: ['code']
          },
          async get(args) {
            return startExecution(async () => {
              const codeToReview = args.code;
              const lang = args.language || 'unknown';
              const messages = [{
                role: 'user',
                content: {
                  type: 'text',
                  text: `Please review this ${lang} code for best practices:\n\n\`\`\`${lang}\n${codeToReview}\n\`\`\``
                }
              }];
              setLastMessages(messages);
              setLastArgs({
                code: codeToReview,
                language: lang
              });
              setPromptCalls(prev => [...prev, {
                time: new Date().toISOString(),
                name: 'code-review',
                args: {
                  code: codeToReview.substring(0, 50) + (codeToReview.length > 50 ? '...' : ''),
                  language: lang
                },
                status: 'success',
                messages
              }]);
              return {
                messages
              };
            });
          }
        });
        setIsRegistered(true);
      } catch (error) {
        console.error('Failed to register code-review prompt:', error);
      }
    };
    registerPrompt();
    window.addEventListener('webmcp-loaded', registerPrompt);
    return () => {
      window.removeEventListener('webmcp-loaded', registerPrompt);
      if (window.navigator?.modelContext?.unregisterPrompt) {
        window.navigator.modelContext.unregisterPrompt('code-review');
      }
    };
  }, []);
  const isActive = executionPhase !== null;
  return <div ref={containerRef} className={`not-prose border rounded-xl p-6 space-y-4 transition-all duration-300 relative ${isActive ? 'border-[#8B5CF6] shadow-lg shadow-[#8B5CF6]/10 ring-2 ring-[#8B5CF6]/20' : 'border-zinc-200 dark:border-white/10'}`}>
      {isActive && <div className="absolute top-0 left-0 right-0 h-1 bg-zinc-100 dark:bg-zinc-800 rounded-t-xl overflow-hidden">
          <div className={`h-full bg-[#8B5CF6] transition-all duration-500 ${executionPhase === 'executing' ? 'w-2/3 animate-pulse' : 'w-full'}`} />
        </div>}

      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <h3 className="text-lg font-semibold text-zinc-950 dark:text-white">
            Code Review Prompt
          </h3>
          {isActive && <span className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-md bg-[#8B5CF6]/10 text-[#8B5CF6] dark:bg-[#8B5CF6]/20 dark:text-[#A78BFA]">
              {executionPhase === 'executing' && <>
                  <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
                  </svg>
                  Getting prompt...
                </>}
              {executionPhase === 'complete' && <>
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
                    <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                  </svg>
                  Complete
                </>}
            </span>}
        </div>
        {isRegistered && !isActive && <span className="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-md bg-violet-50 dark:bg-violet-900/20 text-violet-700 dark:text-violet-400 border border-violet-200 dark:border-violet-800">
            <span className="w-1.5 h-1.5 rounded-full bg-violet-500" />
            Ready
          </span>}
      </div>

      <div className="flex items-center gap-2 text-xs text-zinc-500 dark:text-zinc-400">
        <span className="px-2 py-0.5 rounded bg-zinc-100 dark:bg-zinc-800 font-mono">
          argsSchema
        </span>
        <span>Prompt with validated arguments</span>
      </div>

      {!isRegistered && !isActive && <div className="p-3 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800">
          <p className="text-sm text-amber-800 dark:text-amber-200">
            WebMCP not detected. Install the MCP-B extension to enable AI agent integration.
          </p>
        </div>}

      <div className="space-y-3">
        {}
        <div className="p-4 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 border border-zinc-200 dark:border-zinc-700">
          <p className="text-xs font-medium text-zinc-500 dark:text-zinc-400 mb-2 uppercase tracking-wide">
            Arguments Schema
          </p>
          <div className="space-y-2 text-sm">
            <div className="flex items-center gap-2">
              <code className="text-violet-600 dark:text-violet-400">code</code>
              <span className="text-zinc-500 dark:text-zinc-400">string</span>
              <span className="px-1.5 py-0.5 text-xs rounded bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400">
                required
              </span>
            </div>
            <div className="flex items-center gap-2">
              <code className="text-violet-600 dark:text-violet-400">language</code>
              <span className="text-zinc-500 dark:text-zinc-400">string</span>
              <span className="text-zinc-400 dark:text-zinc-500">default: "javascript"</span>
            </div>
          </div>
        </div>

        {}
        {lastMessages && lastArgs && (executionPhase === 'complete' || promptCalls.length > 0) && <div className="p-4 rounded-lg bg-[#8B5CF6]/5 dark:bg-[#8B5CF6]/10 border border-[#8B5CF6]/20">
            <div className="flex items-center justify-between mb-2">
              <p className="text-xs font-medium text-[#8B5CF6] dark:text-[#A78BFA] uppercase tracking-wide">
                Last Generated Message
              </p>
              <span className="text-xs text-zinc-500 dark:text-zinc-400">
                lang: {lastArgs.language}
              </span>
            </div>
            <pre className="text-xs text-zinc-900 dark:text-zinc-100 whitespace-pre-wrap bg-zinc-100 dark:bg-zinc-800 p-3 rounded-lg overflow-x-auto max-h-40">
              {lastMessages[0]?.content?.text || lastMessages[0]?.content}
            </pre>
          </div>}
      </div>

      {promptCalls.length > 0 && <div className="mt-6 pt-4 border-t border-zinc-200 dark:border-zinc-800">
          <h4 className="text-xs font-semibold text-zinc-500 dark:text-zinc-400 mb-3 uppercase tracking-wide">
            Recent Calls
          </h4>
          <div className="space-y-2 max-h-40 overflow-y-auto">
            {promptCalls.slice(-3).reverse().map((call, idx) => <div key={idx} className="p-3 rounded-lg text-sm bg-zinc-50 dark:bg-zinc-800/50 border border-zinc-200 dark:border-zinc-700">
                  <div className="flex items-center justify-between">
                    <code className="text-zinc-700 dark:text-zinc-300 font-mono text-sm">
                      getPrompt("{call.name}", {'{'}lang: "{call.args?.language}"{'}'})
                    </code>
                    <svg className="w-3.5 h-3.5 text-emerald-600 dark:text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
                      <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                    </svg>
                  </div>
                </div>)}
          </div>
        </div>}
    </div>;
};

export const GreetingPrompt = () => {
  const [isRegistered, setIsRegistered] = useState(false);
  const [promptCalls, setPromptCalls] = useState([]);
  const [executionPhase, setExecutionPhase] = useState(null);
  const [lastMessages, setLastMessages] = useState(null);
  const containerRef = useRef(null);
  const showPageEffect = (color = '#8B5CF6') => {
    const overlay = document.createElement('div');
    overlay.id = 'webmcp-prompt-effect';
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      background: ${color};
      opacity: 0;
      pointer-events: none;
      z-index: 9999;
      transition: opacity 0.3s ease;
    `;
    document.body.appendChild(overlay);
    requestAnimationFrame(() => {
      overlay.style.opacity = '0.08';
    });
    return overlay;
  };
  const hidePageEffect = () => {
    const overlay = document.getElementById('webmcp-prompt-effect');
    if (overlay) {
      overlay.style.opacity = '0';
      setTimeout(() => overlay.remove(), 300);
    }
  };
  const startExecution = async onExecute => {
    setExecutionPhase('executing');
    showPageEffect('#8B5CF6');
    if (containerRef.current) {
      containerRef.current.scrollIntoView({
        behavior: 'smooth',
        block: 'center'
      });
    }
    await new Promise(resolve => setTimeout(resolve, 1000));
    const result = await onExecute();
    setExecutionPhase('complete');
    hidePageEffect();
    await new Promise(resolve => setTimeout(resolve, 2000));
    setExecutionPhase(null);
    return result;
  };
  useEffect(() => {
    const registerPrompt = async () => {
      if (typeof window === 'undefined' || !window.navigator?.modelContext) {
        return;
      }
      try {
        await window.navigator.modelContext.registerPrompt({
          name: 'greeting',
          description: 'A friendly greeting prompt that welcomes users and offers assistance',
          async get() {
            return startExecution(async () => {
              const messages = [{
                role: 'user',
                content: {
                  type: 'text',
                  text: 'Hello! How can you help me today?'
                }
              }];
              setLastMessages(messages);
              setPromptCalls(prev => [...prev, {
                time: new Date().toISOString(),
                name: 'greeting',
                status: 'success',
                messages
              }]);
              return {
                messages
              };
            });
          }
        });
        setIsRegistered(true);
      } catch (error) {
        console.error('Failed to register greeting prompt:', error);
      }
    };
    registerPrompt();
    window.addEventListener('webmcp-loaded', registerPrompt);
    return () => {
      window.removeEventListener('webmcp-loaded', registerPrompt);
      if (window.navigator?.modelContext?.unregisterPrompt) {
        window.navigator.modelContext.unregisterPrompt('greeting');
      }
    };
  }, []);
  const isActive = executionPhase !== null;
  return <div ref={containerRef} className={`not-prose border rounded-xl p-6 space-y-4 transition-all duration-300 relative ${isActive ? 'border-[#8B5CF6] shadow-lg shadow-[#8B5CF6]/10 ring-2 ring-[#8B5CF6]/20' : 'border-zinc-200 dark:border-white/10'}`}>
      {isActive && <div className="absolute top-0 left-0 right-0 h-1 bg-zinc-100 dark:bg-zinc-800 rounded-t-xl overflow-hidden">
          <div className={`h-full bg-[#8B5CF6] transition-all duration-500 ${executionPhase === 'executing' ? 'w-2/3 animate-pulse' : 'w-full'}`} />
        </div>}

      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <h3 className="text-lg font-semibold text-zinc-950 dark:text-white">Greeting Prompt</h3>
          {isActive && <span className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-md bg-[#8B5CF6]/10 text-[#8B5CF6] dark:bg-[#8B5CF6]/20 dark:text-[#A78BFA]">
              {executionPhase === 'executing' && <>
                  <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
                  </svg>
                  Getting prompt...
                </>}
              {executionPhase === 'complete' && <>
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
                    <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                  </svg>
                  Complete
                </>}
            </span>}
        </div>
        {isRegistered && !isActive && <span className="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-md bg-violet-50 dark:bg-violet-900/20 text-violet-700 dark:text-violet-400 border border-violet-200 dark:border-violet-800">
            <span className="w-1.5 h-1.5 rounded-full bg-violet-500" />
            Ready
          </span>}
      </div>

      <div className="flex items-center gap-2 text-xs text-zinc-500 dark:text-zinc-400">
        <span className="px-2 py-0.5 rounded bg-zinc-100 dark:bg-zinc-800 font-mono">
          registerPrompt()
        </span>
        <span>Simple prompt without arguments</span>
      </div>

      {!isRegistered && !isActive && <div className="p-3 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800">
          <p className="text-sm text-amber-800 dark:text-amber-200">
            WebMCP not detected. Install the MCP-B extension to enable AI agent integration.
          </p>
        </div>}

      {}
      <div className="space-y-3">
        <div className="p-4 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 border border-zinc-200 dark:border-zinc-700">
          <p className="text-xs font-medium text-zinc-500 dark:text-zinc-400 mb-2 uppercase tracking-wide">
            Prompt Template
          </p>
          <div className="flex items-start gap-2">
            <span className="px-1.5 py-0.5 text-xs rounded bg-violet-100 dark:bg-violet-900/30 text-violet-600 dark:text-violet-400">
              user
            </span>
            <p className="text-sm text-zinc-700 dark:text-zinc-300">
              Hello! How can you help me today?
            </p>
          </div>
        </div>

        {}
        {lastMessages && (executionPhase === 'complete' || promptCalls.length > 0) && <div className="p-4 rounded-lg bg-[#8B5CF6]/5 dark:bg-[#8B5CF6]/10 border border-[#8B5CF6]/20">
            <p className="text-xs font-medium text-[#8B5CF6] dark:text-[#A78BFA] mb-2 uppercase tracking-wide">
              Last Retrieved
            </p>
            <div className="space-y-2">
              {lastMessages.map((msg, idx) => <div key={idx} className="flex items-start gap-2">
                  <span className="px-1.5 py-0.5 text-xs rounded bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300">
                    {msg.role}
                  </span>
                  <p className="text-sm text-zinc-900 dark:text-zinc-100">
                    {msg.content?.text || msg.content}
                  </p>
                </div>)}
            </div>
          </div>}
      </div>

      {promptCalls.length > 0 && <div className="mt-6 pt-4 border-t border-zinc-200 dark:border-zinc-800">
          <h4 className="text-xs font-semibold text-zinc-500 dark:text-zinc-400 mb-3 uppercase tracking-wide">
            Recent Calls
          </h4>
          <div className="space-y-2 max-h-40 overflow-y-auto">
            {promptCalls.slice(-3).reverse().map((call, idx) => <div key={idx} className="p-3 rounded-lg text-sm bg-zinc-50 dark:bg-zinc-800/50 border border-zinc-200 dark:border-zinc-700">
                  <div className="flex items-center justify-between">
                    <code className="text-zinc-700 dark:text-zinc-300 font-mono text-sm">
                      getPrompt("{call.name}")
                    </code>
                    <svg className="w-3.5 h-3.5 text-emerald-600 dark:text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
                      <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                    </svg>
                  </div>
                </div>)}
          </div>
        </div>}
    </div>;
};

This page demonstrates **live WebMCP prompts** that register themselves with the browser and can be retrieved by AI agents in real-time. Prompts are reusable message templates that help standardize AI interactions.

<Note>
  **These prompts are live and ready!** The WebMCP polyfill is included with this documentation site. Install the [MCP-B browser extension](https://chromewebstore.google.com/detail/mcp-b-extension/daohopfhkdelnpemnhlekblhnikhdhfa) to enable AI agents (like Claude) to discover and use these prompts directly.
</Note>

<CardGroup cols={3}>
  <Card title="Prompt Registration" icon="list-check" href="/concepts/prompts">
    Understanding prompt registration
  </Card>

  <Card title="Live Tools" icon="wand-magic-sparkles" href="/live-tool-examples">
    Interactive tool demonstrations
  </Card>

  <Card title="Live Resources" icon="database" href="/live-resource-examples">
    Interactive resource demonstrations
  </Card>
</CardGroup>

***

## WebMCP Status

Check if the WebMCP polyfill is loaded and ready:

<PolyfillSetup />

***

## What are Prompts?

Prompts in MCP are **reusable message templates** that AI agents can retrieve and use. Unlike tools (which execute actions) or resources (which read data), prompts generate structured messages that guide AI interactions.

| Feature       | Description                                   |
| ------------- | --------------------------------------------- |
| **Purpose**   | Generate pre-formatted messages for AI        |
| **Arguments** | Optional schema-validated parameters          |
| **Output**    | Array of role-based messages (user/assistant) |
| **Use Case**  | Standardized AI conversation starters         |

***

## Greeting Prompt

**Demonstrates:** Basic prompt registration without arguments

This prompt shows the fundamentals of `registerPrompt()` - a simple prompt that returns a greeting message. Perfect for initializing conversations with AI agents.

<GreetingPrompt />

<Tip>
  **Try it with your AI assistant:** Ask Claude to "use the greeting prompt" and watch it retrieve the pre-formatted message!
</Tip>

<CodeGroup>
  ```jsx "Greeting Prompt Implementation" theme={null}
  // Register a simple prompt without arguments
  navigator.modelContext.registerPrompt({
    name: 'greeting',
    description: 'A friendly greeting prompt that welcomes users',
    async get() {
      return {
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              text: 'Hello! How can you help me today?'
            },
          },
        ],
      };
    },
  });
  ```
</CodeGroup>

***

## Code Review Prompt

**Demonstrates:** Prompt with validated arguments schema

This prompt shows advanced usage with `argsSchema` - it accepts code and language parameters to generate a customized code review request. The schema validation ensures correct argument types.

<CodeReviewPrompt />

<Tip>
  **Try it with your AI assistant:** Ask Claude to "get the code-review prompt for my React component" and watch it generate a formatted review request!
</Tip>

<CodeGroup>
  ```jsx "Code Review Prompt Implementation" theme={null}
  // Register a prompt with arguments schema
  navigator.modelContext.registerPrompt({
    name: 'code-review',
    description: 'Generate a code review request with syntax-highlighted code',
    argsSchema: {
      type: 'object',
      properties: {
        code: {
          type: 'string',
          description: 'The code to review'
        },
        language: {
          type: 'string',
          description: 'Programming language',
          default: 'javascript'
        },
      },
      required: ['code'],
    },
    async get(args) {
      const code = args.code;
      const language = args.language || 'unknown';

      return {
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              text: `Please review this ${language} code:\n\n\`\`\`${language}\n${code}\n\`\`\``,
            },
          },
        ],
      };
    },
  });
  ```
</CodeGroup>

***

## Prompt API Reference

### `registerPrompt(descriptor)`

Registers a new prompt with the browser.

```typescript theme={null}
interface PromptDescriptor {
  name: string;                    // Unique prompt name
  description?: string;            // Human-readable description
  argsSchema?: InputSchema;        // Optional JSON Schema for arguments
  get: (args: object) => Promise<{ messages: PromptMessage[] }>;
}

interface PromptMessage {
  role: 'user' | 'assistant';
  content: { type: 'text'; text: string };
}
```

### `listPrompts()`

Returns all registered prompts (called by AI agents via MCP protocol).

```typescript theme={null}
const prompts = navigator.modelContext.listPrompts();
// [{ name: 'greeting', description: '...' }, ...]
```

<Note>
  The `getPrompt()` method is called by AI agents through the MCP protocol, not directly from your application code. When an AI agent calls `getPrompt('greeting')`, your registered `get()` handler is invoked and the result is returned to the agent.
</Note>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use descriptive names">
    Choose prompt names that clearly indicate their purpose. Use kebab-case for multi-word names (e.g., `code-review`, `bug-report`).
  </Accordion>

  <Accordion title="Provide helpful descriptions">
    Write descriptions that help AI agents understand when to use the prompt and what it generates.
  </Accordion>

  <Accordion title="Validate arguments with schemas">
    Use `argsSchema` to ensure AI agents provide the correct argument types. Include descriptions for each property.
  </Accordion>

  <Accordion title="Keep messages focused">
    Generate concise, focused messages. Avoid overly complex prompts that try to do too much.
  </Accordion>

  <Accordion title="Use appropriate roles">
    Use `user` role for requests and `assistant` role for context or examples the AI should follow.
  </Accordion>
</AccordionGroup>

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Concepts: Prompts" icon="lightbulb" href="/concepts/prompts">
    Deep dive into prompt architecture and patterns
  </Card>

  <Card title="Live Tool Examples" icon="wand-magic-sparkles" href="/live-tool-examples">
    Interactive tool demonstrations
  </Card>

  <Card title="Live Resource Examples" icon="database" href="/live-resource-examples">
    Interactive resource demonstrations
  </Card>

  <Card title="Best Practices" icon="star" href="/best-practices">
    Guidelines for effective WebMCP usage
  </Card>
</CardGroup>
