Skip to main content
Glama

Feishu MCP Server

mcp-tool.ts3.19 kB
import { Client } from '@larksuiteoapi/node-sdk'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { LarkMcpToolOptions, McpTool, ToolNameCase, TokenMode } from './types'; import { AllTools, AllToolsZh } from './tools'; import { filterTools } from './utils/filter-tools'; import { defaultToolNames } from './constants'; import { larkOapiHandler } from './utils/handler'; import { caseTransf } from './utils/case-transf'; import { getShouldUseUAT } from './utils/get-should-use-uat'; /** * Feishu/Lark MCP */ export class LarkMcpTool { // Lark Client private client: Client | null = null; // User Access Token private userAccessToken: string | undefined; // Token Mode private tokenMode: TokenMode = TokenMode.AUTO; // All Tools private allTools: McpTool[] = []; /** * Feishu/Lark MCP * @param options Feishu/Lark Client Options */ constructor(options: LarkMcpToolOptions) { if (options.client) { this.client = options.client; } else if (options.appId && options.appSecret) { this.client = new Client({ appId: options.appId, appSecret: options.appSecret, ...options, }); } this.tokenMode = options.tokenMode || TokenMode.AUTO; const isZH = options.toolsOptions?.language === 'zh'; const filterOptions = { allowTools: defaultToolNames, tokenMode: this.tokenMode, ...options.toolsOptions, }; this.allTools = filterTools(isZH ? AllToolsZh : AllTools, filterOptions); } /** * Update User Access Token * @param userAccessToken User Access Token */ updateUserAccessToken(userAccessToken: string) { this.userAccessToken = userAccessToken; } /** * Get MCP Tools * @returns MCP Tool Definition Array */ getTools(): McpTool[] { return this.allTools; } /** * Register Tools to MCP Server * @param server MCP Server Instance */ registerMcpServer(server: McpServer, options?: { toolNameCase?: ToolNameCase }): void { for (const tool of this.allTools) { server.tool(caseTransf(tool.name, options?.toolNameCase), tool.description, tool.schema, (params: any) => { try { if (!this.client) { return { isError: true, content: [{ type: 'text' as const, text: 'Client not initialized' }], }; } const handler = tool.customHandler || larkOapiHandler; if (this.tokenMode === TokenMode.USER_ACCESS_TOKEN && !this.userAccessToken) { return { isError: true, content: [{ type: 'text' as const, text: 'Invalid UserAccessToken' }], }; } const shouldUseUAT = getShouldUseUAT(this.tokenMode, this.userAccessToken, params?.useUAT); return handler( this.client, { ...params, useUAT: shouldUseUAT }, { userAccessToken: this.userAccessToken, tool }, ); } catch (error) { return { isError: true, content: [{ type: 'text' as const, text: `Error: ${JSON.stringify((error as Error)?.message)}` }], }; } }); } } }

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/Xumingmingming/feishu-mcp-server'

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