|
5 | 5 |
|
6 | 6 | import { expect } from 'chai' |
7 | 7 | import * as sinon from 'sinon' |
8 | | -import { McpManager } from './mcpManager' |
| 8 | +import { AGENT_TOOLS_CHANGED, MCP_SERVER_STATUS_CHANGED, McpManager } from './mcpManager' |
9 | 9 | import * as mcpUtils from './mcpUtils' |
10 | | -import type { MCPServerConfig } from './mcpTypes' |
| 10 | +import type { MCPServerConfig, MCPServerPermissionUpdate } from './mcpTypes' |
11 | 11 | import { Client } from '@modelcontextprotocol/sdk/client/index.js' |
12 | 12 |
|
13 | 13 | // Shared fakes |
@@ -484,6 +484,97 @@ describe('getEnabledTools()', () => { |
484 | 484 | expect(mgr.getAllTools()).to.have.length(1) |
485 | 485 | expect(mgr.getEnabledTools()).to.be.empty |
486 | 486 | }) |
| 487 | + |
| 488 | + it('server-level permission change (enabled->disabled)', async () => { |
| 489 | + const cfg = { |
| 490 | + command: 'c', |
| 491 | + args: [], |
| 492 | + env: {}, |
| 493 | + disabled: false, |
| 494 | + autoApprove: false, |
| 495 | + toolOverrides: {}, |
| 496 | + __configPath__: 'srv.json', |
| 497 | + } as MCPServerConfig |
| 498 | + loadStub.resolves(new Map([['srv', cfg]])) |
| 499 | + const mgr = await McpManager.init(['srv.json'], features) |
| 500 | + const client = new Client({ name: 'x', version: 'v' }) |
| 501 | + ;(mgr as any).clients.set('srv', client) |
| 502 | + ;(mgr as any).mcpTools.push({ serverName: 'srv', toolName: 'tool1', description: '', inputSchema: {} }) |
| 503 | + |
| 504 | + const statusEvents: any[] = [] |
| 505 | + mgr.events.on(MCP_SERVER_STATUS_CHANGED, (_, s) => statusEvents.push(s)) |
| 506 | + const toolsEvents: any[] = [] |
| 507 | + mgr.events.on(AGENT_TOOLS_CHANGED, (_, t) => toolsEvents.push(t)) |
| 508 | + |
| 509 | + const closeSpy = sinon.spy(client, 'close') |
| 510 | + await mgr.updateServerPermission('srv', { disabled: true } as MCPServerPermissionUpdate) |
| 511 | + |
| 512 | + expect(closeSpy.calledOnce).to.be.true |
| 513 | + expect(statusEvents).to.deep.equal([{ status: 'DISABLED', toolsCount: 0, lastError: undefined }]) |
| 514 | + expect(toolsEvents).to.deep.equal([[]]) |
| 515 | + }) |
| 516 | + |
| 517 | + it('server-level permission change (disabled->enabled)', async () => { |
| 518 | + const cfg = { |
| 519 | + command: 'c', |
| 520 | + args: [], |
| 521 | + env: {}, |
| 522 | + disabled: true, |
| 523 | + autoApprove: false, |
| 524 | + toolOverrides: {}, |
| 525 | + __configPath__: 'srv2.json', |
| 526 | + } as MCPServerConfig |
| 527 | + loadStub.resolves(new Map([['srv2', cfg]])) |
| 528 | + const mgr = await McpManager.init([], features) |
| 529 | + ;(mgr as any).mcpServers.set('srv2', cfg) |
| 530 | + |
| 531 | + await mgr.updateServerPermission('srv2', { disabled: false } as MCPServerPermissionUpdate) |
| 532 | + expect(initOneStub.calledOnceWith('srv2')).to.be.true |
| 533 | + }) |
| 534 | + |
| 535 | + it('disables individual tool-level permission and filters tool list', async () => { |
| 536 | + const cfg = { |
| 537 | + command: 'c', |
| 538 | + args: [], |
| 539 | + env: {}, |
| 540 | + disabled: false, |
| 541 | + autoApprove: false, |
| 542 | + toolOverrides: {}, |
| 543 | + __configPath__: 'srv3.json', |
| 544 | + } as MCPServerConfig |
| 545 | + loadStub.resolves(new Map([['srv3', cfg]])) |
| 546 | + const mgr = await McpManager.init(['srv3.json'], features) |
| 547 | + ;(mgr as any).mcpTools = [{ serverName: 'srv3', toolName: 'toolA', description: '', inputSchema: {} }] |
| 548 | + |
| 549 | + const toolsEvents: any[] = [] |
| 550 | + mgr.events.on(AGENT_TOOLS_CHANGED, (_, t) => toolsEvents.push(t)) |
| 551 | + await mgr.updateServerPermission('srv3', { toolOverrides: { toolA: { disabled: true } } }) |
| 552 | + |
| 553 | + expect(toolsEvents[0]).to.deep.equal([]) |
| 554 | + }) |
| 555 | + |
| 556 | + it('re-enables individual tool-level permission and restores tool', async () => { |
| 557 | + const cfg = { |
| 558 | + command: 'c', |
| 559 | + args: [], |
| 560 | + env: {}, |
| 561 | + disabled: false, |
| 562 | + autoApprove: false, |
| 563 | + toolOverrides: { toolB: { disabled: true } }, |
| 564 | + __configPath__: 'srv4.json', |
| 565 | + } as MCPServerConfig |
| 566 | + loadStub.resolves(new Map([['srv4', cfg]])) |
| 567 | + const mgr = await McpManager.init(['srv4.json'], features) |
| 568 | + ;(mgr as any).mcpTools = [{ serverName: 'srv4', toolName: 'toolB', description: '', inputSchema: {} }] |
| 569 | + |
| 570 | + const toolsEvents: any[] = [] |
| 571 | + mgr.events.on(AGENT_TOOLS_CHANGED, (_, t) => toolsEvents.push(t)) |
| 572 | + await mgr.updateServerPermission('srv4', { toolOverrides: { toolB: { disabled: false } } }) |
| 573 | + |
| 574 | + expect(toolsEvents[0]).to.deep.equal([ |
| 575 | + { serverName: 'srv4', toolName: 'toolB', description: '', inputSchema: {} }, |
| 576 | + ]) |
| 577 | + }) |
487 | 578 | }) |
488 | 579 |
|
489 | 580 | // getAllToolsWithStates() |
|
0 commit comments