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

@jxee/sdk

v1.1.0

Published

Lightweight MCP SDK with inMemory transport - works on React Native, Web, and Node.js

Downloads

274

Readme

MCP TypeScript SDK (Lightweight)

NPM Version MIT licensed

🎯 轻量级 MCP SDK - 跨平台支持 使用 inMemory 传输方式,支持 React Native、Web 浏览器和 Node.js 环境,实现客户端和服务端在同一进程内高效通信。

✨ 特性

  • 跨平台兼容 - 支持 React Native、Web 浏览器、Node.js
  • 零网络开销 - Client 和 Server 在同一进程内通信
  • 类型安全 - 完整的 TypeScript 类型支持
  • 简单易用 - 开箱即用的 API
  • 轻量级 - 移除了 HTTP/stdio 等传输层,只保留核心功能
  • 高性能 - 内存直传,无序列化开销

📦 安装

# npm
npm install @jxee/sdk

# yarn
yarn add @jxee/sdk

# pnpm
pnpm add @jxee/sdk

🚀 快速开始

基础示例

import { McpServer, Client, InMemoryTransport } from '@jxee/sdk';
import { z } from 'zod';

// 1. 创建 MCP Server
const server = new McpServer({
  name: 'my-rn-server',
  version: '1.0.0'
});

// 2. 注册一个工具
server.registerTool(
  'calculate',
  {
    title: '计算器',
    description: '执行数学计算',
    inputSchema: {
      expression: z.string().describe('数学表达式,如 "2 + 3"')
    },
    outputSchema: {
      result: z.number()
    }
  },
  async ({ expression }) => {
    const result = eval(expression); // 实际应用中请使用安全的计算方法
    return {
      content: [{ type: 'text', text: `结果: ${result}` }],
      structuredContent: { result }
    };
  }
);

// 3. 创建配对的传输层
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();

// 4. 连接 Server
await server.connect(serverTransport);

// 5. 创建 Client 并连接
const client = new Client({
  name: 'my-rn-client',
  version: '1.0.0'
});

await client.connect(clientTransport);

// 6. 调用工具
const result = await client.callTool({
  name: 'calculate',
  arguments: { expression: '10 * 5' }
});

console.log(result.structuredContent); // { result: 50 }

📚 完整示例

1. 注册多个工具

// 天气查询工具
server.registerTool(
  'get-weather',
  {
    title: '获取天气',
    description: '查询指定城市的天气信息',
    inputSchema: {
      city: z.string().describe('城市名称')
    },
    outputSchema: {
      temperature: z.number(),
      condition: z.string()
    }
  },
  async ({ city }) => {
    // 模拟天气数据
    const weather = {
      temperature: 25,
      condition: '晴朗'
    };

    return {
      content: [
        {
          type: 'text',
          text: `${city}的天气:${weather.condition},温度${weather.temperature}°C`
        }
      ],
      structuredContent: weather
    };
  }
);

// 用户信息工具
server.registerTool(
  'get-user-info',
  {
    title: '获取用户信息',
    description: '根据用户ID获取用户信息',
    inputSchema: {
      userId: z.string()
    },
    outputSchema: {
      name: z.string(),
      email: z.string(),
      age: z.number()
    }
  },
  async ({ userId }) => {
    const user = {
      name: '张三',
      email: '[email protected]',
      age: 30
    };

    return {
      content: [
        { type: 'text', text: JSON.stringify(user, null, 2) }
      ],
      structuredContent: user
    };
  }
);

2. 注册资源

import { ResourceTemplate } from '@jxee/sdk';

// 静态资源
server.registerResource(
  'app-config',
  'config://app',
  {
    title: '应用配置',
    description: '应用的全局配置信息',
    mimeType: 'application/json'
  },
  async (uri) => ({
    contents: [{
      uri: uri.href,
      text: JSON.stringify({
        version: '1.0.0',
        apiUrl: 'https://api.example.com',
        features: ['tool1', 'tool2']
      }, null, 2)
    }]
  })
);

// 动态资源(带参数)
server.registerResource(
  'user-profile',
  new ResourceTemplate('user://{userId}/profile', { list: undefined }),
  {
    title: '用户资料',
    description: '获取用户的详细资料'
  },
  async (uri, { userId }) => ({
    contents: [{
      uri: uri.href,
      text: `用户 ${userId} 的资料信息`
    }]
  })
);

3. 注册提示词(Prompts)

import { completable } from '@jxee/sdk';

server.registerPrompt(
  'code-review',
  {
    title: '代码审查',
    description: '对提供的代码进行审查和建议',
    argsSchema: {
      code: z.string().describe('需要审查的代码'),
      language: completable(
        z.enum(['javascript', 'typescript', 'python', 'java']),
        (value) => {
          const langs = ['javascript', 'typescript', 'python', 'java'];
          return langs.filter(lang => lang.startsWith(value));
        }
      )
    }
  },
  ({ code, language }) => ({
    messages: [
      {
        role: 'user',
        content: {
          type: 'text',
          text: `请审查以下 ${language} 代码并提供改进建议:\n\n${code}`
        }
      }
    ]
  })
);

🎨 React Native 集成示例

在 React Native 组件中使用

import React, { useEffect, useState } from 'react';
import { View, Text, Button, ActivityIndicator } from 'react-native';
import { McpServer, Client, InMemoryTransport } from '@jxee/sdk';

function McpDemo() {
  const [client, setClient] = useState<Client | null>(null);
  const [result, setResult] = useState<string>('');
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    initializeMcp();
  }, []);

  const initializeMcp = async () => {
    // 创建并配置 Server
    const server = new McpServer({
      name: 'rn-demo-server',
      version: '1.0.0'
    });

    server.registerTool(
      'greet',
      {
        title: '打招呼',
        description: '向用户打招呼',
        inputSchema: { name: z.string() },
        outputSchema: { greeting: z.string() }
      },
      async ({ name }) => {
        const greeting = `你好,${name}!欢迎使用 MCP SDK for RN`;
        return {
          content: [{ type: 'text', text: greeting }],
          structuredContent: { greeting }
        };
      }
    );

    // 创建传输层
    const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();

    // 连接
    await server.connect(serverTransport);

    const newClient = new Client({
      name: 'rn-demo-client',
      version: '1.0.0'
    });

    await newClient.connect(clientTransport);
    setClient(newClient);
  };

  const handleCallTool = async () => {
    if (!client) return;

    setLoading(true);
    try {
      const response = await client.callTool({
        name: 'greet',
        arguments: { name: '浮浮酱' }
      });

      setResult(response.structuredContent.greeting);
    } catch (error) {
      setResult(`错误: ${error.message}`);
    } finally {
      setLoading(false);
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <Text style={{ fontSize: 18, marginBottom: 20 }}>MCP SDK Demo</Text>

      <Button
        title="调用工具"
        onPress={handleCallTool}
        disabled={!client || loading}
      />

      {loading && <ActivityIndicator style={{ marginTop: 20 }} />}

      {result ? (
        <Text style={{ marginTop: 20, fontSize: 16 }}>
          结果: {result}
        </Text>
      ) : null}
    </View>
  );
}

export default McpDemo;

使用 Context 管理 MCP 实例

import React, { createContext, useContext, useEffect, useState } from 'react';
import { McpServer, Client, InMemoryTransport } from '@jxee/sdk';

interface McpContextType {
  client: Client | null;
  server: McpServer | null;
  isReady: boolean;
}

const McpContext = createContext<McpContextType>({
  client: null,
  server: null,
  isReady: false
});

export const McpProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [client, setClient] = useState<Client | null>(null);
  const [server, setServer] = useState<McpServer | null>(null);
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    const setup = async () => {
      // 创建 Server
      const mcpServer = new McpServer({
        name: 'app-server',
        version: '1.0.0'
      });

      // 注册你的工具、资源等...
      // mcpServer.registerTool(...)

      // 创建传输层并连接
      const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
      await mcpServer.connect(serverTransport);

      const mcpClient = new Client({
        name: 'app-client',
        version: '1.0.0'
      });
      await mcpClient.connect(clientTransport);

      setServer(mcpServer);
      setClient(mcpClient);
      setIsReady(true);
    };

    setup();

    return () => {
      client?.close();
      server?.close();
    };
  }, []);

  return (
    <McpContext.Provider value={{ client, server, isReady }}>
      {children}
    </McpContext.Provider>
  );
};

export const useMcp = () => useContext(McpContext);

🔧 API 参考

InMemoryTransport

// 创建配对的传输层
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();

// 启动传输
await clientTransport.start();
await serverTransport.start();

// 关闭传输
await clientTransport.close();
await serverTransport.close();

Client API

// 列出所有工具
const tools = await client.listTools();

// 调用工具
const result = await client.callTool({
  name: 'tool-name',
  arguments: { /* ... */ }
});

// 列出资源
const resources = await client.listResources();

// 读取资源
const resource = await client.readResource({
  uri: 'resource://uri'
});

// 列出提示词
const prompts = await client.listPrompts();

// 获取提示词
const prompt = await client.getPrompt({
  name: 'prompt-name',
  arguments: { /* ... */ }
});

Server API

// 注册工具
server.registerTool(name, config, handler);

// 注册资源
server.registerResource(name, uriOrTemplate, metadata, handler);

// 注册提示词
server.registerPrompt(name, config, handler);

// 获取客户端能力
const capabilities = server.getClientCapabilities();

// 发送通知
await server.sendToolListChanged();
await server.sendResourceListChanged();
await server.sendPromptListChanged();

🎯 为什么选择 inMemory 传输?

在 React Native 环境中,使用 inMemory 传输有以下优势:

  1. 零网络开销 - Client 和 Server 在同一进程,无需 HTTP/WebSocket
  2. 简单可靠 - 没有网络错误、连接断开等问题
  3. 高性能 - 直接内存传递,无序列化/反序列化开销
  4. 易于调试 - 所有通信都在同一进程,方便断点调试
  5. 完全离线 - 不依赖任何网络连接

📖 与原版 SDK 的区别

| 特性 | 原版 SDK | 本 SDK | |------|----------|---------| | HTTP 传输 | ✅ | ❌ | | stdio 传输 | ✅ | ❌ | | SSE 传输 | ✅ | ❌ | | WebSocket 传输 | ✅ | ❌ | | inMemory 传输 | ✅ | | | 核心协议 | ✅ | ✅ | | 工具系统 | ✅ | ✅ | | 资源系统 | ✅ | ✅ | | 提示词系统 | ✅ | ✅ | | Node.js 特定依赖 | 有 | | | React Native 兼容 | 部分 | 完全 | | Web 浏览器兼容 | 部分 | 完全 |

🤝 贡献

欢迎贡献!请查看 CONTRIBUTING.md 了解详情。

📄 许可证

MIT License - 详见 LICENSE 文件

🔗 相关链接


由 jxee 维护