summaryrefslogtreecommitdiff
path: root/integration-tests/mcp_server_cyclic_schema.test.js
diff options
context:
space:
mode:
authorTommaso Sciortino <[email protected]>2025-08-12 15:57:27 -0700
committerGitHub <[email protected]>2025-08-12 22:57:27 +0000
commit9d023be1d16a6bf7427569f863e6cfd2c3442d8b (patch)
treeb983227f56fd9f26008b475061a345b61207c970 /integration-tests/mcp_server_cyclic_schema.test.js
parent8d6eb8c322890b5cdf20d4a30dd17afb1541f5aa (diff)
Upgrade integration tests to use Vitest (#6021)
Diffstat (limited to 'integration-tests/mcp_server_cyclic_schema.test.js')
-rw-r--r--integration-tests/mcp_server_cyclic_schema.test.js199
1 files changed, 0 insertions, 199 deletions
diff --git a/integration-tests/mcp_server_cyclic_schema.test.js b/integration-tests/mcp_server_cyclic_schema.test.js
deleted file mode 100644
index 1ace98f1..00000000
--- a/integration-tests/mcp_server_cyclic_schema.test.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * @license
- * Copyright 2025 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * This test verifies we can match maximum schema depth errors from Gemini
- * and then detect and warn about the potential tools that caused the error.
- */
-
-import { test, describe, before } from 'node:test';
-import { strict as assert } from 'node:assert';
-import { TestRig } from './test-helper.js';
-import { join } from 'path';
-import { fileURLToPath } from 'url';
-import { writeFileSync } from 'fs';
-
-const __dirname = fileURLToPath(new URL('.', import.meta.url));
-
-// Create a minimal MCP server that doesn't require external dependencies
-// This implements the MCP protocol directly using Node.js built-ins
-const serverScript = `#!/usr/bin/env node
-/**
- * @license
- * Copyright 2025 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-const readline = require('readline');
-const fs = require('fs');
-
-// Debug logging to stderr (only when MCP_DEBUG or VERBOSE is set)
-const debugEnabled = process.env.MCP_DEBUG === 'true' || process.env.VERBOSE === 'true';
-function debug(msg) {
- if (debugEnabled) {
- fs.writeSync(2, \`[MCP-DEBUG] \${msg}\\n\`);
- }
-}
-
-debug('MCP server starting...');
-
-// Simple JSON-RPC implementation for MCP
-class SimpleJSONRPC {
- constructor() {
- this.handlers = new Map();
- this.rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
- terminal: false
- });
-
- this.rl.on('line', (line) => {
- debug(\`Received line: \${line}\`);
- try {
- const message = JSON.parse(line);
- debug(\`Parsed message: \${JSON.stringify(message)}\`);
- this.handleMessage(message);
- } catch (e) {
- debug(\`Parse error: \${e.message}\`);
- }
- });
- }
-
- send(message) {
- const msgStr = JSON.stringify(message);
- debug(\`Sending message: \${msgStr}\`);
- process.stdout.write(msgStr + '\\n');
- }
-
- async handleMessage(message) {
- if (message.method && this.handlers.has(message.method)) {
- try {
- const result = await this.handlers.get(message.method)(message.params || {});
- if (message.id !== undefined) {
- this.send({
- jsonrpc: '2.0',
- id: message.id,
- result
- });
- }
- } catch (error) {
- if (message.id !== undefined) {
- this.send({
- jsonrpc: '2.0',
- id: message.id,
- error: {
- code: -32603,
- message: error.message
- }
- });
- }
- }
- } else if (message.id !== undefined) {
- this.send({
- jsonrpc: '2.0',
- id: message.id,
- error: {
- code: -32601,
- message: 'Method not found'
- }
- });
- }
- }
-
- on(method, handler) {
- this.handlers.set(method, handler);
- }
-}
-
-// Create MCP server
-const rpc = new SimpleJSONRPC();
-
-// Handle initialize
-rpc.on('initialize', async (params) => {
- debug('Handling initialize request');
- return {
- protocolVersion: '2024-11-05',
- capabilities: {
- tools: {}
- },
- serverInfo: {
- name: 'cyclic-schema-server',
- version: '1.0.0'
- }
- };
-});
-
-// Handle tools/list
-rpc.on('tools/list', async () => {
- debug('Handling tools/list request');
- return {
- tools: [{
- name: 'tool_with_cyclic_schema',
- inputSchema: {
- type: 'object',
- properties: {
- data: {
- type: 'array',
- items: {
- type: 'object',
- properties: {
- child: { $ref: '#/properties/data/items' },
- },
- },
- },
- },
- }
- }]
- };
-});
-
-// Send initialization notification
-rpc.send({
- jsonrpc: '2.0',
- method: 'initialized'
-});
-`;
-
-describe('mcp server with cyclic tool schema is detected', () => {
- const rig = new TestRig();
-
- before(async () => {
- // Setup test directory with MCP server configuration
- await rig.setup('cyclic-schema-mcp-server', {
- settings: {
- mcpServers: {
- 'cyclic-schema-server': {
- command: 'node',
- args: ['mcp-server.cjs'],
- },
- },
- },
- });
-
- // Create server script in the test directory
- const testServerPath = join(rig.testDir, 'mcp-server.cjs');
- writeFileSync(testServerPath, serverScript);
-
- // Make the script executable (though running with 'node' should work anyway)
- if (process.platform !== 'win32') {
- const { chmodSync } = await import('fs');
- chmodSync(testServerPath, 0o755);
- }
- });
-
- test('should error and suggest disabling the cyclic tool', async () => {
- // Just run any command to trigger the schema depth error.
- // If this test starts failing, check `isSchemaDepthError` from
- // geminiChat.ts to see if it needs to be updated.
- // Or, possibly it could mean that gemini has fixed the issue.
- const output = await rig.run('hello');
-
- assert.match(
- output,
- /Skipping tool 'tool_with_cyclic_schema' from MCP server 'cyclic-schema-server' because it has missing types in its parameter schema/,
- );
- });
-});