supermemory/apps/mcp/e2e/discovery.test.ts
MaheshtheDev 9808441f6b test(mcp): add deployed-server e2e suite (#1057)
End-to-end tests that drive the deployed Supermemory MCP over streamable HTTP (no mocks):

- discovery: handshake + tool/resource/prompt listing
- identity: whoAmI, listProjects
- memory: save -> recall round-trip, profile variants, forget, container scoping
- graph/resources/prompts: memory-graph, fetch-graph-data, profile/projects, context
- oauth: protected-resource discovery chain, dynamic client registration,
token-endpoint negatives, and a real refresh -> access token round-trip
- auth: GET / info, 401 on missing/invalid token
- root-scope: x-sm-project scoping behavior

Tests skip without SUPERMEMORY_API_KEY (OAuth tier-D skips without its token env vars) so CI is safe without secrets. Adds vitest + a test:e2e script and documents running + the OAuth flow in apps/mcp/README.md.
2026-06-07 04:30:17 +00:00

52 lines
1.5 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from "vitest"
import { API_KEY, callTool, connect, textOf, type Session } from "./helpers"
const EXPECTED_TOOLS = [
"memory",
"recall",
"listProjects",
"whoAmI",
"memory-graph",
]
describe.skipIf(!API_KEY)("MCP — discovery & identity", () => {
let s: Session
beforeAll(async () => {
s = await connect()
})
afterAll(async () => {
await s?.close()
})
it("handshakes and lists the expected tools", async () => {
const { tools } = await s.client.listTools()
const names = tools.map((t) => t.name)
for (const t of EXPECTED_TOOLS) expect(names).toContain(t)
})
it("lists profile & projects resources", async () => {
const { resources } = await s.client.listResources()
const uris = resources.map((r) => r.uri)
expect(uris).toContain("supermemory://profile")
expect(uris).toContain("supermemory://projects")
})
it("lists the context prompt", async () => {
const { prompts } = await s.client.listPrompts()
expect(prompts.map((p) => p.name)).toContain("context")
})
it("whoAmI resolves to the authenticated account", async () => {
const res = await callTool(s.client, "whoAmI")
expect(res.isError).toBeFalsy()
const parsed = JSON.parse(textOf(res))
expect(parsed.userId).toBeTruthy()
})
it("listProjects returns content", async () => {
const res = await callTool(s.client, "listProjects", { refresh: true })
expect(res.isError).toBeFalsy()
expect(textOf(res).length).toBeGreaterThan(0)
})
})