cli / mcp for bitbucket
1import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
3import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4import { afterAll, beforeAll, describe, expect, it } from 'vitest';
5import { registerAllTools } from '../tools';
6
7const EXPECTED_TOOLS = [
8 'list_pull_requests',
9 'get_pull_request',
10 'create_pull_request',
11 'update_pull_request',
12 'decline_pull_request',
13 'get_pull_request_comments',
14 'add_pull_request_comment',
15 'get_pull_request_diff',
16 'list_pipelines',
17 'get_pipeline',
18 'get_pipeline_step_log',
19 'trigger_pipeline',
20 'list_repositories',
21 'list_branches',
22 'get_branch',
23 'create_branch',
24 'delete_branch',
25 'list_commits',
26 'get_commit',
27] as const;
28
29describe('MCP Server integration', () => {
30 let client: Client;
31 let server: McpServer;
32
33 beforeAll(async () => {
34 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
35 server = new McpServer({ name: 'bitbucket-test', version: '0.0.1' });
36 client = new Client({ name: 'test-client', version: '0.0.1' });
37
38 registerAllTools(server);
39
40 await server.connect(serverTransport);
41 await client.connect(clientTransport);
42 });
43
44 afterAll(async () => {
45 await client.close();
46 await server.close();
47 });
48
49 it('starts and responds to tool listing', async () => {
50 const { tools } = await client.listTools();
51 expect(tools.length).toBeGreaterThan(0);
52 });
53
54 it('registers exactly 19 tools', async () => {
55 const { tools } = await client.listTools();
56 expect(tools).toHaveLength(19);
57 });
58
59 it('registers all expected tool names', async () => {
60 const { tools } = await client.listTools();
61 const names = tools.map((t) => t.name).sort();
62 expect(names).toEqual([...EXPECTED_TOOLS].sort());
63 });
64
65 it.each(EXPECTED_TOOLS)('tool "%s" has a description and input schema', async (toolName) => {
66 const { tools } = await client.listTools();
67 const tool = tools.find((t) => t.name === toolName);
68
69 expect(tool).toBeDefined();
70 expect(tool!.description).toBeTruthy();
71 expect(tool!.inputSchema).toBeDefined();
72 expect(tool!.inputSchema.type).toBe('object');
73 });
74});