AI 应用媒体生成后端前端【免费下载链接】pollinationsYour Friendly Open-Source Gen-AI Platform项目地址https://gitcode.com/gh_mirrors/po/pollinations点击查看免费下载Pollinations 是一个开源多模型生成式 AI 平台Your Friendly Open-Source Gen-AI Platform其官方 MCPModel Context Protocol服务器将 Pollinations 的文本、图像、视频、音频、3D 与账户能力封装为一组 Agent 工具供 Claude Desktop、Cursor 等宿主通过 Streamable HTTP 调用。本文以仓库内 Agent Guidelines for MCP Server Development 为核心骨架结合 packages/mcp 的源码实现、测试用例 与 部署 Worker系统讲解该服务器的五大设计原则、代码结构、无状态 HTTP 纪律、工具注册流程、模型校验模式与测试方法。读完本文你将掌握如何在既有架构约束下安全地为 Pollinations MCP Server 新增一个工具并理解其薄代理 实时注册表校验 请求级鉴权的实现原理。一、设计原则为什么 MCP Server 要做得薄AGENTS.md开篇给出了五条设计原则它们是整个代码库的灵魂也是审查任何新增代码时的第一检查项。1. 薄代理Thin ProxyAPI 调用全部经由gen.pollinations.ai网关转发生成的媒体复用 API 已返回的公开 URL作为 MCP resource link不做下载再上传。媒体 URL 有两个来源图像 API 的 JSON 响应data[0].url字段二进制响应视频、音频、3D的Link响应头relenclosure。对应的实现位于 coreUtils.js 的 fetchMediaLink请求发出后读取响应头Link中^([^]); relenclosure$捕获组得到公开文件 URL随即response.body?.cancel()释放连接绝不把二进制数据拉进内存const mediaUrl response.headers .get(Link) ?.match(/^([^]); relenclosure$/)?.[1]; await response.body?.cancel(); if (!mediaUrl) throw new Error(Media generation returned no public file URL);同时服务端禁止直接调用其他服务主机必须走网关的 rewrite 路由/account/*、/image/*、/text/*、/audio/*、/v1/*。这一约束在 coreUtils.js 的 buildUrl 中落地所有请求都基于单一API_BASE_URL默认https://gen.pollinations.ai可由环境变量POLLINATIONS_BASE_URL覆盖拼接路径天然杜绝了向任意第三方主机发请求的写法。2. 无硬编码模型/音色枚举MCP Server不内置任何模型名或音色名的枚举而是通过 utils/models.js 实时拉取注册表校验。工具参数 schema 一律写成z.string()并在描述中提示使用listModels获取实时列表。原因很直接Pollinations 是活的多模型网关模型随时可能上下架、新增别名硬编码会让工具在模型变更后立刻失准。3. 不转换响应数据API 响应原样透传仅在需要 MCP content block 时才做重塑例如把生成的媒体 URL 包装成 resource link。这条原则保证了 MCP 返回内容与网关真实数据一致避免二次加工引入偏差。4. 最小工具面Minimal Tool Surface每个工具都会成为 LLM 推理的额外上下文也是选错工具的一个机会。因此只在宿主Claude Desktop、Cursor 等内真正有用的工具才会被加入。当前 server 注册了 17 个工具见下文工具全览每个都对应一个明确的 API 能力域。5. 无状态 HTTPStateless HTTP OnlyBearer token 从请求上下文读取不引入进程内状态、认证工具、会话或 stdio 入口。这是整个服务可部署为 Cloudflare Worker、可水平扩展的前提。二、代码结构按服务域组织的模块化布局AGENTS.md给出了标准目录结构仓库实际布局与之一致packages/mcp/ src/ server.js # server factory、工具注册、SERVER_INSTRUCTIONS services/ imageService.js # generateImage, generateVideo textService.js # generateText audioService.js # generateAudio, transcribeAudio embeddingService.js # createEmbeddings model3dService.js # generate3D discoveryService.js # listModels, getModelStatus accountService.js # getBalance, getUsage, getEarnings, listQuests, listKeys, createKey, revokeKey走 /account/* utils/ authUtils.js # 请求级 bearer 鉴权 coreUtils.js # fetch 封装、URL 构建、错误映射 models.js # 注册表拉取 校验器 test/ accountService.test.js audioService.test.js coreUtils.test.js discoveryService.test.js textService.test.js AGENTS.md README.md package.json各文件职责要点server.js导出createMcpHandler与buildServer()。buildServer创建McpServer实例声明SERVER_VERSION当前为 2.5.1见 package.json把来自 7 个 service 的工具数组全部 spread 进tools再通过server.registerTool(name, { description, inputSchema: z.object(inputSchema) }, handler)逐个注册server.js L70-L77。SERVER_INSTRUCTIONS作为注入给 LLM 的系统级指令包含鉴权方式、模型发现与生成约定、账户权限要求、API Endpoint 四部分其中 Endpoint 由validateApiBaseUrl()动态生成。utils/authUtils.js负责从context.http.authInfo.token解析密钥并拼装Authorization: Bearer ...头coreUtils.js提供buildUrl、fetchWithAuth、fetchJsonWithAuth、fetchMediaLink、createMCPResponse、createTextContent、parseApiErrormodels.js提供按模态分组的注册表获取与校验函数。apps/mcp/worker.js托管在 Cloudflare 的 Streamable HTTP Worker导入packages/mcp/src/server.js的工厂负责 bearer token 解析、健康检查、批量请求拒绝等 HTTP 边界职责。三、无状态 HTTP 纪律凭据只属于一个请求AGENTS.md强调The public server uses Streamable HTTP without MCP sessions. Credentials belong to one request and must never be stored in module state.这在两层代码中体现为硬约束第一层工具层。authUtils.js 每次调用都从请求上下文取密钥function resolveApiKey(context) { return context?.http?.authInfo?.token || null; }requireApiKey(context)在无密钥时抛出提示信息getAuthHeaders(context)在存在密钥时才附加Authorization头。密钥从不写入模块级变量、不缓存、不进会话。第二层HTTP 边界层。apps/mcp/worker.js 在fetch入口解析Authorization: Bearer token未携带则直接返回 401带WWW-Authenticate头通过后将 token 作为authInfo.token传入 MCP handlerreturn mcpHandler.fetch(request, { authInfo: { token, clientId: pollinations-api-key, scopes: [], }, });同时 Worker 使用legacy: stateless模式worker.js L6-L9并拒绝 JSON 数组形式的批量请求返回 400invalid_request进一步强化一次请求一次鉴权的纪律。/health端点返回stateless: true便于探活确认。四、添加一个工具五步标准流程AGENTS.md给出新增工具的标准步骤结合源码可将每一步落到具体位置在相关 service 文件中添加 handler新域则新建 service 文件。handler 签名统一为async (params, context) { ... }内部先requireApiKey(context)再校验模型如需要最后通过fetchJsonWithAuth/fetchMediaLink调用网关并组装 MCP 响应。在工具数组中导出[name, description, zodShape, handler]四元组。例如 imageService.js 的 imageToolsname是工具名description是给 LLM 看的能力说明含先用 listModels的提示语zodShape是 zod schema 对象handler是执行函数。在 src/server.js 导入数组并 spread 进tools。工具顺序即注册顺序buildServer会将其逐一注册。在SERVER_INSTRUCTIONS中补一行说明server.js L26-L54确保注入给 LLM 的指引与工具面同步。更新 README.md 的工具表格记录工具名、用途与对应 API 路由保持文档与实现一致。服务端的工具四元组会被z.object(inputSchema)包装成 MCP 输入 schemadescription会被 MCP 协议暴露给宿主 LLM因此描述的质量直接影响 Agent 的工具选择准确率——这也是最小工具面原则的延伸宁缺毋滥。五、校验模式剖析注册表实时校验 模糊建议AGENTS.md给出了标准的校验写法import { validateImageModel } from ../utils/models.js; const result await validateImageModel(model); if (!result.valid) { throw new Error(${result.error} Use listModels for the live registry.); }底层实现在 models.js 的 validateAgainstRegistry流程如下若模型名为空直接返回{ valid: true }未指定模型时走网关默认值拉取对应模态的实时注册表/image/models、/text/models、/video/models、/audio/models、/embeddings/models、/3d/models全部经 MODEL_PATHS 映射按m.name modelName || m.aliases?.includes(modelName)匹配规范名或别名未命中时对名称做双向子串匹配最多给出 3 个建议名并附带availableCount供错误提示使用。各模态的校验入口validateImageModel、validateTextModel、validateVideoModel、validateEmbeddingModel、validateModel3d均由该函数参数化生成。实际错误信息比模板更友好例如 imageService.js L16-L22throw new Error( ${validation.error} Did you mean: ${validation.suggestions.join(, )}? Use listModels with typeimage to see all available models., );这套机制保证模型名拼写错误、模型下线、新增模型都能得到实时、可操作的反馈而不会出现模型不存在但工具仍按旧枚举放行的过期行为。六、工具全览17 个工具的能力域与 API 路由结合 README.md 工具表 与各 service 源码当前工具面如下工具用途API 路由generateText文本生成、搜索、多模态输入与工具调用/v1/chat/completionsgenerateImage生成或编辑图像/v1/images/generationsgenerateVideo生成视频/video/{prompt}generateAudio生成语音、音乐或音效/audio/{text}transcribeAudio转写公开 HTTPS 音频 URL/v1/audio/transcriptionsgenerate3D生成 GLB 3D 模型/3d/{prompt}createEmbeddings创建文本或多模态嵌入/v1/embeddingslistModels搜索并列出实时模型、能力、音色与定价模型注册表路由getModelStatus查看近期请求、错误与延迟/models/statusgetBalance查询剩余 Pollen 余额需account:usage/account/balancegetUsage请求历史或按日汇总需account:usage/account/usage、/account/usage/dailygetEarningsBYOP 应用与社区模型的开发者收益需account:usage/account/earningslistQuests任务奖励与领取状态需account:usage/account/questslistKeys列出 API 密钥需account:keys/account/keyscreateKey创建 secret 或 publishable 应用密钥需account:keysPOST /account/keysrevokeKey按 id 吊销密钥需account:keysDELETE /account/keys/{id}几个值得深入的点生成类工具的典型返回图像返回resource_linkuri为image.urlmimeType为image.media_type 结构化文本元数据视频/音频/3D 通过fetchMediaLink拿到content-type与公开 URL 后同样组装resource_link。媒体以链接形式返回不占用模型上下文窗口且任何持有链接者都可访问过期文件返回 404README 原话。generateText是能力最重的工具textService.js 的 schema 覆盖 messages6 种角色、温度/采样参数temperature0-2、top_p0-1、三类惩罚系数、response_formattext/json_object/json_schema 结构化输出、reasoning_effort、tools/tool_choice/parallel_tool_calls、modalities/audio语音输出、logprobs/logit_bias、legacy 的functions/function_call等响应侧按assistantMessage拆分 content、reasoning_content、tool_calls、function_call、audio含转录文本与citations最后附上model、finish_reason、usage元数据。账户类工具权限由 API 端强制读类需account:usage密钥类需account:keys错误信息原样透传accountService.js L10-L11createKey返回完整密钥仅此一次工具描述明确要求展示给用户且不得存储accountService.js L179。getUsage支持dailytrue切换汇总口径days上限 90、limit默认 20accountService.js L50-L60。listModels的过滤参数typeall/text/image/video/audio/embedding/3d、community仅社区/仅官方模型、agent仅 Agent、query名称/别名/标题/描述/发布者全词匹配、capabilities如tool_calling、reasoning、web_search、limit上限 500服务端在 Gen 侧过滤客户端只传筛选条件discoveryService.js L10-L16。七、错误映射与安全细节coreUtils.js 的 parseApiError 把网关的 HTTP 错误翻译成对 LLM 友好的中文/英文提示400命中 content moderation/safety/blocked 时提示内容被安全过滤器拦截命中 invalid model 时提示用listModels查看可用模型401提示发送有效 API 密钥bearer token及其获取入口403优先透传 API 返回的原始错误消息如密钥无权使用该模型无消息时才用兜底文案404 / 429 / 5xx / 502-504分别给出资源不存在、限流并提示 publishablepk_密钥可升级 secretsk_密钥以提升限额、服务器错误与临时不可用提示。coreUtils.test.js 对该映射有针对性覆盖403 场景分别验证了网关权限错误消息原样保留含编辑密钥链接、非权限消息透传、staging 白名单限制消息透传与空 body 兜底文案四种分支。在音频转写上还有一层 SSRF 防护audioService.js 的 publicAudioUrl 强制source为无凭据的公开 HTTPS URL拒绝localhost、.localhost域名与 IP 地址同时因 Workers 拒绝redirect: error采用redirect: manual并显式拒绝 3xx 重定向audioService.js L45-L62防止代理访问内网地址。八、测试体系AGENTS.md给出两级测试npm run test在 packages/mcp 内执行聚焦工具 handler 的单元测试。脚本定义于 package.jsonnode --test test/*.test.js覆盖coreUtils、textService、audioService、discoveryService、accountService。运行环境要求 Node.js 20package.json engines。npm run test在 apps/mcp 内执行Streamable HTTP Worker 层的测试worker.test.js覆盖鉴权、路由、批量请求拒绝等 HTTP 边界行为。新增工具时应同时在对应 service 的测试文件中补充 handler 级用例保证工具注册 schema、错误分支与响应组装都有可验证的依据。九、连接与使用方式Streamable HTTP 客户端可连接至网关暴露的端点路径见 README 与SERVER_INSTRUCTIONS每次请求携带 Pollinations API 密钥Authorization: Bearer YOUR_KEY密钥的 Pollen 钱包、权限与预算即被用于该请求的计费与鉴权。所有模型、音色、能力与定价均来自实时注册表因此在选定模型或音色前应先用listModels查询。生成的媒体以 MCP resource link 形式返回无需下载与回传。十、小结packages/mcp/AGENTS.md用极简的篇幅定义了 Pollinations MCP Server 的全部架构约束而这些约束在源码中均有一一对应的强制实现薄代理→buildUrl单网关拼接 fetchMediaLink复用公开 URL无硬编码枚举→models.js注册表拉取与validateAgainstRegistry模糊建议不转换响应→ 除 resource link 包装外原样透传最小工具面→ 17 个工具全部有明确 API 路由对应无状态 HTTP→authUtils.js请求级取 token worker.js的legacy: stateless与批量请求拒绝。这套设计让服务器既能在 Cloudflare Worker 上无状态水平扩展又能保持对多模态模型生态的实时感知。对于希望为 Pollinations 贡献新工具或在其上构建自定义 MCP 工具集的开发者按四、添加一个工具的五步流程操作再以第八节的测试体系验证即可安全合入。延伸阅读进一步了解工具能力说明与 API 路由对应关系可读 packages/mcp/README.md模型校验与注册表映射可读 packages/mcp/src/utils/models.jsHTTP 边界实现可读 apps/mcp/worker.js 与 apps/mcp/worker.test.js。赞分享AI 应用媒体生成后端前端【免费下载链接】pollinationsYour Friendly Open-Source Gen-AI Platform项目地址https://gitcode.com/gh_mirrors/po/pollinations点击查看免费下载相关推荐metro-bootstrap开发环境搭建Gulp编译流程与依赖管理全攻略metro bootstrap开发环境搭建Gulp编译流程与依赖管理全攻略 metro bootstrap是一款融合Twitter Bootstrap框架与M如何快速扩展 mcp-server-browserbase自定义工具开发完整指南如何快速扩展 mcp server browserbase自定义工具开发完整指南 mcp server browserbase 是一个允许大型语言模型LLMmcp-for-beginners 实战用 FastMCP 为 Calculator MCP Server 扩展平方根工具mcp for beginners 实战用 FastMCP 为 Calculator MCP Server 扩展平方根工具 在本教程中你将基于 mcp fo教程文档人工智能上一篇如何快速优化Windows系统3步完成智能清理与性能提升终极指南下一篇Windows Cleaner终极指南简单三步告别C盘爆红让电脑重获新生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考