Files
freee__freee-mcp/scripts/test-mcp.js
T
Hiroki Nakashima 37edff1a74 feat: 開発ツールチェーンを bun に移行 (#283)
* feat: migrate toolchain from pnpm/tsx/esbuild to bun

- Package manager: pnpm → bun (bun install, bun.lock)
- Bundler: esbuild → Bun.build (build.ts rewritten)
- Script execution: tsx → bun (dev, start, scripts)
- Tests: kept vitest (bun:test mock.module has file isolation bugs)
- CI/CD: pnpm/action-setup → oven-sh/setup-bun
- Removed devDependencies: esbuild, tsx
- Built artifact still targets Node.js (#!/usr/bin/env node)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: .mcp.json のコマンドを pnpm から bun に変更

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: 残存していた pnpm/tsx/esbuild 参照を bun に統一

README.md, mcp.json, scripts/, release.yml, .claude/settings.json,
schema-loader.ts, constants.ts のコマンドやコメントを更新。
bun.lock を再生成して不要な eslint/prettier/tsx 依存を削除。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: CI の node-version を .tool-versions から読むように修正

publish.yml, test.yml, release.yml でハードコードされた
node-version を node-version-file: .tool-versions に変更。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:54:41 +09:00

178 lines
4.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* MCP Server 動作確認スクリプト
* freee MCP serverのツールをテストするためのスクリプト
*/
import { spawn } from 'child_process';
import { createInterface } from 'readline';
// MCP メッセージを送信するヘルパー関数
function sendMcpMessage(process, message) {
const jsonMessage = JSON.stringify(message);
console.log(`\n📤 送信: ${jsonMessage}`);
process.stdin.write(jsonMessage + '\n');
}
// MCP リクエストIDを生成
let requestId = 1;
function getNextRequestId() {
return requestId++;
}
async function testMcpTools() {
console.log('🚀 freee MCP Server 動作確認を開始します...\n');
// MCP serverプロセスを起動
const mcpProcess = spawn('bun', ['run', 'src/index.ts'], {
stdio: 'pipe',
cwd: process.cwd()
});
// 標準出力の監視
mcpProcess.stdout.on('data', (data) => {
console.log(`📥 受信: ${data.toString().trim()}`);
});
// 標準エラー出力の監視(ログ用)
mcpProcess.stderr.on('data', (data) => {
console.log(`📋 ログ: ${data.toString().trim()}`);
});
// プロセス終了時の処理
mcpProcess.on('exit', (code) => {
console.log(`\n🏁 MCP Server プロセスが終了しました (コード: ${code})`);
});
// 少し待ってからテスト開始
await new Promise(resolve => setTimeout(resolve, 2000));
console.log('\n=== MCP 初期化テスト ===');
// 1. Initialize request
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'initialize',
params: {
protocolVersion: '2024-11-05',
capabilities: {
tools: {}
},
clientInfo: {
name: 'freee-mcp-test-client',
version: '1.0.0'
}
}
});
await new Promise(resolve => setTimeout(resolve, 1000));
// 2. List tools
console.log('\n=== 利用可能ツール一覧取得 ===');
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'tools/list',
params: {}
});
await new Promise(resolve => setTimeout(resolve, 1000));
// 3. Test freee_list_companies tool
console.log('\n=== freee_list_companies ツールテスト ===');
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'tools/call',
params: {
name: 'freee_list_companies',
arguments: {}
}
});
await new Promise(resolve => setTimeout(resolve, 2000));
// 4. Test freee_auth_status tool
console.log('\n=== freee_auth_status ツールテスト ===');
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'tools/call',
params: {
name: 'freee_auth_status',
arguments: {}
}
});
await new Promise(resolve => setTimeout(resolve, 2000));
// 5. Test freee_current_user tool
console.log('\n=== freee_current_user ツールテスト ===');
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'tools/call',
params: {
name: 'freee_current_user',
arguments: {}
}
});
await new Promise(resolve => setTimeout(resolve, 2000));
// インタラクティブモード
console.log('\n=== インタラクティブモード ===');
console.log('ツール名を入力してテストしてください(例: freee_current_user)');
console.log('終了するには "exit" と入力してください\n');
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
const askForTool = () => {
rl.question('ツール名を入力 > ', (toolName) => {
if (toolName.toLowerCase() === 'exit') {
console.log('\n👋 テスト終了');
mcpProcess.kill();
rl.close();
process.exit(0);
}
if (toolName.trim()) {
console.log(`\n=== ${toolName} ツールテスト ===`);
sendMcpMessage(mcpProcess, {
jsonrpc: '2.0',
id: getNextRequestId(),
method: 'tools/call',
params: {
name: toolName,
arguments: {}
}
});
setTimeout(() => {
askForTool();
}, 2000);
} else {
askForTool();
}
});
};
askForTool();
}
// エラーハンドリング
process.on('uncaughtException', (error) => {
console.error('❌ 未処理の例外:', error);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('❌ 未処理のPromise拒否:', reason);
});
// テスト開始
testMcpTools().catch(console.error);