diff --git a/src/everything/auth.ts b/src/everything/auth.ts new file mode 100644 index 00000000..941b6d08 --- /dev/null +++ b/src/everything/auth.ts @@ -0,0 +1,43 @@ +import express, { Request, Response } from 'express'; + +export interface AuthConfig { + enabled: boolean; + // Additional auth config options can be added here later +} + +export interface WellKnownOAuthMetadata { + issuer: string; + authorization_endpoint: string; + token_endpoint: string; + jwks_uri: string; + response_types_supported: string[]; + grant_types_supported: string[]; + subject_types_supported: string[]; + id_token_signing_alg_values_supported: string[]; + scopes_supported: string[]; +} + +export function addAuthEndpoints(app: express.Application, config: AuthConfig): void { + if (!config.enabled) { + return; + } + + // OAuth metadata endpoint + app.get('/.well-known/oauth-authorization-server', (req: Request, res: Response) => { + const baseUrl = `${req.protocol}://${req.get('host')}`; + + const metadata: WellKnownOAuthMetadata = { + issuer: baseUrl, + authorization_endpoint: `${baseUrl}/oauth/authorize`, + token_endpoint: `${baseUrl}/oauth/token`, + jwks_uri: `${baseUrl}/.well-known/jwks.json`, + response_types_supported: ['code', 'token', 'id_token', 'code token', 'code id_token', 'token id_token', 'code token id_token'], + grant_types_supported: ['authorization_code', 'implicit', 'refresh_token', 'client_credentials'], + subject_types_supported: ['public'], + id_token_signing_alg_values_supported: ['RS256'], + scopes_supported: ['openid', 'profile', 'email'] + }; + + res.header('Content-Type', 'application/json').send(metadata); + }); +} \ No newline at end of file diff --git a/src/everything/sse.ts b/src/everything/sse.ts index 7a02eb53..501681fa 100644 --- a/src/everything/sse.ts +++ b/src/everything/sse.ts @@ -1,11 +1,20 @@ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import express from "express"; import { createServer } from "./everything.js"; +import { addAuthEndpoints, AuthConfig } from "./auth.js"; const app = express(); const { server, cleanup } = createServer(); +// Configure auth +const authConfig: AuthConfig = { + enabled: process.env.ENABLE_AUTH === 'true' +}; + +// Add auth endpoints if enabled +addAuthEndpoints(app, authConfig); + let transport: SSEServerTransport; app.get("/sse", async (req, res) => { diff --git a/src/everything/streamableHttp.ts b/src/everything/streamableHttp.ts index 3a87bc83..6f0c8433 100644 --- a/src/everything/streamableHttp.ts +++ b/src/everything/streamableHttp.ts @@ -3,11 +3,20 @@ import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/in import express, { Request, Response } from "express"; import { createServer } from "./everything.js"; import { randomUUID } from 'node:crypto'; +import { addAuthEndpoints, AuthConfig } from "./auth.js"; const app = express(); const { server, cleanup } = createServer(); +// Configure auth +const authConfig: AuthConfig = { + enabled: process.env.ENABLE_AUTH === 'true' +}; + +// Add auth endpoints if enabled +addAuthEndpoints(app, authConfig); + const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {}; app.post('/mcp', async (req: Request, res: Response) => {