返回 AiToEarn
mcp-handler.base.ts
根目录 / project / aitoearn-backend / libs / nest-mcp / src / services / handlers / mcp-handler.base.ts
1 import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2 import { Progress } from '@modelcontextprotocol/sdk/types.js'
3 import { Logger } from '@nestjs/common'
4 import { ModuleRef } from '@nestjs/core'
5 import { Context, McpRequest, SerializableValue } from '../../interfaces'
6 import { McpRegistryService } from '../mcp-registry.service'
7
8 export abstract class McpHandlerBase {
9 protected logger: Logger
10
11 constructor(
12 protected readonly moduleRef: ModuleRef,
13 protected readonly registry: McpRegistryService,
14 loggerContext: string,
15 ) {
16 this.logger = new Logger(loggerContext)
17 }
18
19 protected createContext(
20 mcpServer: McpServer,
21 mcpRequest: McpRequest,
22 ): Context {
23 // handless stateless traffic where notifications and progress are not supported
24 if (mcpServer.server.transport?.sessionId === undefined) {
25 return this.createStatelessContext(mcpServer, mcpRequest)
26 }
27
28 const progressToken = mcpRequest.params?._meta?.progressToken
29 return {
30 reportProgress: async (progress: Progress) => {
31 if (progressToken) {
32 await mcpServer.server.notification({
33 method: 'notifications/progress',
34 params: {
35 ...progress,
36 progressToken,
37 } as Progress,
38 })
39 }
40 },
41 log: {
42 debug: (message: string, context?: SerializableValue) => {
43 void mcpServer.server.sendLoggingMessage({
44 level: 'debug',
45 data: { message, context },
46 })
47 },
48 error: (message: string, context?: SerializableValue) => {
49 void mcpServer.server.sendLoggingMessage({
50 level: 'error',
51 data: { message, context },
52 })
53 },
54 info: (message: string, context?: SerializableValue) => {
55 void mcpServer.server.sendLoggingMessage({
56 level: 'info',
57 data: { message, context },
58 })
59 },
60 warn: (message: string, context?: SerializableValue) => {
61 void mcpServer.server.sendLoggingMessage({
62 level: 'warning',
63 data: { message, context },
64 })
65 },
66 },
67 mcpServer,
68 mcpRequest,
69 }
70 }
71
72 protected createStatelessContext(
73 mcpServer: McpServer,
74 mcpRequest: McpRequest,
75 ): Context {
76 const warn = (fn: string) => {
77 this.logger.warn(`Stateless context: '${fn}' is not supported.`)
78 }
79 return {
80 reportProgress: async (_progress: Progress) => {
81 warn('reportProgress not supported in stateless')
82 },
83 log: {
84 debug: (_message: string, _data?: SerializableValue) => {
85 warn('server report logging not supported in stateless')
86 },
87 error: (_message: string, _data?: SerializableValue) => {
88 warn('server report logging not supported in stateless')
89 },
90 info: (_message: string, _data?: SerializableValue) => {
91 warn('server report logging not supported in stateless')
92 },
93 warn: (_message: string, _data?: SerializableValue) => {
94 warn('server report logging not supported in stateless')
95 },
96 },
97 mcpServer,
98 mcpRequest,
99 }
100 }
101 }
102
102 lines TYPESCRIPT