Skip to main content
Glama
index.ts3.28 kB
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import express from "express"; import { createWhoopMcpServer } from "./src/server"; const app = express(); app.use(express.json()); app.post("/mcp", async (req, res) => { // Extract config from query parameters (Smithery passes configSchema values as query params) const whoopEmail = (req.query.whoopEmail as string) || process.env.WHOOP_EMAIL; const whoopPassword = (req.query.whoopPassword as string) || process.env.WHOOP_PASSWORD; const mcpAuthToken = (req.query.mcpAuthToken as string) || process.env.MCP_AUTH_TOKEN; // Validate required credentials if (!whoopEmail || !whoopPassword) { return res.status(400).json({ error: "Bad Request", message: "whoopEmail and whoopPassword are required (via query params or environment variables)", }); } // Optional authentication check if (mcpAuthToken) { const authHeader = req.headers.authorization; if (!authHeader) { return res.status(401).json({ error: "Unauthorized", message: "Authorization header is required", }); } const [scheme, token] = authHeader.split(" "); if (scheme !== "Bearer" || !token) { return res.status(401).json({ error: "Unauthorized", message: "Invalid authorization format. Use 'Bearer <token>'", }); } if (token !== mcpAuthToken) { return res.status(401).json({ error: "Unauthorized", message: "Invalid authentication token", }); } } // Create server instance with credentials from query params or env vars const server = createWhoopMcpServer({ email: whoopEmail, password: whoopPassword, }); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true, }); res.on("close", () => { transport.close(); }); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); const port = parseInt(process.env.PORT || "3000"); app .listen(port, () => { console.log(`Whoop MCP Server running on http://localhost:${port}/mcp`); console.log( `\nConfiguration: Credentials and auth token should be provided via query parameters` ); console.log(` - whoopEmail: Required`); console.log(` - whoopPassword: Required`); console.log( ` - mcpAuthToken: Optional (enables Bearer token authentication)` ); console.log(`\nAlternatively, use environment variables:`); console.log(` - WHOOP_EMAIL`); console.log(` - WHOOP_PASSWORD`); console.log(` - MCP_AUTH_TOKEN`); console.log(`\nAvailable tools:`); console.log( ` - whoop_get_overview: Comprehensive overview with metrics, activities & stats` ); console.log(` - whoop_get_sleep: Detailed sleep analysis and performance`); console.log( ` - whoop_get_recovery: Recovery score with HRV, RHR & trends` ); console.log( ` - whoop_get_strain: Strain score with HR zones & activities` ); console.log(` - whoop_get_healthspan: Biological age & pace of aging`); }) .on("error", (error) => { console.error("Server error:", error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JedPattersonn/whoop-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server