| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import { describe, expect, it, vi } from "vitest"
- import { buildMcpRuntime, defaultUnavailableMcpCaller } from "./runtime"
- import type { McpConfig } from "./config"
- import type { McpToolDescriptor } from "./types"
- function descriptor(operation: McpToolDescriptor["operation"], name = "query_graph"): McpToolDescriptor {
- return {
- serverId: "graph",
- serverName: "Knowledge Graph",
- name,
- description: "Query graph",
- operation,
- inputSchema: {
- type: "object",
- properties: { query: { type: "string", description: "Query" } },
- required: ["query"],
- },
- }
- }
- describe("buildMcpRuntime", () => {
- it("ignores disabled servers", () => {
- const config: McpConfig = {
- servers: [{ id: "graph", name: "Graph", enabled: false, tools: [descriptor("read")] }],
- }
- const runtime = buildMcpRuntime(config)
- expect(runtime.mcpTools).toEqual([])
- expect(runtime.mcpCapabilities).toEqual([])
- expect(runtime.warnings).toEqual([])
- })
- it("builds tools and capabilities for enabled read and analysis MCP descriptors", () => {
- const config: McpConfig = {
- servers: [{
- id: "graph",
- name: "Graph",
- enabled: true,
- tools: [descriptor("read"), descriptor("analysis", "analyze_relation")],
- }],
- }
- const runtime = buildMcpRuntime(config)
- expect(runtime.mcpTools.map((tool) => tool.name)).toEqual([
- "mcp_graph_query_graph",
- "mcp_graph_analyze_relation",
- ])
- expect(runtime.mcpCapabilities).toContainEqual(expect.objectContaining({
- kind: "mcp_tool",
- toolName: "mcp_graph_query_graph",
- source: "mcp",
- }))
- expect(runtime.mcpCapabilities).toContainEqual(expect.objectContaining({
- kind: "mcp_tool",
- toolName: "mcp_graph_analyze_relation",
- source: "mcp",
- }))
- })
- it("rejects destructive and unsupported MCP descriptors with Chinese warnings", () => {
- const badSchema: McpToolDescriptor = {
- ...descriptor("read", "bad"),
- inputSchema: {
- type: "object",
- properties: { cb: { type: "function" } },
- },
- }
- const config: McpConfig = {
- servers: [{
- id: "graph",
- name: "Graph",
- enabled: true,
- tools: [descriptor("delete"), descriptor("overwrite"), badSchema],
- }],
- }
- const runtime = buildMcpRuntime(config)
- expect(runtime.mcpTools).toEqual([])
- expect(runtime.mcpCapabilities).toEqual([])
- expect(runtime.warnings.join("\n")).toContain("MCP")
- expect(runtime.warnings.join("\n")).toContain("未启用")
- })
- it("default caller returns Chinese unavailable degradation", async () => {
- const result = await defaultUnavailableMcpCaller({
- serverId: "graph",
- serverName: "Knowledge Graph",
- toolName: "query_graph",
- qmaiToolName: "mcp_graph_query_graph",
- }, { query: "主角关系" })
- expect(result.status).toBe("error")
- expect(result.message).toContain("MCP")
- expect(result.message).toContain("未连接")
- })
- it("server 配置 command 且提供 realConnector 时使用真实 caller", async () => {
- const realCaller = vi.fn(async () => ({
- status: "ok" as const,
- content: "真实结果",
- summary: "真实结果",
- }))
- const config: McpConfig = {
- servers: [{
- id: "graph",
- name: "Graph",
- enabled: true,
- command: "node",
- tools: [descriptor("read")],
- }],
- }
- const runtime = buildMcpRuntime(config, defaultUnavailableMcpCaller, { caller: realCaller } as any)
- await runtime.mcpTools[0].execute({ query: "主角" })
- expect(realCaller).toHaveBeenCalledWith(
- expect.objectContaining({ serverId: "graph", toolName: "query_graph" }),
- { query: "主角" },
- undefined,
- )
- })
- })
|