mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-08 04:38:45 +02:00
feat: discover MCP tools via protocol probing for approval pill
When MCP server configs declare wildcard tools (empty tools array), the Copilot SDK has no API to list individual tool names. Add direct MCP protocol probing using @modelcontextprotocol/sdk to discover available tools from each accepted server. - Add McpToolProber service supporting stdio/SSE/HTTP transports - Probe accepted MCP servers on project load, acceptance, and rescan - Store probed tools on DiscoveredMcpServer and McpServerDefinition - Use probed tools in listApprovalToolDefinitions when declared tools are empty, so the approval pill shows individual tool toggles - Remove unused isMcpServerApprovalKey helper - Fix effectiveAutoApprovedCount Math.max workaround in ChatPane - Add comprehensive tests for probed tool behavior - Update ARCHITECTURE.md tooling integration section Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -7,6 +7,7 @@ export interface BaseDiscoveredMcpServer {
|
||||
name: string;
|
||||
transport: DiscoveredMcpServerTransport;
|
||||
tools: string[];
|
||||
probedTools?: { name: string; description?: string }[];
|
||||
timeoutMs?: number;
|
||||
scope: DiscoveredToolingScope;
|
||||
scannerId: string;
|
||||
|
||||
@@ -9,11 +9,17 @@ import { nowIso } from '@shared/utils/ids';
|
||||
|
||||
export type McpServerTransport = 'local' | 'http' | 'sse';
|
||||
|
||||
export interface McpProbedTool {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface BaseMcpServerDefinition {
|
||||
id: string;
|
||||
name: string;
|
||||
transport: McpServerTransport;
|
||||
tools: string[];
|
||||
probedTools?: McpProbedTool[];
|
||||
timeoutMs?: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
@@ -155,10 +161,6 @@ export function buildMcpServerApprovalKey(serverName: string): string {
|
||||
return `${MCP_SERVER_APPROVAL_PREFIX}${serverName}`;
|
||||
}
|
||||
|
||||
export function isMcpServerApprovalKey(key: string): boolean {
|
||||
return key.startsWith(MCP_SERVER_APPROVAL_PREFIX);
|
||||
}
|
||||
|
||||
export function createWorkspaceSettings(): WorkspaceSettings {
|
||||
return {
|
||||
theme: 'dark',
|
||||
@@ -240,10 +242,16 @@ export function listApprovalToolDefinitions(
|
||||
}
|
||||
|
||||
for (const server of tooling.mcpServers) {
|
||||
for (const toolName of normalizeStringArray(server.tools)) {
|
||||
const declaredTools = normalizeStringArray(server.tools);
|
||||
const toolEntries = declaredTools.length > 0
|
||||
? declaredTools.map((name) => ({ name, description: undefined }))
|
||||
: (server.probedTools ?? []).filter((t) => t.name.trim().length > 0);
|
||||
|
||||
for (const tool of toolEntries) {
|
||||
registerApprovalTool(toolsById, {
|
||||
id: toolName,
|
||||
label: toolName,
|
||||
id: tool.name,
|
||||
label: tool.name,
|
||||
description: tool.description,
|
||||
kind: 'mcp',
|
||||
providerId: server.id,
|
||||
providerName: server.name,
|
||||
@@ -469,6 +477,10 @@ function toResolvedMcpServerDefinition(
|
||||
server: ReturnType<typeof listAcceptedDiscoveredMcpServers>[number],
|
||||
timestamp = nowIso(),
|
||||
): McpServerDefinition {
|
||||
const probedTools = server.probedTools && server.probedTools.length > 0
|
||||
? [...server.probedTools]
|
||||
: undefined;
|
||||
|
||||
if (server.transport === 'local') {
|
||||
return normalizeMcpServerDefinition({
|
||||
id: server.id,
|
||||
@@ -479,6 +491,7 @@ function toResolvedMcpServerDefinition(
|
||||
cwd: server.cwd,
|
||||
env: server.env ? { ...server.env } : undefined,
|
||||
tools: [...server.tools],
|
||||
probedTools,
|
||||
timeoutMs: server.timeoutMs,
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
@@ -492,6 +505,7 @@ function toResolvedMcpServerDefinition(
|
||||
url: server.url,
|
||||
headers: server.headers ? { ...server.headers } : undefined,
|
||||
tools: [...server.tools],
|
||||
probedTools,
|
||||
timeoutMs: server.timeoutMs,
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
|
||||
Reference in New Issue
Block a user