Skip to content

Commit 8437ce9

Browse files
authored
Revert "Update extension examples" (#16442)
1 parent 7d92242 commit 8437ce9

13 files changed

Lines changed: 157 additions & 84 deletions

File tree

eslint.config.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,16 +301,6 @@ export default tseslint.config(
301301
'@typescript-eslint/no-require-imports': 'off',
302302
},
303303
},
304-
// Examples should have access to standard globals like fetch
305-
{
306-
files: ['packages/cli/src/commands/extensions/examples/**/*.js'],
307-
languageOptions: {
308-
globals: {
309-
...globals.node,
310-
fetch: 'readonly',
311-
},
312-
},
313-
},
314304
// extra settings for scripts that we run directly with node
315305
{
316306
files: ['packages/vscode-ide-companion/scripts/**/*.js'],

packages/cli/src/commands/extensions/examples/hooks/gemini-extension.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/cli/src/commands/extensions/examples/hooks/hooks/hooks.json

Lines changed: 0 additions & 14 deletions
This file was deleted.

packages/cli/src/commands/extensions/examples/hooks/scripts/on-start.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

packages/cli/src/commands/extensions/examples/mcp-server/README.md

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10+
import { z } from 'zod';
11+
12+
// Mock the MCP server and transport
13+
const mockRegisterTool = vi.fn();
14+
const mockRegisterPrompt = vi.fn();
15+
const mockConnect = vi.fn();
16+
17+
vi.mock('@modelcontextprotocol/sdk/server/mcp.js', () => ({
18+
McpServer: vi.fn().mockImplementation(() => ({
19+
registerTool: mockRegisterTool,
20+
registerPrompt: mockRegisterPrompt,
21+
connect: mockConnect,
22+
})),
23+
}));
24+
25+
vi.mock('@modelcontextprotocol/sdk/server/stdio.js', () => ({
26+
StdioServerTransport: vi.fn(),
27+
}));
28+
29+
describe('MCP Server Example', () => {
30+
beforeEach(async () => {
31+
// Dynamically import the server setup after mocks are in place
32+
await import('./example.js');
33+
});
34+
35+
afterEach(() => {
36+
vi.clearAllMocks();
37+
vi.resetModules();
38+
});
39+
40+
it('should create an McpServer with the correct name and version', () => {
41+
expect(McpServer).toHaveBeenCalledWith({
42+
name: 'prompt-server',
43+
version: '1.0.0',
44+
});
45+
});
46+
47+
it('should register the "fetch_posts" tool', () => {
48+
expect(mockRegisterTool).toHaveBeenCalledWith(
49+
'fetch_posts',
50+
{
51+
description: 'Fetches a list of posts from a public API.',
52+
inputSchema: z.object({}).shape,
53+
},
54+
expect.any(Function),
55+
);
56+
});
57+
58+
it('should register the "poem-writer" prompt', () => {
59+
expect(mockRegisterPrompt).toHaveBeenCalledWith(
60+
'poem-writer',
61+
{
62+
title: 'Poem Writer',
63+
description: 'Write a nice haiku',
64+
argsSchema: expect.any(Object),
65+
},
66+
expect.any(Function),
67+
);
68+
});
69+
70+
it('should connect the server to an StdioServerTransport', () => {
71+
expect(StdioServerTransport).toHaveBeenCalled();
72+
expect(mockConnect).toHaveBeenCalledWith(expect.any(StdioServerTransport));
73+
});
74+
75+
describe('fetch_posts tool implementation', () => {
76+
it('should fetch posts and return a formatted response', async () => {
77+
const mockPosts = [
78+
{ id: 1, title: 'Post 1' },
79+
{ id: 2, title: 'Post 2' },
80+
];
81+
global.fetch = vi.fn().mockResolvedValue({
82+
json: vi.fn().mockResolvedValue(mockPosts),
83+
});
84+
85+
const toolFn = mockRegisterTool.mock.calls[0][2];
86+
const result = await toolFn();
87+
88+
expect(global.fetch).toHaveBeenCalledWith(
89+
'https://jsonplaceholder.typicode.com/posts',
90+
);
91+
expect(result).toEqual({
92+
content: [
93+
{
94+
type: 'text',
95+
text: JSON.stringify({ posts: mockPosts }),
96+
},
97+
],
98+
});
99+
});
100+
});
101+
102+
describe('poem-writer prompt implementation', () => {
103+
it('should generate a prompt with a title', () => {
104+
const promptFn = mockRegisterPrompt.mock.calls[0][2];
105+
const result = promptFn({ title: 'My Poem' });
106+
expect(result).toEqual({
107+
messages: [
108+
{
109+
role: 'user',
110+
content: {
111+
type: 'text',
112+
text: 'Write a haiku called My Poem. Note that a haiku is 5 syllables followed by 7 syllables followed by 5 syllables ',
113+
},
114+
},
115+
],
116+
});
117+
});
118+
119+
it('should generate a prompt with a title and mood', () => {
120+
const promptFn = mockRegisterPrompt.mock.calls[0][2];
121+
const result = promptFn({ title: 'My Poem', mood: 'sad' });
122+
expect(result).toEqual({
123+
messages: [
124+
{
125+
role: 'user',
126+
content: {
127+
type: 'text',
128+
text: 'Write a haiku with the mood sad called My Poem. Note that a haiku is 5 syllables followed by 7 syllables followed by 5 syllables ',
129+
},
130+
},
131+
],
132+
});
133+
});
134+
});
135+
});

packages/cli/src/commands/extensions/examples/mcp-server/example.js renamed to packages/cli/src/commands/extensions/examples/mcp-server/example.ts

File renamed without changes.

packages/cli/src/commands/extensions/examples/mcp-server/gemini-extension.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"mcpServers": {
55
"nodeServer": {
66
"command": "node",
7-
"args": ["${extensionPath}${/}example.js"],
7+
"args": ["${extensionPath}${/}dist${/}example.js"],
88
"cwd": "${extensionPath}"
99
}
1010
}

packages/cli/src/commands/extensions/examples/mcp-server/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
"description": "Example MCP Server for Gemini CLI Extension",
55
"type": "module",
66
"main": "example.js",
7+
"scripts": {
8+
"build": "tsc"
9+
},
10+
"devDependencies": {
11+
"typescript": "~5.4.5",
12+
"@types/node": "^20.11.25"
13+
},
714
"dependencies": {
815
"@modelcontextprotocol/sdk": "^1.23.0",
916
"zod": "^3.22.4"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "NodeNext",
5+
"moduleResolution": "NodeNext",
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"skipLibCheck": true,
9+
"forceConsistentCasingInFileNames": true,
10+
"outDir": "./dist"
11+
},
12+
"include": ["example.ts"]
13+
}

0 commit comments

Comments
 (0)