feat(ai): add integration tests for MCP controller and improve JSON-R… (#14047)

…PC validation

- Introduced full integration test suite for MCP controller, testing
`POST /mcp` with valid and invalid payloads.
- Added `@IsDefined` validation to ensure the `method` field is required
in JSON-RPC requests.
- Applied `RestApiExceptionFilter` to MCP controller for consistent
error handling.
- Enhanced validation pipe in MCP controller to whitelist and reject
non-whitelisted properties.
- Consolidated exception filters in SSOAuthController.
This commit is contained in:
Antoine Moreaux
2025-08-25 10:30:38 +02:00
committed by GitHub
parent 6c5a265a4e
commit 9f16b13843
5 changed files with 190 additions and 8 deletions
@@ -6,6 +6,7 @@ import { type Workspace } from 'src/engine/core-modules/workspace/workspace.enti
import { MCP_SERVER_METADATA } from 'src/engine/core-modules/ai/constants/mcp.const';
import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service';
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { McpController } from './mcp.controller';
@@ -33,6 +34,12 @@ describe('McpController', () => {
provide: WorkspaceCacheStorageService,
useValue: jest.fn(),
},
{
provide: HttpExceptionHandlerService,
useValue: {
handleError: jest.fn(),
},
},
],
}).compile();
@@ -2,6 +2,7 @@ import {
Body,
Controller,
Post,
UseFilters,
UseGuards,
UsePipes,
ValidationPipe,
@@ -15,21 +16,29 @@ import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-worksp
import { JsonRpc } from 'src/engine/core-modules/ai/dtos/json-rpc';
import { McpService } from 'src/engine/core-modules/ai/services/mcp.service';
import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard';
import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter';
@Controller('mcp')
@UseGuards(JwtAuthGuard, WorkspaceAuthGuard)
@UseFilters(RestApiExceptionFilter)
export class McpController {
constructor(private readonly mcpService: McpService) {}
@Post()
@UsePipes(new ValidationPipe({ transform: true }))
@UsePipes(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
}),
)
async handleMcpCore(
@Body() body: JsonRpc,
@AuthWorkspace() workspace: Workspace,
@AuthApiKey() apiKey: string | undefined,
@AuthUserWorkspaceId() userWorkspaceId: string | undefined,
) {
return this.mcpService.handleMCPCoreQuery(body, {
return await this.mcpService.handleMCPCoreQuery(body, {
workspace,
userWorkspaceId,
apiKey,
@@ -1,4 +1,5 @@
import {
IsDefined,
IsNotEmpty,
IsObject,
IsOptional,
@@ -14,6 +15,7 @@ export class JsonRpc {
@Matches(/^2\.0$/, { message: 'jsonrpc must be exactly "2.0"' })
jsonrpc = '2.0';
@IsDefined({ message: 'method is required' })
@IsString()
@IsNotEmpty()
method: string;