Skip to main content
Glama

360 AI Cloud Drive MCP Server

by Qihoo360
auth.ts5.05 kB
import dotenv from 'dotenv'; import { generateSign, generateSignedParams } from './sign.js'; import { getConfig } from './const.js'; // 加载环境变量 dotenv.config(); // 定义鉴权响应接口 export interface AuthResponse { errno: number; errmsg: string; data: { token: string; access_token: string; access_token_expire: number; qid: string; }; trace_id: string; } // 定义存储鉴权信息的接口 export interface AuthInfo { access_token: string; qid: string; token: string; sign?: string; request_url?: string; } // 定义认证方法参数接口 export interface AuthParams { method?: string; extraParams?: Record<string|number, string|number>; req?: any; // 添加Express请求对象参数 } // 鉴权信息缓存 let authCache: AuthInfo | null = null; let authExpireTime: number = 0; /** * 从环境变量读取云盘API密钥信息 * @returns 云盘API密钥信息 */ function getKeyInfo(transportAuthInfo?: any): { apiKey: string; clientId: string; clientSecret: string; } { // 首先尝试从HTTP请求获取API_KEY let apiKey = ''; if (transportAuthInfo) { // 直接使用传入的 apiKey if (transportAuthInfo.apiKey) { apiKey = transportAuthInfo.apiKey; } } // 如果请求中没有找到,使用环境变量 if (!apiKey) { apiKey = process.env.API_KEY || ''; } const { client_id, client_secret } = getConfig(transportAuthInfo?.ecsEnv); return { apiKey, clientId: client_id, clientSecret: client_secret } } /** * 调用鉴权接口获取认证信息 * @param authParams 可选的认证参数 * @returns 鉴权信息 */ async function fetchAuthInfo(authParams: AuthParams, transportAuthInfo?: any): Promise<AuthInfo> { const keyInfo = getKeyInfo(transportAuthInfo); if (!keyInfo.apiKey) { throw new Error('未配置YUNPAN_API_KEY环境变量'); } try { const { request_url } = getConfig(transportAuthInfo?.ecsEnv); // 构建请求URL和参数 const url = new URL(request_url); // 基础参数 let baseParams: Record<string, string> = {}; const extraParams = authParams.extraParams; if (extraParams && extraParams.toolName === 'file-upload-stdio') { baseParams['method'] = extraParams.method as string; baseParams['client_id'] = extraParams.clientId as string; baseParams['client_secret'] = extraParams.clientSecret as string; baseParams['qid'] = extraParams.qid as string; baseParams['grant_type'] = extraParams.grantType as string; } else { baseParams['method'] = 'Oauth.getAccessTokenByApiKey'; baseParams['client_id'] = keyInfo.clientId; baseParams['client_secret'] = keyInfo.clientSecret; baseParams['grant_type'] = 'authorization_code'; baseParams['api_key'] = keyInfo.apiKey; } // 添加所有参数到URL Object.entries(baseParams).forEach(([key, value]) => { url.searchParams.append(key, value); }); const response = await fetch(url.toString(), { method: 'GET', headers: { 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`鉴权请求失败,状态码: ${response.status}`); } const authResponse: AuthResponse = await response.json(); if (authResponse.errno !== 0) { throw new Error(`鉴权请求返回错误: ${authResponse.errmsg}`); } // 从响应中提取需要的信息 const { access_token, qid, token } = authResponse.data; return { access_token, qid, token }; } catch (error) { console.error('获取鉴权信息失败:', error); throw error; } } /** * 获取鉴权信息,如果缓存有效则使用缓存 * @param authParams 可选的认证参数,包括方法名和路径等 * @returns 鉴权信息 */ export async function getAuthInfo(authParams: AuthParams = {}, transportAuthInfo?: any): Promise<AuthInfo> { const now = Date.now(); // 如果缓存可用且未过期,直接返回缓存 // if (authCache && now < authExpireTime) { // delete authCache.sign; // authCache.sign = generateSign(generateSignedParams(authCache, authParams.method || '', authParams.extraParams)); // return authCache; // } // 获取新的鉴权信息 const authInfo = await fetchAuthInfo(authParams, transportAuthInfo); if (authParams.extraParams && authParams.extraParams.toolName === 'file-upload-stdio') { authInfo.qid = authParams.extraParams.qid as string; return authInfo; } const signedAuthInfo = { access_token: authInfo.access_token, qid: authInfo.qid, } // 确保方法名存在,默认为空字符串 const method = authParams.method || ''; // 生成签名 const sign = generateSign(generateSignedParams(signedAuthInfo, method, authParams.extraParams)); authInfo.sign = sign; // 更新缓存,使用API返回的过期时间 authCache = authInfo; authExpireTime = now + 60 * 60 * 1000; // 默认1小时过期 return authInfo; }

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/Qihoo360/ecs_mcp_server'

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