test(mcp): cover note tool registration adapter
This commit is contained in:
parent
a10709f33a
commit
2340be157e
61
backend/src/mcp/register-note-tools.test.ts
Normal file
61
backend/src/mcp/register-note-tools.test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
import { NOTES_MCP_TOOL_NAMES } from './note-tool-contracts.js';
|
||||||
|
|
||||||
|
const { executableToolsMock, toolNames } = vi.hoisted(() => ({
|
||||||
|
toolNames: {
|
||||||
|
list: 'notes.notes.list',
|
||||||
|
createDraft: 'notes.notes.create_draft',
|
||||||
|
},
|
||||||
|
executableToolsMock: [
|
||||||
|
{
|
||||||
|
name: 'notes.notes.list',
|
||||||
|
description: 'List notes',
|
||||||
|
requiredRole: 'viewer' as const,
|
||||||
|
inputSchema: { safeParse: vi.fn() },
|
||||||
|
execute: vi.fn(async () => ({ ok: true })),
|
||||||
|
readOnly: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'notes.notes.create_draft',
|
||||||
|
description: 'Create draft',
|
||||||
|
requiredRole: 'admin' as const,
|
||||||
|
inputSchema: { safeParse: vi.fn() },
|
||||||
|
execute: vi.fn(async () => ({ ok: true })),
|
||||||
|
readOnly: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('./note-tools.js', () => ({
|
||||||
|
NotesExecutableMcpTools: executableToolsMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { getNotesMcpToolsForRegistration, registerNotesMcpTools } from './register-note-tools.js';
|
||||||
|
|
||||||
|
describe('register note tools adapter', () => {
|
||||||
|
it('returns a registration-friendly tool list', () => {
|
||||||
|
const tools = getNotesMcpToolsForRegistration();
|
||||||
|
|
||||||
|
expect(tools).toHaveLength(2);
|
||||||
|
expect(tools.map(tool => tool.name)).toEqual([
|
||||||
|
toolNames.list,
|
||||||
|
toolNames.createDraft,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('registers every executable tool through the provided callback', () => {
|
||||||
|
const registerTool = vi.fn();
|
||||||
|
|
||||||
|
registerNotesMcpTools(registerTool);
|
||||||
|
|
||||||
|
expect(registerTool).toHaveBeenCalledTimes(2);
|
||||||
|
expect(registerTool).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
expect.objectContaining({ name: toolNames.list, requiredRole: 'viewer' })
|
||||||
|
);
|
||||||
|
expect(registerTool).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
expect.objectContaining({ name: toolNames.createDraft, requiredRole: 'admin' })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -71,6 +71,7 @@ Parent: `docs/ROADMAP.md`
|
|||||||
- an adapter that exports the note tools in a shape compatible with shared `mcp-server` registration
|
- an adapter that exports the note tools in a shape compatible with shared `mcp-server` registration
|
||||||
- a clear product-side handoff point for future shared-server wiring
|
- a clear product-side handoff point for future shared-server wiring
|
||||||
- backend verification still passing after the adapter layer was introduced
|
- backend verification still passing after the adapter layer was introduced
|
||||||
|
- explicit adapter tests now verify exported tool shape and registration callback coverage
|
||||||
- 2026-03-10 — Product-side MCP hardening advanced:
|
- 2026-03-10 — Product-side MCP hardening advanced:
|
||||||
- executable tools now reject mismatched `productId` scope at runtime
|
- executable tools now reject mismatched `productId` scope at runtime
|
||||||
- regression coverage now asserts mutating calls do not persist when scope is invalid
|
- regression coverage now asserts mutating calls do not persist when scope is invalid
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user