diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 3f8a95f..d6689ed 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "parseable", "displayName": "Parseable", - "version": "0.2.14", + "version": "0.2.15", "description": "Query and manage Parseable logs, metrics, datasets, and alerts from Cursor.", "author": { "name": "Parseable" @@ -20,10 +20,6 @@ "mcp" ], "category": "developer-tools", - "tags": [ - "observability", - "monitoring", - "mcp" - ], + "tags": ["observability", "monitoring", "mcp"], "mcpServers": "./mcp.json" } diff --git a/package.json b/package.json index 467fa43..12e9c4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@parseable/parseable-mcp-server", - "version": "0.2.14", + "version": "0.2.15", "mcpName": "io.github.parseablehq/parseable-mcp-server", "description": "Model Context Protocol server for Parseable. Lets LLMs discover and query Parseable datasets.", "repository": { diff --git a/server.json b/server.json index b43a4e9..6d5b4c1 100644 --- a/server.json +++ b/server.json @@ -6,12 +6,12 @@ "url": "https://github.com/parseablehq/parseable-mcp-server", "source": "github" }, - "version": "0.2.14", + "version": "0.2.15", "packages": [ { "registryType": "npm", "identifier": "@parseable/parseable-mcp-server", - "version": "0.2.14", + "version": "0.2.15", "transport": { "type": "stdio" } diff --git a/src/bootstrap.ts b/src/bootstrap.ts index 2b65314..765c0ae 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -5,7 +5,7 @@ import { tools } from "./tools/index.js"; import type { ToolContext } from "./tools/types.js"; import { errorResult, jsonResult } from "./tools/types.js"; -const SERVER_VERSION = "0.2.14"; +const SERVER_VERSION = "0.2.15"; export function buildMcpServer(ctx: ToolContext): McpServer { const server = new McpServer({ diff --git a/src/http.ts b/src/http.ts index f36216b..81561e7 100644 --- a/src/http.ts +++ b/src/http.ts @@ -88,6 +88,18 @@ app.get("/assets/*", async (c) => { app.get("/", serveRoot); +// Streamable HTTP clients probe GET /mcp for an optional standalone SSE stream. +// This server is stateless and POST-only, so the MCP transport requires 405 +// rather than 404 to signal that clients should continue without that stream. +app.get( + "/mcp", + () => + new Response(null, { + status: 405, + headers: { Allow: "POST" }, + }), +); + async function buildApiKeyClient(reqHeaders: Headers): Promise<{ client: ParseableClient; config: Config; diff --git a/test/http.test.ts b/test/http.test.ts index 3dc7ba6..8e3aca1 100644 --- a/test/http.test.ts +++ b/test/http.test.ts @@ -45,6 +45,14 @@ describe("HTTP routes", () => { expect(body).toMatch(/X-Parseable-URL/); }); + it("GET /mcp returns 405 for stateless Streamable HTTP clients", async () => { + const res = await app.request("/mcp", { + headers: { accept: "text/event-stream" }, + }); + expect(res.status).toBe(405); + expect(res.headers.get("allow")).toBe("POST"); + }); + it("POST /mcp without auth returns 401", async () => { const res = await app.fetch( new Request("http://localhost/mcp", {