61 lines
2.6 KiB
TypeScript
61 lines
2.6 KiB
TypeScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// The tools this app opts in to, listed by the real mount over the real registry through the official
|
|
// SDK client. The transport's own rules are `@conusai-kit/host/http`'s tests.
|
|
|
|
import { buildRegistry } from "@conusai-kit/core"
|
|
import { createMcpHandler } from "@conusai-kit/host/http"
|
|
import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client"
|
|
import { describe, expect, it, vi } from "vitest"
|
|
import { appModules } from "../modules/index.js"
|
|
|
|
const registry = buildRegistry([...appModules])
|
|
|
|
describe("this app's MCP tools", () => {
|
|
it("are the procedures that opted in, and a tool call goes through the scoped caller", async () => {
|
|
const output = { notes: [], hasMore: false }
|
|
const callByName = vi.fn(async () => output)
|
|
const handle = createMcpHandler({
|
|
registry,
|
|
contextFor: async () => ({
|
|
principal: { method: "bearer", actor: { userId: "user-a" } },
|
|
caller: { callByName } as never,
|
|
}),
|
|
checkCsrf: () => undefined,
|
|
})
|
|
const transport = new StreamableHTTPClientTransport(new URL("https://app.example.test/api/mcp"), {
|
|
fetch: (url, init) => handle(new Request(url, init), "sdk-request"),
|
|
})
|
|
const client = new Client({ name: "app-template-test", version: "1.0.0" }, { versionNegotiation: { mode: "auto" } })
|
|
try {
|
|
await client.connect(transport)
|
|
const listed = await client.listTools()
|
|
// The Agent's workspace reads are tools too: what an MCP client of a workspace can list and open.
|
|
expect(listed.tools.map((tool) => tool.name)).toEqual([
|
|
"agent.run.status", // kit:agent
|
|
"assistant.workspace.openProject", // kit:agent
|
|
"assistant.workspace.projects", // kit:agent
|
|
"knowledge.search", // kit:knowledge
|
|
"notes.note.list",
|
|
])
|
|
expect(listed.tools.find((tool) => tool.name === "notes.note.list")?.inputSchema.required).toEqual([
|
|
"org",
|
|
"workspace",
|
|
"project",
|
|
])
|
|
const result = await client.callTool({
|
|
name: "notes.note.list",
|
|
arguments: { org: "org-a", workspace: "ws-a", project: "project-a" },
|
|
})
|
|
expect(result.structuredContent).toEqual(output)
|
|
} finally {
|
|
await client.close()
|
|
}
|
|
})
|
|
})
|
|
|
|
// This journey requires explicit optional-module admission.
|
|
vi.mock("../modules/inclusion.js", async (importOriginal) => ({
|
|
...(await importOriginal<typeof import("../modules/inclusion.js")>()),
|
|
...(await import("./support/native-readiness.js")).selectedModules(["agent", "knowledge"]),
|
|
}))
|