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.1

Published

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

Readme

PostMessage MCP

基于 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

快速开始

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

主页面(Server)

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

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

  // 注册工具
  addTool({
    name: 'greet',
    description: '问候工具',
    inputSchema: {
      type: 'object',
      properties: {
        name: { type: 'string' },
      },
    },
    handler: async (input) => {
      return {
        content: [{ type: 'text', text: `Hello, ${input.name}!` }],
      };
    },
  });

  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 和窗口通信进行域名白名单控制。

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: '*' 配合空白名单
  3. 尽量使用精确匹配而非通配符
  4. 定期审查和更新白名单配置

开发

# 开发服务器
pnpm dev

# 构建应用
pnpm build

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

# 预览构建结果
pnpm preview

发布到 npm

# 构建库
pnpm build:lib

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

React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.

Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...

      // Remove tseslint.configs.recommended and replace with this
      tseslint.configs.recommendedTypeChecked,
      // Alternatively, use this for stricter rules
      tseslint.configs.strictTypeChecked,
      // Optionally, add this for stylistic rules
      tseslint.configs.stylisticTypeChecked,

      // Other configs...
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])

You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:

// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...
      // Enable lint rules for React
      reactX.configs['recommended-typescript'],
      // Enable lint rules for React DOM
      reactDom.configs.recommended,
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])