链式MCP构建工具

一个用于通过链式接口快速构建MCP服务器和客户端的工具库,提供内置CRUD操作、资源管理和多传输协议支持。

  • by jasonkneen
  • TypeScript
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 jasonkneen/fluent-mcp

使用说明

流利的MCP

一个可链接、流畅的界面,用于用最少的代码构建模型上下文协议(MCP)服务器和客户端。该库提供了一个jQuery-like API,用于创建具有内置CRUD操作和资源管理的MCP服务器,以及用于与MCP服务器通信的轻量级MCP客户端。

特性

  • 可链接API:使用流畅、可链接的界面创建和配置MCP服务器和客户端
  • 内置CRUD操作:自动为您的资源生成CRUD工具
  • 资源管理:使用内置存储轻松管理资源
  • 客户支持:使用同样熟悉的API创建MCP客户端
  • 多个传输:支持stdio、SSE和HTTP传输
  • 运输链:在同一服务器上同时运行多个传输
  • 灵活的配置:默认情况下很简单,但需要时可自定义
  • TypeScript支持:用于类型安全的完整TypeScript声明
  • JavaScript兼容性:适用于TypeScript和JavaScript环境

安装

npm install @jasonkneen/fluent-mcp

快速开始

# Run the demo server
npm start

配置选项

这 createMCP 函数接受可选 options 自定义参数:

import { createMCP } from '@jasonkneen/fluent-mcp';

// Simple usage with defaults
const simpleServer = createMCP('Notes API', '1.0.0');

// Advanced usage with custom options
const advancedServer = createMCP('Notes API', '1.0.0', {
  autoGenerateIds: false,     // Default: true - Set to false to manually manage IDs
  timestampEntries: false,    // Default: true - Set to false to disable automatic timestamps
  customOption: 'value'       // Any additional custom options
});

可用选项:

  • autoGenerateIds (布尔值,默认值: true):自动为CRUD操作生成随机ID
  • timestampEntries (布尔值,默认值: true):自动添加 createdAt/updatedAt 时间戳
  • 自定义选项:您特定用例所需的任何其他选项

使用Fluent MCP服务器界面

简单用法

有多种方法可以将Zod与FluentMCP一起用于模式验证:

选项1:单独导入Zod(传统方法)

import { createMCP, z } from '@jasonkneen/fluent-mcp';

// Create a new MCP server with fluent interface
const server = createMCP('Notes API', '1.0.0')
  // Define the Notes resource and CRUD operations
  .resource('Notes', {})
  .crud('Note', {
    title: z.string().describe('The title of the note'),
    content: z.string().describe('The content of the note'),
    tags: z.array(z.string()).optional().describe('Optional tags for the note')
  })

选项2:使用内置 .z 财产

import { createMCP } from '@jasonkneen/fluent-mcp';

// Create a new MCP server with fluent interface
const server = createMCP('Notes API', '1.0.0');

// Use the built-in .z property for schema validation
server
  .resource('Notes', {})
  .crud('Note', {
    title: server.z.string().describe('The title of the note'),
    content: server.z.string().describe('The content of the note'),
    tags: server.z.array(server.z.string()).optional().describe('Optional tags for the note')
  })

选项3:使用内置 .schema 属性(替代名称)

import { createMCP } from '@jasonkneen/fluent-mcp';

// Create a new MCP server with fluent interface
const server = createMCP('Notes API', '1.0.0');

// Use the built-in .schema property for schema validation
server
  .resource('Notes', {})
  .crud('Note', {
    title: server.schema.string().describe('The title of the note'),
    content: server.schema.string().describe('The content of the note'),
    tags: server.schema.array(server.schema.string()).optional().describe('Optional tags for the note')
  })

选项4:简化代码结构

import { createMCP } from '@jasonkneen/fluent-mcp';

// Create a new MCP server with fluent interface
const server = createMCP('Notes API', '1.0.0');
const { z } = server;  // or const { schema } = server;

server
  .resource('Notes', {})
  .crud('Note', {
    title: z.string().describe('The title of the note'),
    content: z.string().describe('The content of the note'),
    tags: z.array(z.string()).optional().describe('Optional tags for the note')
  })
  
  // Add a custom search tool
  .tool(
    'searchNotes',
    {
      query: z.string().describe('The search query')
    },
    async ({ query }) => {
      // Implementation...
    }
  )
  
  // Enable stdio transport and start the server
  .stdio()
  .start();

高级用法

import { createMCP, z } from '@jasonkneen/fluent-mcp';

// Create a new MCP server with advanced options
const server = createMCP('Task Manager API', '1.0.0', {
  autoGenerateIds: false,  // We'll manage IDs ourselves
  timestampEntries: false  // No automatic timestamps
})
  // Define resources with custom options
  .resource('Tasks', {})
  .crud('Task', {
    id: z.string().describe('The unique ID of the task'),
    title: z.string().describe('The title of the task'),
    // ...more fields
  }, {
    singularName: 'Task',
    pluralName: 'Tasks'  // Explicit pluralization
  })
  
  // Start the server
  .start();

运输选项

FluentMCP支持多种传输机制,可以同时运行。

标准运输

stdio传输是默认的,用于命令行MCP服务器。

import { createMCP } from '@jasonkneen/fluent-mcp';

const server = createMCP('My Server', '1.0.0')
  .tool('hello', { name: server.z.string() }, async ({ name }) => ({
    content: [{ type: 'text', text: `Hello, ${name}!` }]
  }))
  .stdio()
  .start();

SSE传输(服务器发送事件)

SSE传输支持通过HTTP进行实时通信。这非常适合基于web的MCP客户端。

import express from 'express';
import { createMCP } from '@jasonkneen/fluent-mcp';

const app = express();
app.use(express.json());

// SSE endpoint
app.get('/sse', async (req, res) => {
  const server = createMCP('SSE Server', '1.0.0')
    .tool('getData', {}, async () => ({
      content: [{ type: 'text', text: 'Data from SSE transport' }]
    }))
    .sse('/messages', res)
    .start();
});

app.listen(3000, () => {
  console.log('SSE server running on http://localhost:3000/sse');
});

多种运输方式(链式)

您可以在同一MCP服务器实例上同时运行多个传输。这允许客户端通过不同的方法连接,同时共享相同的工具和资源。

import express from 'express';
import { createMCP } from '@jasonkneen/fluent-mcp';

const app = express();

// Create a single server instance
function createServerInstance() {
  return createMCP('Multi-Transport Server', '1.0.0')
    .resource('Data', {})
    .crud('Item', {
      name: server.z.string(),
      value: server.z.string()
    })
    .tool('customTool', { query: server.z.string() }, async ({ query }) => ({
      content: [{ type: 'text', text: `Processed: ${query}` }]
    }));
}

// SSE endpoint
app.get('/sse', async (req, res) => {
  await createServerInstance().sse('/messages', res).start();
});

// Stdio transport (runs in parallel)
if (!process.stdin.isTTY) {
  createServerInstance().stdio().start();
}

app.listen(3000);

两种运输方式都可以使用相同的工具和资源!

使用Fluent MCP客户端界面

简单用法

import { createMCPClient } from '@jasonkneen/fluent-mcp';

// Create an MCP client with fluent API
const client = createMCPClient('Notes Client', '1.0.0')
  // Configure connection to an MCP server over stdio
  .stdio('node', ['path/to/server.js'])
  // Connect to the server
  .connect();
  
// Call server tools
const result = await client.callTool('searchNotes', { query: 'example' });
console.log(client.parseToolResult(result)); // Parse JSON response

HTTP客户端

import { createMCPClient } from '@jasonkneen/fluent-mcp';

// Create an HTTP client
const client = createMCPClient('Notes HTTP Client', '1.0.0')
  // Configure HTTP connection
  .http('http://localhost:3000/mcp')
  // Connect to the server
  .connect();

// List available tools
const tools = await client.listTools();
console.log(tools);

// Disconnect when done
await client.disconnect();

SSE客户端

import { createMCPClient } from '@jasonkneen/fluent-mcp';

// Create an SSE client
const client = createMCPClient('Notes SSE Client', '1.0.0')
  // Configure SSE connection
  .sse('http://localhost:3000/sse')
  // Connect to the server
  .connect();

// Call tools
const result = await client.callTool('getData', {});
console.log(client.parseToolResult(result));

// Disconnect when done
await client.disconnect();

高级客户端使用

import { createMCPClient, LoggingMessageNotificationSchema } from '@jasonkneen/fluent-mcp';

// Create a client with notification handlers
const client = createMCPClient('Notes Client', '1.0.0')
  // Register notification handler
  .onNotification(LoggingMessageNotificationSchema, (notification) => {
    console.log(`Server notification: ${notification.params.level} - ${notification.params.data}`);
  })
  // Register error handler
  .onError((error) => {
    console.error('Client error:', error);
  })
  // Configure connection
  .stdio('node', ['path/to/server.js']);

// Connect and use the client
await client.connect();

// Use helper methods
const resources = await client.listResources();
const prompts = await client.listPrompts();
const promptTemplate = await client.getPrompt('examplePrompt', { param: 'value' });

// Disconnect when done
await client.disconnect();

运行Demos

服务器演示

npm start            # Run the JavaScript demo server
# or
npm run demo         # Same as above
npm run demo:ts      # Run the TypeScript demo server
npm run demo:sse     # Run the SSE server demo (with multiple transports)

客户演示

npm run demo:client       # Run the stdio client demo
npm run demo:http-client  # Run the HTTP client demo
npm run demo:sse-client   # Run the SSE client demo

可用方法

核心方法

  • createMCP(name, version, options):使用灵活的配置选项创建新的FluentMCP服务器实例
  • createMCPClient(name, version, options):使用灵活的配置选项创建新的FluentMPClient实例
  • connectMCPClient(name, version, transportConfig):一步创建和连接客户端
  • z:重新导出用于模式定义的Zod库(无需单独安装Zod)

服务器方法

  • resource(name, initialData):初始化资源存储
  • getResource(name):获取资源存储
  • setResource(name, id, data):设置资源值
  • deleteResource(name, id):删除资源值
  • crud(resourceName, schema, options):为资源创建CRUD操作
  • tool(name, schema, handler):向服务器添加工具
  • stdio():启用stdio传输
  • sse(endpoint, res):启用SSE传输
  • start():使用配置的传输启动服务器

客户端方法

  • onError(handler):注册错误处理程序
  • onNotification(schema, handler):注册通知处理程序
  • stdio(command, args, options):配置stdio传输
  • http(url, options):配置HTTP传输
  • sse(url, options):配置SSE传输
  • callTool(name, args, resultSchema):调用MCP服务器上的工具
  • listTools():列出服务器上可用的工具
  • listResources():列出服务器上的可用资源
  • listPrompts():列出服务器上的可用提示
  • getPrompt(name, args):从服务器获取提示
  • parseToolResult(result):将工具结果解析为JSON
  • connect():连接到MCP服务器
  • disconnect():断开与MCP服务器的连接

测试

使用以下命令运行测试:

npm test

或观看模式:

npm run test:watch

定制化

您可以使用自己的方法扩展FluentMCP类以添加其他功能。可链接的设计使添加新功能变得容易,同时保持一个干净的API。