本地大模型不仅能聊天,还可以通过工具完成文件检索、数据库查询和业务接口调用。Ollama 已支持函数调用,而 MCP(Model Context Protocol)负责以统一协议暴露外部能力。把两者连接起来,就能组成“本地模型负责决策、MCP Server 提供工具、客户端负责调度”的可扩展方案。🧩
一、先理解整体调用链路
MCP 是连接大模型应用与外部数据源、工具服务的开放协议,服务器可以提供 Tools、Resources 和 Prompts 等能力,具体定义可参考 MCP 官方规范。Ollama 的作用是运行本地模型,并通过聊天接口返回结构化的工具调用请求。
一次完整调用通常包含以下环节:
- 客户端启动或连接 MCP 工具服务器。
- 客户端通过 tools/list 获取工具名称、描述和参数结构。
- 客户端把这些工具转换成 Ollama 接受的 function schema。
- 本地模型根据用户问题决定是否调用工具。
- 客户端执行对应的 MCP 工具,并收集返回结果。
- 工具结果以 role 为 tool 的消息再次发送给模型。
- 模型结合结果生成最终的自然语言回答。🔄
需要特别注意:模型只负责生成“调用哪个工具、传入什么参数”的决定,真正执行文件读写、网络请求或数据库操作的是客户端与 MCP Server。
二、准备 Ollama 与支持函数调用的模型
先安装 Ollama,然后拉取支持工具调用的模型。不同模型对参数生成、中文理解和复杂任务规划的表现存在差异,可以优先选择模型页面明确标注支持 tools 的版本。
ollama pull qwen3
ollama serve
服务启动后,默认本地 API 地址通常为 来源链接
curl 来源链接 -d '{"model":"qwen3","messages":[{"role":"user","content":"你好"}],"stream":false}'
Ollama 的 tools 参数采用类似 JSON Schema 的函数描述,模型的响应中则可能出现 tool_calls 字段。单工具、并行工具以及多轮工具循环的格式,可以查看 Ollama 工具调用文档。
三、启动一个 MCP 工具服务器
MCP Server 可以通过 stdio 与本地客户端通信,也可以采用规范支持的远程传输方式。初次实践建议选择 stdio,因为服务器作为子进程启动,不需要额外开放端口,排查日志也更直接。🛠️
以一个提供目录查询能力的服务器为例,客户端配置可以采用如下思路:
{
"command": "npx",
"args": ["-y", "某个MCP服务器包", "D:/workspace"]
}
这里的包名应替换为实际选用且经过审查的 MCP Server,目录参数则应限制在允许访问的工作区。不要为了省事把整个系统盘、用户主目录或包含密钥的目录直接开放给工具。
四、编写 Ollama 与 MCP 之间的桥接层
桥接程序是配置实战的核心。它既是 MCP Client,也是 Ollama API 的调用方。以 Python 为例,可以安装 Ollama SDK 与 MCP SDK:
python -m pip install -U ollama mcp
连接 MCP Server 后,先调用 list_tools。对于每个 MCP Tool,将 name、description 和 inputSchema 映射成 Ollama 工具定义:
{
"type": "function",
"function": {
"name": tool.name,
"description": tool.description,
"parameters": tool.inputSchema
}
}
随后,把转换后的工具列表和用户消息提交给 Ollama:
response = ollama.chat(
model="qwen3",
messages=messages,
tools=ollama_tools
)
如果 response.message.tool_calls 不为空,就根据 function.name 查找对应 MCP 工具,并把 function.arguments 作为参数执行:
result = await session.call_tool(
call.function.name,
call.function.arguments
)
执行结束后,应先把模型产生的 assistant 消息加入历史记录,再追加工具结果。工具返回内容建议统一序列化为字符串,避免对象类型无法被 SDK 正确处理:
messages.append(response.message)
messages.append({
"role": "tool",
"tool_name": call.function.name,
"content": str(result.content)
})
最后再次调用 ollama.chat。如果模型继续返回 tool_calls,就继续循环;如果返回普通 content,则结束任务并展示答案。实际项目中应设置最大循环次数,例如 5 次,防止模型不断调用工具而无法退出。♻️
五、常见故障与排查方法
模型始终不调用工具
首先确认所用模型支持工具调用,其次检查工具描述是否具体。与其写“执行查询”,不如写“根据文件名关键词搜索指定工作目录,并返回匹配文件路径”。参数中的 required、type 和 properties 也必须保持一致。
MCP 工具能列出但执行失败
检查服务器启动命令、运行目录、环境变量和参数路径。stdio 模式下,MCP Server 不应把普通调试信息写入标准输出,否则可能破坏 JSON-RPC 消息;日志应输出到标准错误或独立文件。
工具结果返回后模型不作答
重点检查消息顺序是否为 user、assistant tool_calls、tool result。还要保证 tool_name 与模型请求的函数名完全一致,并保留模型原始的 assistant 消息。缺少其中任一步,都可能让模型无法理解结果来自哪个工具。
六、安全与工程化建议
- 执行前校验:只允许调用白名单中的工具,并使用参数 Schema 做二次验证。
- 最小权限:文件工具限定工作目录,数据库账号只开放必要的查询或写入权限。
- 敏感操作确认:删除文件、执行命令、发送消息和修改数据前增加人工确认。
- 控制输出:限制工具结果长度,避免大文件或超长查询结果挤占模型上下文。
- 记录审计日志:保存请求时间、工具名称、参数摘要、执行状态与耗时,但不要明文记录令牌和密码。🔐
总结
Ollama 接入 MCP 的关键并不是修改模型本身,而是实现可靠的桥接层:发现 MCP 工具、转换函数 Schema、识别 tool_calls、执行服务器工具,再把结果送回本地模型。完成这条闭环后,不同 MCP Server 就能像插件一样接入同一套本地模型应用。建议先用只读文件查询或计算器工具验证流程,再逐步增加数据库、内部接口和自动化操作,从而兼顾扩展能力、稳定性与安全性。🚀