@opentiny/agent 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -1,13 +1,107 @@
1
- # OpenTiny Agent
1
+ # OpenTiny NEXT
2
2
 
3
- OpenTiny Agent Server
3
+ OpenTiny NEXT 是一个基于 Model Context Protocol(MCP)的 TypeScript 库,提供了多种传输方式来支持 MCP 客户端与服务端的通信。本库支持三种主要的传输方式:
4
+
5
+ 1. MessageChannel API - 用于浏览器内部不同上下文之间的通信
6
+ 2. SSE (Server-Sent Events) Client Proxy - 基于 HTTP 长连接实现单向数据推送的 Client 连接代理
7
+ 3. Streamable HTTP Client Proxy - 通过分块传输编码实现任意数据的流式传输的 Client 连接代理
4
8
 
5
9
  ## 安装
6
10
 
7
11
  ```bash
8
- npm install @opentiny/agent
12
+ npm install @opentiny/next
9
13
  ```
10
14
 
15
+ ## 客户端 API (client.js)
16
+
17
+ 客户端 API 主要用于在浏览器环境中的 MCP 通信。
18
+
19
+ ### MessageChannel API
20
+
21
+ #### 在同一浏览器窗口内互相通信的场景
22
+
23
+ 使用 `createTransportPair` 创建一对可互通的 Transport 服务的和客户端实例来进行通信。
24
+
25
+ ```typescript
26
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
27
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
28
+ import { createTransportPair } from '@opentiny/next';
29
+
30
+ // 创建一对可互通的 Transport 实例
31
+ const [serverTransport, clientTransport] = createTransportPair();
32
+
33
+ // 创建 MCP 服务端和客户端实例
34
+ const serverCapabilities = {
35
+ prompts: { listChanged: true },
36
+ resources: { subscribe: true, listChanged: true },
37
+ tools: { listChanged: true },
38
+ completions: {},
39
+ logging: {}
40
+ };
41
+ const clientCapabilities = { roots: { listChanged: true }, sampling: {}, elicitation: {} };
42
+ const server = new McpServer({ name: 'mcp-server', version: '1.0.0' }, { capabilities: serverCapabilities });
43
+ const client = new Client({ name: 'mcp-client', version: '1.0.0' }, { capabilities: clientCapabilities });
44
+
45
+ // 建立服务端和客户端的通信连接
46
+ await server.connect(serverTransport);
47
+ await client.connect(clientTransport);
48
+
49
+ // 将客户端实例存储到状态中
50
+ state.client = client;
51
+ ```
52
+
53
+ #### 在浏览器主线程与iframe、Web Worker等互相通信的场景
54
+
55
+ 使用 `MessageChannelServerTransport` 和 `MessageChannelClientTransport` 创建用于监听的 Transport 服务端实例,以及用于连接的 Transport 客户端实例来进行通信。
56
+
57
+ 以下是在浏览器主线程的代码:
58
+
59
+ ```typescript
60
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
61
+ import { MessageChannelServerTransport } from '@opentiny/next';
62
+
63
+ // 创建用于监听的 Transport 服务端实例
64
+ const serverTransport = new MessageChannelServerTransport('endpoint');
65
+
66
+ // 创建 MCP 服务端实例
67
+ const capabilities = {
68
+ prompts: { listChanged: true },
69
+ resources: { subscribe: true, listChanged: true },
70
+ tools: { listChanged: true },
71
+ completions: {},
72
+ logging: {}
73
+ };
74
+ const server = new McpServer({ name: 'mcp-server', version: '1.0.0' }, { capabilities });
75
+
76
+ // 监听 endpoint 端点,等待客户端连接
77
+ await serverTransport.listen();
78
+
79
+ // 建立服务端和客户端的通信连接
80
+ await server.connect(serverTransport);
81
+ ```
82
+
83
+ 以下是在 iframe、Web Worker 的代码:
84
+
85
+ ```typescript
86
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
87
+ import { MessageChannelClientTransport } from '@opentiny/next';
88
+
89
+ // 创建用于连接的 Transport 客户端实例
90
+ const clientTransport = new MessageChannelClientTransport('endpoint');
91
+
92
+ // 创建 MCP 客户端实例
93
+ const capabilities = { roots: { listChanged: true }, sampling: {}, elicitation: {} };
94
+ const client = new Client({ name: 'mcp-client', version: '1.0.0' }, { capabilities });
95
+
96
+ // 建立服务端和客户端的通信连接
97
+ await client.connect(clientTransport);
98
+
99
+ // 将客户端实例存储到状态中
100
+ state.client = client;
101
+ ```
102
+
103
+ 请注意:创建 `MessageChannelServerTransport` 实例必须在创建 `MessageChannelClientTransport` 实例之前,确保客户端连接之前服务端已经开始监听。由于 iframe、Web Worker 等代码运行通常在浏览器主线程之后,所以上述示例代码执行顺序一般是先创建 `MessageChannelServerTransport` 实例,后创建 `MessageChannelClientTransport` 实例。
104
+
11
105
  ## 许可证
12
106
 
13
107
  MIT
package/index.d.ts CHANGED
@@ -2,6 +2,9 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
3
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
4
4
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
6
+ import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
7
+ import WebSocket from 'ws';
5
8
  import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
6
9
  import { Response, RequestHandler, Request, NextFunction } from 'express';
7
10
  import { JwtPayload } from 'jsonwebtoken';
@@ -9,6 +12,22 @@ import { OAuthClientInformationFull, OAuthTokens, OAuthTokenRevocationRequest }
9
12
  import { AuthorizationParams, OAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/provider.js';
10
13
  import { OAuthRegisteredClientsStore } from '@modelcontextprotocol/sdk/server/auth/clients.js';
11
14
  import { AuthRouterOptions } from '@modelcontextprotocol/sdk/server/auth/router.js';
15
+ import { CorsOptions } from 'cors';
16
+
17
+ /**
18
+ * Server transport for WebSocket: this will listen to clients over the WebSocket protocol.
19
+ */
20
+ declare class WebSocketServerTransport implements Transport {
21
+ private _socket?;
22
+ sessionId?: string;
23
+ onclose?: () => void;
24
+ onerror?: (error: Error) => void;
25
+ onmessage?: (message: JSONRPCMessage) => void;
26
+ constructor(socket: WebSocket);
27
+ start(): Promise<void>;
28
+ close(): Promise<void>;
29
+ send(message: JSONRPCMessage): Promise<void>;
30
+ }
12
31
 
13
32
  declare const ACCESS_TOKEN_EXPIRES_IN: number;
14
33
  declare const REFRESH_TOKEN_EXPIRES_IN: number;
@@ -349,12 +368,13 @@ declare const createAuthCallbackRouter: (callbackEndpoint: string, ...middleware
349
368
  /**
350
369
  * 创建 OAuth 认证元数据路由。
351
370
  *
352
- * @param authServerProvider 认证服务器提供者
371
+ * @param authProvider 认证服务器提供者
353
372
  * @param authUrl 认证 URL
354
373
  * @param resourceUrl 资源 URL
374
+ * @param issuerUrl 签发者 URL,可选
355
375
  * @returns Express 路由处理器
356
376
  */
357
- declare const createAuthMetadataRouter: (authServerProvider: AuthServerProvider, authUrl: string, resourceUrl: string) => RequestHandler;
377
+ declare const createAuthMetadataRouter: (authProvider: AuthServerProvider, authUrl: string, resourceUrl: string, issuerUrl?: string) => RequestHandler;
358
378
  /**
359
379
  * 创建 OAuth 认证路由。
360
380
  *
@@ -362,6 +382,15 @@ declare const createAuthMetadataRouter: (authServerProvider: AuthServerProvider,
362
382
  * @returns Express 路由处理器
363
383
  */
364
384
  declare const createAuthRouter: (options: AuthRouterOptions) => RequestHandler;
385
+ /**
386
+ * 创建锁定 CORS 头中间件
387
+ * 配置的 CORS 规则,并锁定 Access-Control-Allow-Origin,
388
+ * 防止后续中间件(如第三方库)修改它。
389
+ *
390
+ * @param options CORS 选项
391
+ * @returns Express 中间件函数
392
+ */
393
+ declare const lockCors: (options: CorsOptions) => (req: Request, res: Response, next: NextFunction) => void;
365
394
 
366
395
  /**
367
396
  * 客户端连接的信息,包括客户端实例、用户信息和 Transport 类型。
@@ -374,7 +403,7 @@ interface ClientInfo {
374
403
  /**
375
404
  * 客户端连接的 Transport 实例
376
405
  */
377
- transport: SSEServerTransport | StreamableHTTPServerTransport;
406
+ transport: SSEServerTransport | StreamableHTTPServerTransport | WebSocketServerTransport;
378
407
  /**
379
408
  * 连接的用户信息
380
409
  */
@@ -403,7 +432,7 @@ interface ClientInfo {
403
432
  /**
404
433
  * 客户端连接的 Transport 类型
405
434
  */
406
- type: 'SSE' | 'StreamableHTTP';
435
+ type: 'SSE' | 'StreamableHTTP' | 'WebSocket';
407
436
  }
408
437
  /**
409
438
  * 遥控端连接的信息,包括服务端实例、用户信息和 Transport 类型。
@@ -462,7 +491,7 @@ interface ClientError {
462
491
  /**
463
492
  * 客户端连接的 Transport 实例
464
493
  */
465
- transport: SSEServerTransport | StreamableHTTPServerTransport;
494
+ transport: SSEServerTransport | StreamableHTTPServerTransport | WebSocketServerTransport;
466
495
  /**
467
496
  * 错误信息
468
497
  */
@@ -470,7 +499,7 @@ interface ClientError {
470
499
  /**
471
500
  * 服务端连接的 Transport 类型
472
501
  */
473
- type: 'SSE' | 'StreamableHTTP';
502
+ type: 'SSE' | 'StreamableHTTP' | 'WebSocket';
474
503
  }
475
504
  /**
476
505
  * RemoterError 接口,在遥控端连接或处理过程中发生的错误。
@@ -516,6 +545,14 @@ declare module 'express' {
516
545
  declare const auth: ({ secret }: {
517
546
  secret: string;
518
547
  }) => (req: Request, res: Response, next: NextFunction) => void;
548
+ /**
549
+ * 请求认证,用于校验 JWT Token。
550
+ *
551
+ * 检查 request.query 中的 token 字段。
552
+ * 校验通过后,将解码后的用户信息挂载到 req.user
553
+ * 校验失败或缺失 token 时,抛出异常。
554
+ */
555
+ declare const jwtAuth: (req: Request, secret: string) => void;
519
556
  /**
520
557
  * SSE 与 Streamable HTTP 连接的处理函数,同时返回所有客户端代理实例。
521
558
  */
@@ -525,6 +562,7 @@ declare const useProxyHandles: () => {
525
562
  handleSseMessage: (req: Request, res: Response) => Promise<void>;
526
563
  handleStreamRequest: (req: Request, res: Response) => Promise<void>;
527
564
  handleStreamInspector: (req: Request, res: Response) => Promise<void>;
565
+ handleWebSocket: (socket: WebSocket, req: Request) => Promise<void>;
528
566
  clients: Record<string, ClientInfo>;
529
567
  remoters: Record<string, RemoterInfo>;
530
568
  transports: Record<string, any>;
@@ -538,5 +576,5 @@ declare const useProxyHandles: () => {
538
576
  onRemoterError: (onError: (error: RemoterError) => void) => void;
539
577
  };
540
578
 
541
- export { ACCESS_TOKEN_EXPIRES_IN, AuthServerProvider, MemoryAccessTokensStore, MemoryAuthorizationCodeStore, MemoryClientsStore, MemoryRefreshTokensStore, REFRESH_TOKEN_EXPIRES_IN, auth, createAuthCallbackRouter, createAuthMetadataRouter, createAuthMiddleware, createAuthRouter, useProxyHandles };
579
+ export { ACCESS_TOKEN_EXPIRES_IN, AuthServerProvider, MemoryAccessTokensStore, MemoryAuthorizationCodeStore, MemoryClientsStore, MemoryRefreshTokensStore, REFRESH_TOKEN_EXPIRES_IN, WebSocketServerTransport, auth, createAuthCallbackRouter, createAuthMetadataRouter, createAuthMiddleware, createAuthRouter, jwtAuth, lockCors, useProxyHandles };
542
580
  export type { AuthServerProviderOptions, ClientError, ClientInfo, OAuthAccessTokensStore, OAuthAuthorizationCodeStore, OAuthRefreshTokensStore, RemoterError, RemoterInfo };