【编程干货】本地用 Ollama + LLaMA 3 实现 Model Context Protocol(MCP)对话服务

2025-04-30 09:59:01技术分享

模型上下文协议(MCP)本身提供的是一套标准化的通信规则和接口,简化了客户端应用的开发。

MCP 实际上是一套规范,官方把整套协议分成「传输层 + 协议层 + 功能层」三大块,并对初始化握手、能力协商、数据/工具暴露、安全约束等均给出了约束性 JSON-Schema。

基于 JSON-RPC 2.0 的开放协议,目标是像 USB-C 一样为 LLM 应用提供统一“插槽”。它定义三方角色——Host(应用)/Client(适配层)/Server(能力提供者),通过标准消息把 资源、工具、提示模板 等上下文按需送进 LLM,同时保留“人-机共管”审批流程,实现安全、可组合的本地或远程代理体系。

但是,需要注意,不要连接不信任的 server,MCP 没有在数据安全上提供任何保障。

下面我们可以实现一个最简的 MCP 服务。

0 先决条件

软件

版本建议

作用

操作系统

Windows 10/11、macOS 13+ 或任何较新的 Linux

仅需能运行 Ollama

Ollama

≥ 0.1.34

本地大语言模型后端

Python

3.10 – 3.12

运行 FastAPI 服务

Git

最新

克隆或管理代码

CUDA 12+(可选)

若使用 NVIDIA GPU

提升推理速度

CPU 也可运行,但 LLaMA 3-8B 在 GPU 上体验最佳。

 

1 安装 Ollama 并拉取 LLaMA 3

# 1.1 安装(macOS / Linux)
curl -fsSL https://ollama.com/install.sh | sh
# Windows 请下载 .msi 并双击安装

# 1.2 启动后台(首次安装会自动启动)
ollama serve

# 1.3 拉取 8B 模型(约 4.7 GB)
ollama pull llama3:8b

 

2 创建最小可用的 MCP 后端

2.1 目录结构

mcp-ollama/
│
├── app/
│   ├── main.py # FastAPI 入口
│   ├── mcp.py # 协议封装
│   └── store.py # 简易上下文存储
└── requirements.txt

 

2.2 requirements.txt

fastapi==0.110.*
uvicorn[standard]==0.29.*
httpx==0.27.*
python-dotenv==1.0.*

 

2.3 MCP 协议封装(app/mcp.py)

from typing importList, Dict

defbuild_prompt(history: List[Dict[str, str]], user_msg: str) -> str:
    """
    把历史消息与当前输入拼接成大模型 prompt。
    MCP 规定 key 为 role / content,与 OpenAI messages 一致。
    """
    lines = []
    for msg in history:
        lines.append(f"{msg['role'].upper()}: {msg['content']}")
    lines.append(f"USER: {user_msg}")
    return"\n".join(lines)

SYSTEM_PROMPT = (
    "You are an AI assistant that follows instructions precisely. "
    "Answer in the same language as the question."
)

 

2.4 上下文存储(app/store.py)

from collections import defaultdict, deque

_MAX_TURNS = 8 # 只保留最近 8 轮
_history = defaultdict(lambda: deque(maxlen=_MAX_TURNS))

def add_msg(session_id: str, role: str, content: str):
    _history[session_id].append({"role": role, "content": content})

def get_history(session_id: str):
    return list(_history[session_id])

 

2.5 FastAPI 入口(app/main.py)

import os, uuid, httpx
from fastapi import FastAPI
from pydantic import BaseModel
from app.mcp import build_prompt, SYSTEM_PROMPT
from app.store import add_msg, get_history

OLLAMA_URL = os.getenv("OLLAMA_URL", "http://localhost:11434")

classChatReq(BaseModel):
    session_id: str | None = None
    message: str

classChatResp(BaseModel):
    session_id: str
    answer: str

app = FastAPI(title="MCP Demo")

@app.post("/chat", response_model=ChatResp) async def chat(req: ChatReq):
    sid = req.session_id orstr(uuid.uuid4())
    history = get_history(sid)
    prompt = f"{SYSTEM_PROMPT}\n{build_prompt(history, req.message)}"
    payload = {"model": "llama3:8b", "prompt": prompt, "stream": False}
    asyncwith httpx.AsyncClient() as client:
        r = await client.post(f"{OLLAMA_URL}/api/generate", json=payload, timeout=120)
        r.raise_for_status()
        ans = r.json()["response"]
    add_msg(sid, "user", req.message)
    add_msg(sid, "assistant", ans)
    return ChatResp(session_id=sid, answer=ans)

 

2.6 运行服务

pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000

 

3 验证接口

# 第一次调用
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message":"Hello, what is MCP?"}' # 记录返回的 session_id

# 带历史上下文的第二次调用
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"session_id":"<上一步返回的id>","message":"Explain in Chinese."}'

你将看到回答中自动继承了第一轮对话,上下文逻辑即生效。

 

我们的官网

https://www.ai360labs.com


 

加入群聊

点击底部分享、赞和在看,把好内容传递出去!