mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-27 06:15:15 +00:00
feat(mcp): serve an MCP Server Card at /mcp/server-card
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
parent
225fbf0e0c
commit
12f819b1e9
2 changed files with 64 additions and 0 deletions
|
|
@ -42,6 +42,28 @@ describe("MCP — transport & auth (raw HTTP)", () => {
|
|||
expect(body.authorization_servers?.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it("serves an MCP Server Card at the reserved location", async () => {
|
||||
const res = await fetch(`${MCP_URL}/server-card`, {
|
||||
headers: { Accept: "application/mcp-server-card+json" },
|
||||
})
|
||||
expect(res.status).toBe(200)
|
||||
expect(res.headers.get("content-type")).toBe(
|
||||
"application/mcp-server-card+json",
|
||||
)
|
||||
expect(res.headers.get("access-control-allow-origin")).toBe("*")
|
||||
const card = (await res.json()) as {
|
||||
$schema?: string
|
||||
name?: string
|
||||
remotes?: { type?: string; url?: string }[]
|
||||
}
|
||||
expect(card.$schema).toBe(
|
||||
"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
|
||||
)
|
||||
expect(card.name).toMatch(/^[a-zA-Z0-9.-]+\/[a-zA-Z0-9._-]+$/)
|
||||
expect(card.remotes?.[0]).toMatchObject({ type: "streamable-http" })
|
||||
expect(card.remotes?.[0]?.url).toMatch(/\/mcp$/)
|
||||
})
|
||||
|
||||
it("rejects a request with no token (401 + WWW-Authenticate)", async () => {
|
||||
const res = await fetch(MCP_URL, {
|
||||
method: "POST",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import type { AuthInfo } from "@modelcontextprotocol/server"
|
|||
import { createMcpHandler } from "agents/mcp/server"
|
||||
import { Hono, type Context } from "hono"
|
||||
import { cors } from "hono/cors"
|
||||
import { etag } from "hono/etag"
|
||||
import {
|
||||
isApiKey,
|
||||
TransientAuthError,
|
||||
|
|
@ -77,6 +78,47 @@ function resourceMetadata(c: Context<{ Bindings: Bindings }>) {
|
|||
app.get("/.well-known/oauth-protected-resource", resourceMetadata)
|
||||
app.get(PROTECTED_RESOURCE_METADATA_PATH, resourceMetadata)
|
||||
|
||||
app.get("/mcp/server-card", etag(), (c) => {
|
||||
const card = {
|
||||
$schema:
|
||||
"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
|
||||
name: "ai.supermemory/memory",
|
||||
version: "1.0.0",
|
||||
title: "Supermemory",
|
||||
description:
|
||||
"Save, search, and recall a user's memories and documents across AI conversations.",
|
||||
websiteUrl: "https://supermemory.ai/docs/supermemory-mcp/mcp",
|
||||
repository: {
|
||||
url: "https://github.com/supermemoryai/supermemory",
|
||||
source: "github",
|
||||
subfolder: "apps/mcp",
|
||||
},
|
||||
icons: [
|
||||
{
|
||||
src: "https://supermemory.ai/icon-512.png",
|
||||
mimeType: "image/png",
|
||||
sizes: ["512x512"],
|
||||
},
|
||||
{
|
||||
src: "https://supermemory.ai/favicon.svg",
|
||||
mimeType: "image/svg+xml",
|
||||
sizes: ["any"],
|
||||
},
|
||||
],
|
||||
remotes: [
|
||||
{
|
||||
type: "streamable-http",
|
||||
url: c.env.MCP_RESOURCE || DEFAULT_MCP_RESOURCE,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
return c.body(JSON.stringify(card, null, 2), 200, {
|
||||
"Content-Type": "application/mcp-server-card+json",
|
||||
"Cache-Control": "public, max-age=3600",
|
||||
})
|
||||
})
|
||||
|
||||
app.get("/.well-known/openai-apps-challenge", (c) => {
|
||||
return c.text(c.env.OPENAI_APPS_CHALLENGE || "")
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue