{"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/examples/custom-routes.cjs","../../src/examples/custom-routes.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fastmcp/fastmcp/dist/examples/custom-routes.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\n/**\n * Example FastMCP server demonstrating custom HTTP routes using Hono's native API.\n *\n * This example shows how to:\n * - Use getApp() to access Hono's native API\n * - Add REST API endpoints with Hono's standard methods (app.get(), app.post(), etc.)\n * - Implement authentication with a custom helper function\n * - Handle file uploads\n * - Serve admin interfaces\n * - Create webhooks\n * - OAuth discovery endpoints\n * - Integrate custom routes with MCP tools\n *\n * Run with:\n *   npx fastmcp dev src/examples/custom-routes.ts\n *   npx fastmcp inspect src/examples/custom-routes.ts\n *\n * Or directly:\n *   node dist/examples/custom-routes.js --transport=http-stream --port=8080\n */\n\nimport type { Context } from \"hono\";\n\nimport { z } from \"zod\";\n\nimport { FastMCP } from \"../FastMCP.js\";\n\n// Example in-memory data store\ninterface User {\n  email: string;\n  id: string;\n  name: string;\n}\n\nconst users = new Map<string, User>([\n  [\"1\", { email: \"alice@example.com\", id: \"1\", name: \"Alice\" }],\n  [\"2\", { email: \"bob@example.com\", id: \"2\", name: \"Bob\" }],\n]);\n\nlet requestCount = 0;\n\n// Simple authentication for demonstration\ninterface UserAuth {\n  [key: string]: unknown;\n  role: string;\n  userId: string;\n}\n\n// Create the FastMCP server with authentication\nconst server = new FastMCP<UserAuth>({\n  // Simple authentication - in production, use proper tokens/JWTs\n  authenticate: async (req) => {\n    const authHeader = req.headers.authorization;\n    if (authHeader === \"Bearer admin-token\") {\n      return { role: \"admin\", userId: \"admin\" };\n    } else if (authHeader === \"Bearer user-token\") {\n      return { role: \"user\", userId: \"user1\" };\n    }\n    throw new Error(\"Invalid or missing authentication\");\n  },\n  name: \"custom-routes-example\",\n  version: \"1.0.0\",\n});\n\n// Get the Hono app instance for direct access to Hono's native API\nconst app = server.getApp();\n\n// Helper to get authentication from Node.js request\nconst getAuth = async (c: Context): Promise<null | UserAuth> => {\n  const req = c.env.incoming;\n  const authHeader = req.headers.authorization;\n  if (authHeader === \"Bearer admin-token\") {\n    return { role: \"admin\", userId: \"admin\" };\n  } else if (authHeader === \"Bearer user-token\") {\n    return { role: \"user\", userId: \"user1\" };\n  }\n  return null;\n};\n\n// ===== PUBLIC ROUTES (No Authentication Required) =====\n\n// OAuth discovery endpoint - public by design\napp.get(\"/.well-known/openid-configuration\", async (c) => {\n  return c.json({\n    authorization_endpoint: \"https://example.com/oauth/authorize\",\n    issuer: \"https://example.com\",\n    jwks_uri: \"https://example.com/.well-known/jwks.json\",\n    response_types_supported: [\"code\"],\n    scopes_supported: [\"openid\", \"profile\", \"email\"],\n    subject_types_supported: [\"public\"],\n    token_endpoint: \"https://example.com/oauth/token\",\n  });\n});\n\n// OAuth protected resource metadata - also public\napp.get(\"/.well-known/oauth-protected-resource\", async (c) => {\n  return c.json({\n    authorizationServers: [\"https://example.com\"],\n    resource: \"https://example.com/api\",\n    scopesSupported: [\"read\", \"write\"],\n  });\n});\n\n// Public status endpoint - no auth needed\napp.get(\"/status\", async (c) => {\n  return c.json({\n    message: \"Server is running\",\n    status: \"healthy\",\n    timestamp: new Date().toISOString(),\n    version: \"1.0.0\",\n  });\n});\n\n// Public documentation endpoint\napp.get(\"/docs\", async (c) => {\n  const html = `\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <title>API Documentation</title>\n      <style>\n        body { font-family: sans-serif; margin: 40px; line-height: 1.6; }\n        h1, h2 { color: #333; }\n        .endpoint { background: #f8f9fa; padding: 15px; margin: 10px 0; border-left: 4px solid #007bff; }\n        .method { font-weight: bold; color: #28a745; }\n        .auth-required { color: #dc3545; font-size: 0.9em; }\n        .public { color: #6c757d; font-size: 0.9em; }\n      </style>\n    </head>\n    <body>\n      <h1>Custom Routes API Documentation</h1>\n\n      <h2>Public Endpoints (No Authentication)</h2>\n      <div class=\"endpoint\">\n        <span class=\"method\">GET</span> <code>/status</code>\n        <div class=\"public\">✓ Public - Server health status</div>\n      </div>\n      <div class=\"endpoint\">\n        <span class=\"method\">GET</span> <code>/.well-known/openid-configuration</code>\n        <div class=\"public\">✓ Public - OAuth discovery</div>\n      </div>\n\n      <h2>Private Endpoints (Authentication Required)</h2>\n      <div class=\"endpoint\">\n        <span class=\"method\">GET</span> <code>/api/users</code>\n        <div class=\"auth-required\">🔒 Requires: Bearer token</div>\n      </div>\n      <div class=\"endpoint\">\n        <span class=\"method\">GET</span> <code>/admin</code>\n        <div class=\"auth-required\">🔒 Requires: admin token</div>\n      </div>\n\n      <h2>Authentication</h2>\n      <p>Use one of these tokens in the Authorization header:</p>\n      <ul>\n        <li><code>Bearer admin-token</code> - Admin access</li>\n        <li><code>Bearer user-token</code> - User access</li>\n      </ul>\n\n      <h2>Examples</h2>\n      <pre>\n# Public endpoint (no auth needed)\ncurl http://localhost:8080/status\n\n# Private endpoint (auth required)\ncurl -H \"Authorization: Bearer user-token\" http://localhost:8080/api/users\n      </pre>\n    </body>\n    </html>\n  `;\n  return c.html(html);\n});\n\n// Public static assets\napp.get(\"/public/*\", async (c) => {\n  // In a real app, you'd serve actual files here\n  return c.json({\n    file: c.req.url,\n    message: \"This would serve static files\",\n    public: true,\n  });\n});\n\n// ===== PRIVATE ROUTES (Authentication Required) =====\n\n// Add custom routes for a REST API\napp.get(\"/api/users\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const userList = Array.from(users.values());\n  return c.json({\n    authenticated_as: auth.userId,\n    count: userList.length,\n    role: auth.role,\n    users: userList,\n  });\n});\n\napp.get(\"/api/users/:id\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const id = c.req.param(\"id\");\n  const user = users.get(id);\n  if (!user) {\n    return c.json({ error: \"User not found\" }, 404);\n  }\n  return c.json(user);\n});\n\napp.post(\"/api/users\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const body = (await c.req.json()) as { email: string; name: string };\n\n  if (!body.name || !body.email) {\n    return c.json({ error: \"Name and email are required\" }, 400);\n  }\n\n  const id = String(users.size + 1);\n  const newUser: User = {\n    email: body.email,\n    id,\n    name: body.name,\n  };\n\n  users.set(id, newUser);\n  return c.json(newUser, 201);\n});\n\napp.put(\"/api/users/:id\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const id = c.req.param(\"id\");\n  const user = users.get(id);\n  if (!user) {\n    return c.json({ error: \"User not found\" }, 404);\n  }\n\n  const body = (await c.req.json()) as Partial<User>;\n  const updatedUser = { ...user, ...body, id: user.id };\n  users.set(user.id, updatedUser);\n  return c.json(updatedUser);\n});\n\napp.delete(\"/api/users/:id\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const id = c.req.param(\"id\");\n  if (!users.has(id)) {\n    return c.json({ error: \"User not found\" }, 404);\n  }\n\n  users.delete(id);\n  return c.body(null, 204);\n});\n\n// Add a simple admin dashboard - requires admin role\napp.get(\"/admin\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  // Check for admin role\n  if (auth.role !== \"admin\") {\n    return c.json({ error: \"Admin access required\" }, 403);\n  }\n\n  const html = `\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <title>Admin Dashboard</title>\n      <style>\n        body { font-family: sans-serif; margin: 40px; }\n        h1 { color: #333; }\n        .stats { background: #f0f0f0; padding: 20px; border-radius: 8px; }\n        .stat { margin: 10px 0; }\n      </style>\n    </head>\n    <body>\n      <h1>Admin Dashboard</h1>\n      <div class=\"stats\">\n        <div class=\"stat\">Total Users: ${users.size}</div>\n        <div class=\"stat\">Request Count: ${requestCount}</div>\n        <div class=\"stat\">Server Time: ${new Date().toISOString()}</div>\n      </div>\n      <h2>Users</h2>\n      <ul>\n        ${Array.from(users.values())\n          .map((u) => `<li>${u.name} (${u.email})</li>`)\n          .join(\"\")}\n      </ul>\n    </body>\n    </html>\n  `;\n  return c.html(html);\n});\n\n// Add a webhook endpoint\napp.post(\"/webhook/github\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  const payload = await c.req.json();\n  const event = c.req.header(\"x-github-event\");\n\n  console.log(`GitHub webhook received: ${event}`, payload);\n\n  // Process webhook (e.g., trigger MCP tools)\n  return c.json({ event, received: true });\n});\n\n// Add a file upload endpoint\napp.post(\"/upload\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  try {\n    const body = await c.req.text();\n    const size = Buffer.byteLength(body);\n\n    return c.json({\n      message: \"File received\",\n      size: `${size} bytes`,\n    });\n  } catch (error) {\n    return c.json(\n      {\n        error: error instanceof Error ? error.message : \"Upload failed\",\n      },\n      500,\n    );\n  }\n});\n\n// Add middleware-like request counting\napp.get(\"/stats\", async (c) => {\n  const auth = await getAuth(c);\n  if (!auth) {\n    return c.json({ error: \"Authentication required\" }, 401);\n  }\n\n  requestCount++;\n  return c.json({\n    requests: requestCount,\n    timestamp: Date.now(),\n    uptime: process.uptime(),\n  });\n});\n\n// Add MCP tools that can interact with the custom routes\nserver.addTool({\n  description: \"List all users from the REST API\",\n  execute: async () => {\n    const userList = Array.from(users.values());\n    return {\n      content: [\n        {\n          text: `Found ${userList.length} users:\\n${userList\n            .map((u) => `- ${u.name} (${u.email})`)\n            .join(\"\\n\")}`,\n          type: \"text\",\n        },\n      ],\n    };\n  },\n  name: \"list_users\",\n  parameters: z.object({}),\n});\n\nserver.addTool({\n  description: \"Create a new user via the REST API\",\n  execute: async ({ email, name }) => {\n    const id = String(users.size + 1);\n    const newUser: User = { email, id, name };\n    users.set(id, newUser);\n\n    return {\n      content: [\n        {\n          text: `User created successfully:\\nID: ${id}\\nName: ${name}\\nEmail: ${email}`,\n          type: \"text\",\n        },\n      ],\n    };\n  },\n  name: \"create_user\",\n  parameters: z.object({\n    email: z.string().email(),\n    name: z.string(),\n  }),\n});\n\nserver.addTool({\n  description: \"Get server statistics\",\n  execute: async () => {\n    return {\n      content: [\n        {\n          text: `Server Statistics:\n- Total Users: ${users.size}\n- Request Count: ${requestCount}\n- Uptime: ${Math.floor(process.uptime())} seconds\n- Memory Usage: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,\n          type: \"text\",\n        },\n      ],\n    };\n  },\n  name: \"get_stats\",\n  parameters: z.object({}),\n});\n\n// Add a resource that exposes the user list\nserver.addResource({\n  description: \"Current user database\",\n  load: async () => ({\n    text: JSON.stringify(Array.from(users.values()), null, 2),\n  }),\n  mimeType: \"application/json\",\n  name: \"user-database\",\n  uri: \"resource://users\",\n});\n\n// Start the server\nconst PORT = process.env.FASTMCP_PORT\n  ? parseInt(process.env.FASTMCP_PORT)\n  : 8080;\n\nserver\n  .start({\n    httpStream: { port: PORT },\n    transportType: \"httpStream\",\n  })\n  .then(() => {\n    console.log(`\n🚀 Custom Routes Example Server Started!\n\nMCP Endpoint: http://localhost:${PORT}/mcp\nHealth Check: http://localhost:${PORT}/health\n\nPUBLIC ROUTES (No Authentication):\n- Status:       http://localhost:${PORT}/status\n- Docs:         http://localhost:${PORT}/docs\n- OAuth Config: http://localhost:${PORT}/.well-known/openid-configuration\n- Static Files: http://localhost:${PORT}/public/*\n\nPRIVATE ROUTES (Authentication Required):\n- REST API:     http://localhost:${PORT}/api/users\n- Admin Panel:  http://localhost:${PORT}/admin (admin only)\n- Statistics:   http://localhost:${PORT}/stats\n- File Upload:  http://localhost:${PORT}/upload\n- GitHub Hook:  http://localhost:${PORT}/webhook/github\n\nAuthentication:\nUse \"Authorization: Bearer admin-token\" or \"Bearer user-token\"\n\nTry these commands:\n\n# Public routes (no auth needed)\ncurl http://localhost:${PORT}/status\ncurl http://localhost:${PORT}/docs\ncurl http://localhost:${PORT}/.well-known/openid-configuration\n\n# Private routes (auth required)\ncurl -H \"Authorization: Bearer user-token\" http://localhost:${PORT}/api/users\ncurl -H \"Authorization: Bearer admin-token\" http://localhost:${PORT}/admin\ncurl -X POST -H \"Authorization: Bearer user-token\" -H \"Content-Type: application/json\" \\\\\n     -d '{\"name\":\"Charlie\",\"email\":\"charlie@example.com\"}' \\\\\n     http://localhost:${PORT}/api/users\n\n# Test authentication failure\ncurl http://localhost:${PORT}/api/users  # Should return 401\n\nMCP Tools available:\n- list_users\n- create_user  \n- get_stats\n\nTest with MCP Inspector:\nnpx fastmcp inspect src/examples/custom-routes.ts\n  `);\n  })\n  .catch((error) => {\n    console.error(\"Failed to start server:\", error);\n    process.exit(1);\n  });\n"]}