📜 目录(点击瞬移)
- 🌌 MCP 为何物?------ 从"对话"到"上下文"
- 🧠 底层原理:一条 SSE 流如何串起三大洲
- 🏗️ 对 Web 行业的五连击
- 🪄 实战:30 行 JS 搭一个"会自己写代码"的 Next.js 页面
- 🔥 踩坑 & 彩蛋:当 MCP 遇到 CORS、Nginx 与老板的 KPI
- 🚀 尾声:下一站,"模型即后端"?
1. 🌌 MCP 为何物?
官方一句话:
MCP(Model Context Protocol)= HTTP + SSE + JSON-RPC,让大模型"长"在你的 Web 里。
白话翻译:
曾经 | 现在(MCP 加持) |
---|---|
用户 → 前端 → 后端 → OpenAI → 后端 → 前端 | 用户 → 前端 ↔ 大模型(长连接) |
上下文靠开发者手动拼 | 上下文自动累积,像 Git 一样可回滚 |
Token 计费 = 黑盒 | Token 计费 = 实时仪表盘 |
🖼️ 配图:左边是传统"HTTP 回旋镖",右边是 MCP "双向高速公路"。
2. 🧠 底层原理:一条 SSE 流如何串起三大洲
2.1 协议三明治
lua
┌------------┐
│ JSON-RPC │ 业务语义(方法/参数)
├------------┤
│ SSE │ 服务器推送事件(text/event-stream)
├------------┤
│ HTTP/2 │ 复用连接、Header 压缩
└------------┘
2.2 生命周期(伪代码版)
js
// 1. 建立 SSE 流
const eventSource = new EventSource('/mcp');
// 2. 发送 JSON-RPC 请求
eventSource.onopen = () => {
eventSource.send(JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: { capabilities: {} }
}));
};
// 3. 接收增量上下文
eventSource.onmessage = (e) => {
const delta = JSON.parse(e.data);
appendToUI(delta.content);
};
2.3 底层八卦
- 每条 SSE 事件最大 8 KB,再大就拆包(浏览器:我谢谢你)。
- 上下文窗口用 滑动数组 实现,超出长度就
Array.shift()
,像贪吃蛇掉尾巴。 - Token 计数在服务端 逐字累加,前端实时看到账单跳动,心跳也跟着跳。
3. 🏗️ 对 Web 行业的五连击
领域 | 旧玩法 | MCP 新姿势 |
---|---|---|
前端框架 | useEffect 调 API |
useMcp() Hook,上下文即状态 |
低代码 | 拖拽生成死页面 | 拖拽后让模型实时补全逻辑 |
搜索 | 关键字 → 10 条链接 | 关键字 → 模型总结 + 链接 |
IDE 插件 | 补全一行代码 | 直接补全整个 feature 分支 |
运维 | 看日志 | 让模型读日志并自愈(🐍:危险但刺激) |
🎭 配图:一张漫画,React 图标和 GPT 图标手牵手,脚下踩着 Express 说:"兄弟,你歇会儿。"
4. 🪄 实战:30 行 JS 搭一个"会自己写代码"的 Next.js 页面
4.1 目录
app/
├─ api/
│ └─ mcp/
│ └─ route.ts ← SSE 端点
└─ page.tsx ← 前端魔法阵
4.2 服务端:/api/mcp/route.ts
ts
import { NextRequest } from 'next/server';
import { Readable } from 'stream';
export async function GET(req: NextRequest) {
const encoder = new TextEncoder();
const stream = new ReadableStream({
start(controller) {
const send = (data: string) =>
controller.enqueue(encoder.encode(`data: ${data}\n\n`));
// 假装这里连的是真 MCP
send(JSON.stringify({
jsonrpc: '2.0',
id: 1,
result: { greeting: 'Hello MCP, from Next.js Edge Runtime!' }
}));
// 每 2 秒推一次代码补丁
const timer = setInterval(() => {
send(JSON.stringify({
jsonrpc: '2.0',
method: 'textDocument/patch',
params: { code: 'console.log("✨ auto-generated line")' }
}));
}, 2000);
req.signal.addEventListener('abort', () => clearInterval(timer));
},
});
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
},
});
}
4.3 前端:app/page.tsx
tsx
'use client';
import { useEffect, useState } from 'react';
export default function Home() {
const [lines, setLines] = useState<string[]>([]);
useEffect(() => {
const es = new EventSource('/api/mcp');
es.onmessage = (ev) => {
const { params } = JSON.parse(ev.data);
if (params?.code) setLines(l => [...l, params.code]);
};
return () => es.close();
}, []);
return (
<main className="p-8 font-mono">
<h1 className="text-2xl mb-4">🪄 MCP 正在替我写代码:</h1>
<pre className="bg-gray-900 text-green-400 p-4 rounded">
{lines.join('\n')}
</pre>
</main>
);
}
🖼️ 动态图:页面每 2 秒自动追加一行
console.log
,背景是黑客帝国雨。
5. 🔥 踩坑 & 彩蛋
坑 | 原因 | 解药 |
---|---|---|
浏览器 6 条 SSE 并发限制 | HTTP/1.1 规范 | 升级到 HTTP/2,或把多个流复用在同一条 SSE |
Nginx 缓存 60 秒断流 | proxy_buffering=on |
关掉: proxy_buffering off; |
Token 爆炸 | 上下文无限增长 | 前端定期 session.clear() ,像清理浏览器缓存 |
老板 KPI | 想让模型 100% 准确 | 告诉他:模型是概率引擎 ,不是真理机 |
彩蛋:
在 DevTools 的 Console 输入
js
fetch('/api/mcp', { method: 'POST', body: '{"method":"ping"}' })
会看到服务端回你一个 🏓 pong,附带随机一句程序员笑话。
6. 🚀 尾声:下一站,"模型即后端"?
"如果 MCP 继续进化,我们可能会看到:
前端直接
import model from 'gpt://v1'
;后端变成一行
export default model
;而产品经理的 PRD 直接喂给模型,
它吐出前端 + 后端 + 测试 + 上线脚本。"
到那时,Web 行业的岗位 JD 也许只剩下一句:
"会呼吸,能写 prompt。"
🧙♂️ 彩蛋口令
在评论区打出
sql
npx create-mcp-app@latest
即可召唤官方脚手架,一键进入"模型上下文"新世界!