Skip to main content
Glama
larksuite

Feishu/Lark OpenAPI MCP

Official
by larksuite
sse.ts2.88 kB
import express, { NextFunction, Request, Response } from 'express'; import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; import { InitTransportServerFunction } from '../shared'; import { LarkAuthHandler } from '../../auth'; import { parseMCPServerOptionsFromRequest } from './utils'; import { logger } from '../../utils/logger'; export const initSSEServer: InitTransportServerFunction = ( getNewServer, options, { needAuthFlow } = { needAuthFlow: false }, ) => { const { userAccessToken, port, host, oauth } = options; if (!port || !host) { throw new Error('[Lark MCP] Port and host are required'); } const app = express(); const transports: Map<string, SSEServerTransport> = new Map(); let authHandler: LarkAuthHandler | undefined; if (!userAccessToken && needAuthFlow) { authHandler = new LarkAuthHandler(app, options); if (oauth) { authHandler.setupRoutes(); } } const authMiddleware = (req: Request, res: Response, next: NextFunction) => { if (authHandler && oauth) { authHandler.authenticateRequest(req, res, next); } else { const authToken = req.headers.authorization?.split(' ')[1]; if (authToken) { req.auth = { token: authToken, clientId: 'client_id_for_local_auth', scopes: [] }; } next(); } }; app.get('/sse', authMiddleware, async (req: Request, res: Response) => { logger.info(`[SSEServerTransport] Received GET SSE request`); const token = req.auth?.token; const { data } = parseMCPServerOptionsFromRequest(req); const server = getNewServer({ ...options, ...data, userAccessToken: data.userAccessToken || token }, authHandler); const transport = new SSEServerTransport('/messages', res); transports.set(transport.sessionId, transport); res.on('close', () => { transport.close(); server.close(); transports.delete(transport.sessionId); }); await server.connect(transport); }); app.post('/messages', authMiddleware, async (req: Request, res: Response) => { console.log('Received POST messages request'); logger.info(`[SSEServerTransport] Received POST messages request`); const sessionId = req.query.sessionId as string; const transport = transports.get(sessionId); if (!transport) { res.status(400).send('No transport found for sessionId'); return; } await transport.handlePostMessage(req, res); }); console.log('⚠️ SSE Mode is deprecated and will be removed in a future version. Please use Streamable mode instead.'); app.listen(port, host, (error) => { if (error) { logger.error(`[SSEServerTransport] Server error: ${error}`); process.exit(1); } console.log(`📡 SSE endpoint: http://${host}:${port}/sse`); logger.info(`[SSEServerTransport] SSE endpoint: http://${host}:${port}/sse`); }); };

Latest Blog Posts

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/larksuite/lark-openapi-mcp'

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