feat(mcp): generic MCP tool source with per-node function filtering (#301)

* feat(mcp): generic MCP tool source with per-node function filtering

Adds a Model Context Protocol tool category: connect a customer MCP
server and expose its tools to the agent, with optional per-node
allow-listing of individual MCP functions.

- ToolCategory.MCP enum + alembic migration
- MCP definition validator and collision-safe function-name namespacing
- McpToolSession wrapper: graceful-degrade, per-call open/close lifecycle
- CustomToolManager MCP branch (schemas + proxy handlers)
- Per-node mcp_tool_filters threaded through DTO/graph/engine
- Best-effort discovered_tools catalog cache + POST /tools/{uuid}/mcp/refresh
- UI: MCP create/edit config, tabbed ToolSelector with per-node toggles

* feat: refactor for code standardisation and documentation

---------

Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
This commit is contained in:
Paulo Busato Favarato 2026-05-19 07:40:00 -03:00 committed by GitHub
parent 0097974444
commit 75839f9de5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 3028 additions and 137 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -949,7 +949,9 @@ export type CreateToolRequest = {
type: 'transfer_call';
} & TransferCallToolDefinition) | ({
type: 'calculator';
} & CalculatorToolDefinition);
} & CalculatorToolDefinition) | ({
type: 'mcp';
} & McpToolDefinition);
};
/**
@ -2097,6 +2099,102 @@ export type MpsCreditsResponse = {
total_quota: number;
};
/**
* McpRefreshResponse
*
* Result of re-discovering an MCP server's tool catalog.
*/
export type McpRefreshResponse = {
/**
* Tool Uuid
*/
tool_uuid: string;
/**
* Discovered Tools
*/
discovered_tools?: Array<unknown>;
/**
* Error
*/
error?: string | null;
};
/**
* McpToolConfig
*
* Configuration for an MCP tool definition.
*/
export type McpToolConfig = {
/**
* Transport
*
* MCP transport protocol
*/
transport?: 'streamable_http';
/**
* Url
*
* MCP server URL (must be http:// or https://)
*/
url: string;
/**
* Credential Uuid
*
* Reference to ExternalCredentialModel for auth
*/
credential_uuid?: string | null;
/**
* Tools Filter
*
* Allowlist of MCP tool names to expose (empty = all tools)
*/
tools_filter?: Array<string>;
/**
* Timeout Secs
*
* Connection timeout in seconds
*/
timeout_secs?: number;
/**
* Sse Read Timeout Secs
*
* SSE read timeout in seconds
*/
sse_read_timeout_secs?: number;
/**
* Discovered Tools
*
* Server-managed cache of the MCP server's tool catalog [{name, description}]. Populated best-effort by the backend.
*/
discovered_tools?: Array<{
[key: string]: unknown;
}>;
};
/**
* McpToolDefinition
*
* Persisted MCP tool definition.
*/
export type McpToolDefinition = {
/**
* Schema Version
*
* Schema version
*/
schema_version?: number;
/**
* Type
*
* Tool type
*/
type: 'mcp';
/**
* MCP server configuration
*/
config: McpToolConfig;
};
/**
* NodeCategory
*
@ -3842,7 +3940,9 @@ export type UpdateToolRequest = {
type: 'transfer_call';
} & TransferCallToolDefinition) | ({
type: 'calculator';
} & CalculatorToolDefinition) | null;
} & CalculatorToolDefinition) | ({
type: 'mcp';
} & McpToolDefinition) | null;
/**
* Status
*/
@ -7652,6 +7752,50 @@ export type UpdateToolApiV1ToolsToolUuidPutResponses = {
export type UpdateToolApiV1ToolsToolUuidPutResponse = UpdateToolApiV1ToolsToolUuidPutResponses[keyof UpdateToolApiV1ToolsToolUuidPutResponses];
export type RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostData = {
body?: never;
headers?: {
/**
* Authorization
*/
authorization?: string | null;
/**
* X-Api-Key
*/
'X-API-Key'?: string | null;
};
path: {
/**
* Tool Uuid
*/
tool_uuid: string;
};
query?: never;
url: '/api/v1/tools/{tool_uuid}/mcp/refresh';
};
export type RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostErrors = {
/**
* Not found
*/
404: unknown;
/**
* Validation Error
*/
422: HttpValidationError;
};
export type RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostError = RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostErrors[keyof RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostErrors];
export type RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostResponses = {
/**
* Successful Response
*/
200: McpRefreshResponse;
};
export type RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostResponse = RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostResponses[keyof RefreshMcpToolsApiV1ToolsToolUuidMcpRefreshPostResponses];
export type UnarchiveToolApiV1ToolsToolUuidUnarchivePostData = {
body?: never;
headers?: {