supermemory/apps/mcp/e2e/graph.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

59 lines
1.9 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from "vitest"
import { API_KEY, callTool, connect, type Session, textOf } from "./helpers"
describe.skipIf(!API_KEY)("MCP — graph, resources & prompts", () => {
let s: Session
beforeAll(async () => {
s = await connect()
})
afterAll(async () => {
await s?.close()
})
it("memory-graph returns a summary + structured documents", async () => {
const res = await callTool(s.client, "memory-graph")
expect(res.isError).toBeFalsy()
expect(textOf(res)).toMatch(/Memory Graph: \d+ documents/)
const sc = res.structuredContent as {
documents?: unknown[]
totalCount?: number
}
expect(Array.isArray(sc?.documents)).toBe(true)
})
it("fetch-graph-data returns paginated documents", async () => {
const res = await callTool(s.client, "fetch-graph-data", {
page: 1,
limit: 5,
})
expect(res.isError).toBeFalsy()
const sc = res.structuredContent as {
documents?: unknown[]
pagination?: { limit?: number }
}
expect(Array.isArray(sc?.documents)).toBe(true)
expect(sc?.pagination?.limit).toBe(5)
})
it("reads the profile resource", async () => {
const res = await s.client.readResource({ uri: "supermemory://profile" })
expect(res.contents.length).toBeGreaterThan(0)
expect(res.contents[0].mimeType).toBe("text/plain")
expect(typeof res.contents[0].text).toBe("string")
})
it("reads the projects resource as JSON", async () => {
const res = await s.client.readResource({ uri: "supermemory://projects" })
const text = res.contents[0].text as string
const parsed = JSON.parse(text)
expect(Array.isArray(parsed.projects)).toBe(true)
})
it("gets the context prompt as a system message", async () => {
const res = await s.client.getPrompt({ name: "context", arguments: {} })
expect(res.messages.length).toBeGreaterThan(0)
const text = res.messages[0].content.text as string
expect(text).toMatch(/memory|context/i)
})
})