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

postmessage-mcp

v0.0.5

Published

基于 PostMessage 的 MCP (Model Context Protocol) 通信库,支持主页面与 iframe 之间的双向通信

Readme

PostMessage MCP

English

基于 PostMessage 的 Model Context Protocol (MCP) 实现,支持 iframe 和窗口之间的双向通信。

特性

  • 🤝 内置握手机制,杜绝连接时序问题
  • 🔒 支持域名白名单控制,确保通信安全
  • 🚀 基于 PostMessage API,跨域通信更安全
  • 🎯 完整支持 MCP 协议(Tools、Resources、Prompts)
  • ⚛️ React Hooks 封装,易于集成
  • 📦 TypeScript 支持,类型安全
  • 🔄 支持双向模式:主页面/iframe 都可以作为 Server 或 Client

安装

作为 npm 包使用

npm install postmessage-mcp
# 或
pnpm add postmessage-mcp
# 或
yarn add postmessage-mcp

开发环境安装

pnpm install

快速开始

⚠️ 注意:以下示例为简化演示,未配置 allowedOriginstargetOrigin,默认允许所有来源。生产环境中请务必参考域名白名单功能进行配置。

基本用法(主页面作为 Server,iframe 作为 Client)

主页面(Server)

import { useMcpServer } from 'postmessage-mcp';
import { useRef, useEffect } from 'react';

function App() {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  
  const { addTool, isConnected } = useMcpServer({
    name: 'my-server',
    version: '1.0.0',
    iframeRef,
    autoConnect: true,
  });

  // 注册工具(在 useEffect 中注册,避免渲染期间副作用)
  useEffect(() => {
    addTool({
      name: 'greet',
      description: '问候工具',
      inputSchema: {
        type: 'object',
        properties: {
          name: { type: 'string' },
        },
      },
      handler: async (input) => {
        return {
          content: [{ type: 'text', text: `Hello, ${input.name}!` }],
        };
      },
    });
  }, [addTool]);

  return (
    <div>
      <div>状态: {isConnected ? '已连接' : '未连接'}</div>
      <iframe ref={iframeRef} src="/client.html" />
    </div>
  );
}

iframe 页面(Client)

import { useMcpClient } from 'postmessage-mcp';

function ClientApp() {
  const { tools, callTool, isConnected } = useMcpClient({
    name: 'my-client',
    version: '1.0.0',
    autoConnect: true,
  });

  const handleGreet = async () => {
    const result = await callTool('greet', { name: 'World' });
    console.log(result);
  };

  return (
    <div>
      <div>状态: {isConnected ? '已连接' : '未连接'}</div>
      <button onClick={handleGreet}>调用工具</button>
    </div>
  );
}

反向模式(iframe 作为 Server,主页面作为 Client)

iframe 页面(Server)

import { useMcpServer } from 'postmessage-mcp';

function IframeServer() {
  const { addTool } = useMcpServer({
    name: 'iframe-server',
    version: '1.0.0',
    asIframe: true, // 关键:设置为 true 表示 Server 在 iframe 中运行
    autoConnect: true,
  });

  // 注册工具...
}

主页面(Client)

import { useMcpClient } from 'postmessage-mcp';
import { useRef } from 'react';

function ParentClient() {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  
  const { callTool } = useMcpClient({
    name: 'parent-client',
    version: '1.0.0',
    iframeRef, // 指定 iframe,Client 将与其中的 Server 通信
    autoConnect: true,
  });

  // 使用工具...
}

握手机制

为避免连接时序问题(iframe 中的 Client 先于父页面的 Server 发送消息导致消息丢失),传输层内置了 Ready 握手机制:

  1. Transport 在构造时即通过 addEventListener('message') 启动监听,不依赖 start() 调用时机
  2. Client 调用 connect() 时发送 __mcp_ready__ 信号
  3. Server 收到 ready 后通过 event.source 回复 __mcp_ready_ack__
  4. Client 收到 ack 后才发送 MCP initialize,开始正式通信

握手由传输层内部处理,对上层 MCP 协议透明,无需使用者额外配置。

域名白名单功能

⚠️ 安全警告:默认情况下,如果不配置 allowedOriginstargetOrigin,通信链路对任意 origin 完全开放,任何页面都可以通过 postMessage 与你的 MCP Server/Client 通信。在生产环境中务必配置白名单,否则可能导致工具调用、资源读取等 MCP 能力被恶意页面利用。

为了增强安全性,本项目支持对 iframe 和窗口通信进行域名白名单控制。

Server 端配置

import { useMcpServer } from 'postmessage-mcp';

const { server, connect } = useMcpServer({
  iframeRef: iframeRef,
  targetOrigin: 'https://example.com',
  // 配置允许的域名白名单
  allowedOrigins: [
    'https://example.com',           // 精确匹配
    'https://*.example.com',         // 支持协议的通配符
    '*.trusted-domain.com',          // 通配符匹配
  ],
  autoConnect: true,
});

Client 端配置

import { useMcpClient } from 'postmessage-mcp';

const { client, connect } = useMcpClient({
  // 配置允许的域名白名单
  allowedOrigins: [
    'https://parent-domain.com',
    '*.trusted-domain.com',
  ],
  autoConnect: true,
});

白名单规则说明

  • 精确匹配https://example.com - 只允许完全匹配的域名
  • 域名通配符*.example.com - 允许所有 example.com 的子域名
  • 带协议通配符https://*.example.com - 只允许 https 协议的 example.com 子域名
  • 不配置白名单:默认允许所有域名(不推荐在生产环境使用)

安全建议

  1. 在生产环境中必须配置 allowedOrigins,不配置意味着任意页面均可通信
  2. 同时设置 targetOrigin 为非 '*' 的具体 origin,避免消息被任意页面接收
  3. Server 和 Client 两端都应当配置 allowedOrigins,形成双向校验
  4. 尽量使用精确匹配而非通配符
  5. 定期审查和更新白名单配置
  6. 避免在 file:// 协议或 sandbox iframe 下使用默认配置(origin 为 "null" 时会退化为 "*"

开发

# 开发服务器
pnpm dev

# 构建应用
pnpm build

# 构建库(用于发布)
pnpm build:lib

# 预览构建结果
pnpm preview

发布到 npm

# 构建库
pnpm build:lib

# 发布(需要先登录 npm)
npm publish

API 概览

核心类

  • McpServer — MCP Server 实现,注册 tools/resources/prompts 并响应 Client 请求
  • McpClient — MCP Client 实现,发现并调用 Server 暴露的能力
  • PostMessageServerTransport — 基于 postMessage 的 Server 端传输层
  • PostMessageClientTransport — 基于 postMessage 的 Client 端传输层

React Hooks

  • useMcpServer — React Hook,封装 McpServer 的创建、连接与能力注册
  • useMcpClient — React Hook,封装 McpClient 的创建、连接与能力发现

支持的 MCP 方法

| 方法 | 说明 | |---|---| | initialize | 能力握手 | | notifications/initialized | 确认初始化完成 | | tools/list | 发现可用工具 | | tools/call | 调用工具 | | resources/list | 发现可用资源 | | resources/read | 读取资源 | | prompts/list | 发现可用提示词 | | prompts/get | 获取提示词 | | ping | 心跳检测 |

架构

React Hooks(useMcpServer / useMcpClient)
        │  状态管理、自动连接、自动发现
        │
协议层(McpServer / McpClient)
        │  JSON-RPC 2.0、MCP 方法路由、30s 超时
        │
传输层(PostMessageServerTransport / PostMessageClientTransport)
        │  构造时启动监听、Ready 握手、origin 白名单校验
        │
浏览器 API(window.postMessage)

详细架构图与通信流程见 SPEC.md

License

MIT