
LocalAI Assistant 管理员 MCP 服务器REST 端点、MCP 工具与 Skill 提示词的三层契约设计与接入指南【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAILocalAI 的localai_assistant管理面把「安装模型、管理后端、编辑模型配置、查看系统状态」这类管理员日常操作封装为 MCPModel Context Protocol工具让管理员可以通过自然语言聊天或标准 stdio MCP 客户端驱动本地 LocalAI 实例完成运维任务。本文以仓库内契约文档 .agents/localai-assistant-mcp.md 为主体结合pkg/mcp/localaitools/的源码实现完整讲解该功能的双运行模式、REST / MCP / Skill 三层同步架构、新增端点与技能配方的操作清单以及防止魔法字符串漂移的编码规范读者可据此独立扩展该管理面。功能总览把 LocalAI 管理面变成可对话的 MCP 工具集pkg/mcp/localaitools/是一个公开的 Go 包它把 LocalAI 的管理/运维能力admin surface封装成一个 MCP Server。它在项目中有两种截然不同的使用方式进程内模式in-process当管理员在聊天会话中携带metadata.localai_assistanttrue元数据发起请求时聊天处理器会向 LLM 注入一个驻留内存的 MCP Server。它通过net.Pipe()配对的进程内传输通道通信不经过任何 HTTP 回环loopback。LLM 因此可以在对话中直接安装模型、管理后端、编辑配置。独立模式standalone通过local-ai mcp-server --target…子命令启动同一个 MCP Server 以stdio方式对外提供服务内部通过 HTTP 与一个远程 LocalAI 实例通信可被 Claude Desktop、Cursor、mcphost 等宿主接入。两种模式共享全部工具定义与 Skill 提示词唯一差别是LocalAIClient接口的实现进程内使用 inproc/client.go直接调用服务独立模式使用 httpapi/client.go调用 REST 接口。从源码看二者的组装点是一致的NewServer(client, opts)接收任意LocalAIClient实现与选项注册 12 组工具后返回统一类型见 server.gofunc NewServer(client LocalAIClient, opts Options) *mcp.Server { // name 缺省为 localai-adminversion 缺省为 internal.PrintableVersion() srv : mcp.NewServer(mcp.Implementation{Name: name, Version: version}, mcp.ServerOptions{ Instructions: SystemPrompt(opts), // 把嵌入的 markdown 提示词组装成系统提示 }) registerModelTools(srv, client, opts) registerAliasTools(srv, client, opts) registerBackendTools(srv, client, opts) registerConfigTools(srv, client, opts) // …registerSystemTools / registerSchedulingTools / registerStateTools … return srv }Options中DisableMutating会跳过所有改变服务状态的工具供--read-only形态的 CLI 使用ServerName/ServerVersion可覆盖 MCP 对外通告的Implementation.Name与版本号。三条必须保持同步的层级当开发者改动 LocalAI 的管理面时文档强调有三层必须始终对齐缺一不可REST 端点位于 core/http/endpoints/localai/目录下按功能拆分gallery.go、import_model.go、edit_model.go、toggle_model.go、pin_model.go、nodes.go、branding.go等并在 core/http/routes/ 的localai.go中由auth.RequireAdmin()统一做管理员鉴权保护。MCP 工具注册位于pkg/mcp/localaitools/tools_*.go同时需要在 client.go 的LocalAIClient接口上增加对应方法并在inproc 与 httpapi 两个 client中分别实现。Skill 提示词位于 pkg/mcp/localaitools/prompts/skills/ 的 markdown它教会 LLM 在什么场景下调用新工具、先向用户询问什么、出错时如何处理。若只发布 REST 端点而遗漏第 2、3 层对话式管理员将永远看不到该功能——这正是该契约文档存在的根本原因。仓库根目录的 AGENTS.md 也明确要求每个适合对话管理的管理端点都必须同步暴露为 MCP 工具并通过TestToolHTTPRouteMappingComplete这类路由映射测试来防止 REST 与 MCP 之间漂移。新增管理端点的完整核对清单契约文档为「新增一个管理端点」给出了逐项清单下面按层展开说明并结合源码标注落点1. REST 端点在core/http/endpoints/localai/*.go中实现端点并在core/http/routes/localai.go中登记确保挂上auth.RequireAdmin()守卫。项目在 core/http/auth/permissions.go 中定义了FeatureLocalAIAssistant localai_assistant特性开关说明该管理面与鉴权体系深度绑定。2.LocalAIClient接口方法在 pkg/mcp/localaitools/client.go 的接口上新增覆盖该操作的方法。该接口定义了全部 40 方法按领域分组并带注释例如模型/画廊域GallerySearch、ListInstalledModels、InstallModel、ImportModelURI…、后端域ListBackends、InstallBackend、UpgradeBackend…、调度域ListScheduling、SetScheduling…。接口注释同时揭示了实现约定凡是仓库其它地方已有同型如config.Gallery、gallery.Metadata、schema.KnownBackend、vram.EstimateResult、modeladmin.Action/Capability直接复用而非另建平行 DTO从而让 LLM 可见的线上格式与 LocalAI 其余部分天然一致。3. DTO 定义在 dto.go 中增补带 JSON tag 的 DTO绝不直接暴露底层 service 的原始类型例如后端列表刻意使用轻量的localaitools.Backend而不是带RunFile、Metadata等文件系统路径的gallery.SystemBackend避免 LLM 看到不应看到的路径信息。4. 双客户端实现inproc/client.go 直接调用服务层如galleryop.GalleryService、config.ModelConfigLoader、modeladmin不走 HTTP 回环。httpapi/client.go 通过 REST 端点调用。两者的对齐由 parity_test.go 保证输出等价性。5. 工具注册与安全联动在对应的pkg/mcp/localaitools/tools_*.go中注册工具变更类工具的描述里必须引用安全规则 1。若工具会修改状态确保Options{DisableMutating: true}能跳过它参照tools_models.go中的模式。mutatingToolNames是覆盖安全提示词的工具名单位于 tools.go。6. Skill 提示词在pkg/mcp/localaitools/prompts/skills/下新增或更新配方文件。提示词必须指导 LLM何时调用该工具、先向用户确认什么、出错时如何处理。7. 测试server_test.go 把工具名加入expectedFullCatalog只读工具还要加入expectedReadOnlyCatalog。把工具分发加入TestEachToolDispatchesToClient。httpapi/client_test.go 覆盖新的 HTTP 路径。新增 Skill 配方不涉及新工具有时只是想教 LLM 用既有工具组合出新的行为模式此时无需任何 Go 改动直接在 pkg/mcp/localaitools/prompts/skills/ 放一个 markdown 文件即可。该目录通过//go:embed prompts/*.md prompts/skills/*.md在编译期嵌入见 prompts.go并由 SystemPrompt 以字典序确定性遍历拼装进系统提示词每个文件前自动追加!-- file: … --与# section: basename头便于追溯 LLM 引用了哪份配方。配方的既定约定文件名形如动词_名词.md例如install_chat_model.md、upgrade_backend.md、manage_router_corpus.md。首行必须是# Skill: Title Case 描述。步骤必须编号并用反引号引用精确的工具名。若配方会修改状态提醒 LLM 先与用户确认。以 install_chat_model.md 为例它完整示范了标准工作流先gallery_search→ 编号列出候选含名称、画廊、简介、许可证→ 等用户挑选 → 复述安装动作并等待确认 → 确认后调用install_modelvariant留空则自动按机器可用引擎与内存选择最大可运行版本仅当用户点名某个具体构建时才传值→ 用返回的 job id 轮询get_job_status→ 成功后依次调用reload_models与list_installed_models验证 → 告知用户模型名即 chat completions 的model字段取值。仓库当前内置的配方还包括edit_model_config.md、import_model_from_uri.md、configure_branding.md、manage_distributed_scheduling.md、system_status.md、upgrade_backend.md等覆盖配置编辑、URI 导入、品牌配置、分布式调度、系统体检与后端升级。工具全貌只读与变更两类pkg/mcp/localaitools/tools.go是全部Tool*名称常量的唯一事实来源。当前注册工具涵盖模型/画廊、别名、后端、配置、系统、调度、状态启用/固定、品牌、音色库、用量统计、PII 过滤与中间件/router 等 12 类。按是否修改服务器状态可分为两组只读工具gallery_search、list_installed_models、list_galleries、get_job_status、get_model_config、list_backends、list_known_backends、system_info、list_nodes、list_scheduling、get_scheduling、vram_estimate、get_branding、get_usage_stats、get_pii_events、get_middleware_status、get_router_decisions、get_router_corpus_stats、list_aliases、list_voice_profiles。变更类工具均需按安全规则 1 先确认install_model、import_model_uri、delete_model、edit_model_config、reload_models、load_model、install_backend、upgrade_backend、toggle_model_state、toggle_model_pinned、set_branding、set_alias、seed_router_corpus、clear_router_corpus、create_voice_profile、delete_voice_profile、set_node_vram_budget、set_scheduling、delete_scheduling。这些工具各自的用途描述可在 prompts/20_tools.md 中查看——它是面向 LLM 的精选工具目录tools/list仍会暴露每项完整输入 schema。例如import_model_uri支持 HuggingFace / OCI / http(s) / file:// 等任意 URI若多个后端适用会返回ambiguous_backend需带上backend_preference再次调用消歧load_model可预载模型消除冷启动对实时流水线模型会一次性载入 VAD、转写、LLM、TTS 等全部子模型。其中list_installed_models的过滤标签使用强类型 capability.go 的Capabilitychat、completion、embeddings、image、tts、transcript、rerank、vad空值表示不过滤。这些常量会进入工具 DTO 的 jsonschema enum是公开 API 变更——新增取值会直接改变 LLM 在tools/list时看到的合法列表。编码规范对抗魔法字符串漂移文档明确指出这些规范源自第一次审计中暴露的魔法字面量漂移问题目的是防止回归工具名一律引用 tools.go 的Tool*常量。注册、测试目录server_test.go的expectedFullCatalog/expectedReadOnlyCatalog、分发表都引用常量唯一例外是prompts/下嵌入的 markdown 无法引用 Go 常量而保留裸字符串并由TestPromptsContainSafetyAnchors校验其与确认规则的持续对齐。启用/固定类操作使用modeladmin.Action类型位于core/services/modeladmin一律ActionEnable/ActionDisable/ActionPin/ActionUnpin禁止裸写enable/pin。能力标签使用localaitools.CapabilityListInstalledModels接收强类型参数inproc的 switch 只接受规范值——embed与embedding不是别名只有CapabilityEmbeddings合法。HTTP 错误判断用errors.Is(err, ErrHTTPNotFound)不做err.Error()子串匹配。*HTTPError类型携带StatusCode与Body新增哨兵错误应扩展类型体系而非重拾字符串匹配。inproc client 向GalleryService.ModelGalleryChannel/BackendGalleryChannel发送时必须在select中监听ctx.Done()见inproc.sendModelOp/sendBackendOp否则被取消的聊天补全会让 goroutine 泄漏。模型配置 YAML 落盘必须走modeladmin.writeFileAtomic临时文件 os.Rename。裸os.WriteFile在进程崩溃时截断文件会损坏模型配置。MCP Server 生命周期每个完成初始化的持有者holder必须用signals.RegisterGracefulTerminationHandler注册Close()独立的mcp-serverCLI 则用signal.NotifyContext响应 SIGINT/SIGTERM给在途调用排空的机会见下文 CLI 源码。文件地图去哪看、改什么契约文档给出了逐文件的导航图结合仓库实际布局梳理如下pkg/mcp/localaitools/ client.go # LocalAIClient 接口 DTO 注册 dto.go # 双实现共享的 JSON-tagged DTO server.go # NewServer(client, opts) —— 注册全部工具 tools.go # Tool* 名称常量唯一事实来源 mutatingToolNames capability.go # Capability 类型与常量 tools_models.go # gallery_search、install_model、import_model_uri … tools_backends.go # 后端安装/升级/列举 tools_config.go # get_model_config、edit_model_config tools_system.go # system_info、list_nodes 等系统域 tools_state.go # toggle_model_state / toggle_model_pinned tools_aliases.go # set_alias / list_aliases tools_branding.go # get_branding / set_branding tools_scheduling.go # 调度配置读写 tools_voice_profiles.go# 音色库管理 tools_usage.go # get_usage_stats tools_pii.go # get_pii_events tools_middleware.go # get_middleware_status / router 相关 prompts.go # //go:embed 加载器 SystemPrompt(opts) prompts/00_role.md # LLM 角色设定 prompts/10_safety.md # 安全规则改动需极其谨慎 prompts/20_tools.md # 精选工具目录一行式描述 prompts/skills/*.md # 技能配方 inproc/client.go # 进程内 LocalAIClient直连服务 httpapi/client.go # REST LocalAIClientstandalone CLI / 远程 parity_test.go # inproc 与 httpapi 输出等价性 server_test.go # 工具目录 / 分发断言 prompts_test.go # 系统提示词与安全锚点一致性 core/http/endpoints/mcp/ localai_assistant.go # 进程级持有者 LocalAIAssistantHolder LocalToolExecutor core/cli/mcp_server.go # local-ai mcp-server 子命令关于进程内持有者localai_assistant.go 的注释给出了设计取舍采用进程级单例持有者而非每请求临时接线是因为 MCP Server 本身跨请求无状态——每次请求重建net.Pipe()配对并重列工具纯属浪费同一个进程内LocalToolExecutor可为所有 assistant 会话服务无需 NATS、子进程或合成的管理员凭据。持有者在 Application 启动时初始化一次之后可并发使用若初始化失败或DisableLocalAIAssistant生效Executor()返回空执行器且HasTools()为 false聊天处理器将其视为「功能不可用」。此外core/config/runtime_settings.go 暴露localai_assistant_enabled运行时设置可在 UI 上开关该能力。为什么是两套 client 而非一种契约文档解释得很直白进程内 MCP Server 跑在承载聊天的同一 LocalAI 二进制内部如果走 HTTP 回环会有三重代价——服务端需要为自己铸造一个合成的 admin API key才能完成自认证每次工具分发都要双重序列化marshal / unmarshal会丢失进程内通道——例如GalleryService.ModelGalleryChannel上流式的安装进度HTTP 形态拿不到。因此进程内模式用inproc.Client服务直连独立 stdio CLI 面对的是远程 LocalAIHTTP 是唯一选项所以用httpapi.Client。二者实现同一个LocalAIClient接口等价性由 parity_test.go 守护。inproc.Client还刻意保持「薄适配」分发与持久化交给底层服务GalleryService本身具备分布式感知、ModelConfigLoader管理磁盘 YAML该层只做 MCP DTO 与服务签名的翻译其依赖注入式字段如可选的StatsRecorder、PIIRedactor、RouterDecisions允许工具在相应能力未启用时优雅返回「unavailable」错误而非崩溃。为什么用提示词强制确认而非代码闸门设计上选择了 KISS每类变更工具都由一条安全规则prompts/10_safety.md 规则 1约束——LLM 在调用前必须先以自然语言复述「用哪个工具、改哪个目标、带什么参数」并等待用户下一轮显式确认Yes/do it/go ahead/proceed都算确认其余一律不算。代码里不存在plan_*/apply_*两段式设计。因此新增变更工具时不要在 Go 里追加逐工具的确认逻辑而应把新工具名登记进10_safety.md让 LLM 知道它受确认规则约束。tools.go中的mutatingToolNames名单与该 markdown 由prompts_test.go机械地保持同步。该安全提示词还包含另外四条硬规则共同约束 LLM 行为规则 2 要求变更前先消歧画廊候选多个、同名多版本、后端多变体时编号列出请用户挑选规则 3 要求工具报错时逐字转述错误放进围栏代码块不重试不转述规则 4 禁止凭空捏造标识符——模型名、画廊名、后端名、job id 必须来自本会话之前的工具结果规则 5 规定轮询get_job_status的终止条件为processed: true、cancelled: true或轮询满 30 次三者先到为准并始终向用户总结最终结果。独立部署local-ai mcp-server子命令core/cli/mcp_server.go 实现了独立运行形态其命令行参数与环境变量如下参数环境变量默认值说明--targetLOCALAI_MCP_TARGEThttp://localhost:8080目标 LocalAI 的 base URL--api-keyLOCALAI_API_KEY—访问目标 LocalAI 的 Bearer API key--read-only—false跳过全部变更工具install/delete/edit/upgrade 等只读浏览远程状态该命令用httpapi.New(target, apiKey)构造 clientReadOnly映射为Options.DisableMutating随后以mcp.StdioTransport运行宿主导管如 Claude Desktop、Cursor、mcphost通过 JSON-RPC 与进程的 stdin/stdout 通信因此 stdout 被明确定义为「神圣通道」——除协议数据外的任何输出都会污染传输其余日志必须走 stderr。进程用signal.NotifyContext监听 SIGINT/SIGTERM保证 Ctrl-C 或kill -TERM时srv.Run有机会排空在途调用后再退出。分布式模式下的边界契约文档明确划定了分布式模式的边界内存态 MCP Server 只运行在主节点head node上——因为聊天处理器就在主节点。inproc.Client包装的服务本身已具备分布式感知GalleryService会与 worker 协调安装ListNodes读取的是 NATS 填充的节点注册表。MCP 工具不做 NATS 路由管理面整体驻留主节点没有例外。这也意味着list_nodes、list_scheduling、set_scheduling、set_node_vram_budget等联邦工具在单进程部署下会被 inproc 客户端报告为不可用或仅主节点有意义。小结LocalAI Assistant 管理面是一条「REST 端点 → MCP 工具 → Skill 提示词」三层咬合的生产级链路以pkg/mcp/localaitools/单一公开包承载全部工具与提示词以LocalAIClient接口隔离进程内直连与远程 HTTP 两种实现以常量、强类型与机械性测试对抗三层之间的漂移并以「提示词内确认规则」替代繁琐的代码闸门。无论是作为人类开发者扩展新管理能力还是作为 Agent 理解该 MCP Server 的接入方式.agents/localai-assistant-mcp.md 与上述源码文件共同构成了完整、可验证的权威参考。【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考