feat: Add support for MCP Resources (#13178)

Co-authored-by: Jack Wotherspoon <jackwoth@google.com>
This commit is contained in:
Alex Gavrilescu
2025-12-09 03:43:12 +01:00
committed by GitHub
parent 720b31cb8b
commit 560550f5df
20 changed files with 1146 additions and 80 deletions
@@ -63,6 +63,7 @@ describe('mcpCommand', () => {
getPromptRegistry: ReturnType<typeof vi.fn>;
getGeminiClient: ReturnType<typeof vi.fn>;
getMcpClientManager: ReturnType<typeof vi.fn>;
getResourceRegistry: ReturnType<typeof vi.fn>;
};
beforeEach(() => {
@@ -93,6 +94,9 @@ describe('mcpCommand', () => {
getBlockedMcpServers: vi.fn(),
getMcpServers: vi.fn(),
})),
getResourceRegistry: vi.fn().mockReturnValue({
getAllResources: vi.fn().mockReturnValue([]),
}),
};
mockContext = createMockCommandContext({
@@ -141,6 +145,10 @@ describe('mcpCommand', () => {
};
mockConfig.getMcpServers = vi.fn().mockReturnValue(mockMcpServers);
mockConfig.getMcpClientManager = vi.fn().mockReturnValue({
getMcpServers: vi.fn().mockReturnValue(mockMcpServers),
getBlockedMcpServers: vi.fn().mockReturnValue([]),
});
});
it('should display configured MCP servers with status indicators and their tools', async () => {
@@ -169,6 +177,30 @@ describe('mcpCommand', () => {
getAllTools: vi.fn().mockReturnValue(allTools),
});
const resourcesByServer: Record<
string,
Array<{ name: string; uri: string }>
> = {
server1: [
{
name: 'Server1 Resource',
uri: 'file:///server1/resource1.txt',
},
],
server2: [],
server3: [],
};
mockConfig.getResourceRegistry = vi.fn().mockReturnValue({
getAllResources: vi.fn().mockReturnValue(
Object.entries(resourcesByServer).flatMap(([serverName, resources]) =>
resources.map((entry) => ({
serverName,
...entry,
})),
),
),
});
await mcpCommand.action!(mockContext, '');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
@@ -180,6 +212,12 @@ describe('mcpCommand', () => {
description: tool.description,
schema: tool.schema,
})),
resources: expect.arrayContaining([
expect.objectContaining({
serverName: 'server1',
uri: 'file:///server1/resource1.txt',
}),
]),
}),
expect.any(Number),
);
@@ -12,6 +12,7 @@ import type {
import { CommandKind } from './types.js';
import type {
DiscoveredMCPPrompt,
DiscoveredMCPResource,
MessageActionReturn,
} from '@google/gemini-cli-core';
import {
@@ -230,6 +231,13 @@ const listAction = async (
serverNames.includes(prompt.serverName as string),
) as DiscoveredMCPPrompt[];
const resourceRegistry = config.getResourceRegistry();
const mcpResources = resourceRegistry
.getAllResources()
.filter((entry) =>
serverNames.includes(entry.serverName),
) as DiscoveredMCPResource[];
const authStatus: HistoryItemMcpStatus['authStatus'] = {};
const tokenStorage = new MCPOAuthTokenStorage();
for (const serverName of serverNames) {
@@ -265,6 +273,13 @@ const listAction = async (
name: prompt.name,
description: prompt.description,
})),
resources: mcpResources.map((resource) => ({
serverName: resource.serverName,
name: resource.name,
uri: resource.uri,
mimeType: resource.mimeType,
description: resource.description,
})),
authStatus,
blockedServers: blockedMcpServers,
discoveryInProgress,