1
>
/*---------------------------------------------------------------------------------------------
serverToolGroups.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { feedbackServerToolGroup } from './agentFeedbackServerTools.js';
7
>
import { createSessionServerToolGroup, type ISessionServerToolAccessor } from './sessionServerTools.js';
8
>
import type { IServerToolDisplay, IServerToolDisplayResult, IServerToolGroup } from './agentServerToolHost.js';
9
>
10
>
/**
11
>
* Builds the server-tool groups contributed to every agent host session, in
12
>
* priority order. This is the single source of truth wired into the
13
>
* {@link AgentServerToolHost} at startup (see `agentService.ts`) and — via
14
>
* {@link getServerToolDisplay} — consulted by each provider's display layer.
15
>
*
16
>
* Adding a group here makes its tools available to all providers (Copilot,
17
>
* Claude, Codex, …) and — if the group implements
18
>
* {@link IServerToolGroup.getDisplay} — gives them nice display everywhere for
19
>
* free.
20
>
*
21
>
* `sessionAccessor` is the runtime dependency of the session-management group
22
>
* (list/create/delete sessions); it is provided by the host at construction.
23
>
* When omitted (the pure display path) the session group's `execute` is inert,
24
>
* but its definitions and display remain available.
25
>
*/
26
>
export function buildServerToolGroups(sessionAccessor?: ISessionServerToolAccessor): readonly IServerToolGroup[] {
27
>
return [feedbackServerToolGroup, createSessionServerToolGroup(sessionAccessor)];
28
>
}
29
>
30
>
/**
31
>
* The groups used by the pure {@link getServerToolDisplay} path. Built without a
32
>
* session accessor since display never invokes `execute`.
33
>
*/
34
>
const serverToolGroupsForDisplay: readonly IServerToolGroup[] = buildServerToolGroups();
35
>
36
>
/**
37
>
* Whether {@link toolName} (a tool name as seen on a tool call) refers to the
38
>
* server tool {@link bareName}. Accepts both the bare name and a transport
39
>
* prefix such as Claude's `mcp__<server>__<name>` (matched as a `__`-delimited
40
>
* suffix), mirroring the convention in `agentFeedbackAnnotations.ts`.
41
>
*/
42
function matchesServerToolName(toolName: string, bareName: string): boolean {
43
return toolName === bareName || toolName.endsWith(`__${bareName}`);
44
}
46
>
/**
47
>
* Resolves the {@link IServerToolDisplay} for a server tool call, authored by
48
>
* the group that owns the tool. Returns `undefined` when no contributed group
49
>
* owns {@link toolName} or the owning group has no bespoke display, so each
50
>
* provider's display layer can fall back to its generic behavior.
51
>
*
52
>
* Pure over the contributed groups (it does not need the constructed
53
>
* {@link AgentServerToolHost}) so the providers' history-replay paths — which
54
>
* build display from pure functions without a host instance — can call it too.
55
>
*
56
>
* @param toolName The tool name as seen on the call (bare or transport-prefixed).
57
>
* @param args The parsed tool arguments.
58
>
* @param result The tool result, once it has completed; absent while running.
59
>
*/
60
>
export function getServerToolDisplay(toolName: string, args: unknown, result?: IServerToolDisplayResult): IServerToolDisplay | undefined {
61
for (const group of serverToolGroupsForDisplay) {
62
if (!group.getDisplay) {