chore(repo): restructure as monorepo with server and client workspaces
- move NestJS app into server/ subdirectory - add client/ React+TypeScript (Vite) app with Hello World - update docker-compose to build and run both services - add root package.json declaring npm workspaces - update .gitignore to cover node_modules and dist at all depths
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { Controller, Delete, Get, Post, Req, Res } from "@nestjs/common";
|
||||
import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||
import type { Request, Response } from "express";
|
||||
import { McpService } from "./mcp.service";
|
||||
|
||||
@ApiTags("mcp")
|
||||
@Controller("mcp")
|
||||
export class McpController {
|
||||
constructor(private readonly mcpService: McpService) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({
|
||||
summary: "Send JSON-RPC message",
|
||||
description:
|
||||
"Accepts a JSON-RPC request, notification, or response. " +
|
||||
"Returns either `application/json` for a single response or " +
|
||||
"`text/event-stream` (SSE) when the server streams multiple messages.",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: "JSON-RPC response (application/json or text/event-stream)",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 202,
|
||||
description: "Accepted — input was a notification or response only",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 400,
|
||||
description: "Bad Request — malformed JSON-RPC payload",
|
||||
})
|
||||
post(@Req() req: Request, @Res() res: Response): Promise<void> {
|
||||
return this.mcpService.handle(req, res);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({
|
||||
summary: "Open server-sent event stream",
|
||||
description:
|
||||
"Opens a persistent SSE stream so the server can push JSON-RPC requests and " +
|
||||
"notifications to the client without a prior POST. " +
|
||||
"Requires `Accept: text/event-stream`. Pass `Last-Event-ID` to resume a broken stream.",
|
||||
})
|
||||
@ApiResponse({ status: 200, description: "SSE stream (text/event-stream)" })
|
||||
@ApiResponse({
|
||||
status: 405,
|
||||
description: "Method Not Allowed — server does not offer an SSE stream",
|
||||
})
|
||||
get(@Req() req: Request, @Res() res: Response): Promise<void> {
|
||||
return this.mcpService.handle(req, res);
|
||||
}
|
||||
|
||||
@Delete()
|
||||
@ApiOperation({
|
||||
summary: "Terminate session",
|
||||
description:
|
||||
"Explicitly terminates a session identified by the `Mcp-Session-Id` header. " +
|
||||
"The server may return 405 if it does not support client-initiated session termination.",
|
||||
})
|
||||
@ApiResponse({ status: 200, description: "Session terminated" })
|
||||
@ApiResponse({ status: 404, description: "Session not found" })
|
||||
@ApiResponse({
|
||||
status: 405,
|
||||
description:
|
||||
"Method Not Allowed — server does not support session termination",
|
||||
})
|
||||
delete(@Req() req: Request, @Res() res: Response): Promise<void> {
|
||||
return this.mcpService.handle(req, res);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user