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:
2026-04-08 21:28:01 +03:00
parent afc4627353
commit 5cc16725fb
88 changed files with 12637 additions and 405 deletions
+69
View File
@@ -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);
}
}