必看!MCP 實(shí)現(xiàn)原理,小白也能懂
不知道大家有沒有發(fā)現(xiàn)?對(duì)于添加到 MCP 服務(wù)市場(chǎng)的成千上萬個(gè) MCP 服務(wù)(而且這個(gè)數(shù)字每天還在增加),我們可以不寫一行代碼,輕松實(shí)現(xiàn)調(diào)用,但背后的原因究竟是啥呢?
MCP 雖然用起來很方便,但搞不懂背后的實(shí)現(xiàn)原理,總感覺這個(gè)知識(shí)點(diǎn)還沒完全掌握,所以接下來,我們一起來看它的實(shí)現(xiàn)原理。
從某個(gè) MCP 的調(diào)用說起
在調(diào)用某個(gè) MCP 服務(wù)的時(shí)候,只需要在 json 配置文件中添加一段 MCP 服務(wù)廠商提供的 json 信息就可以實(shí)現(xiàn)服務(wù)調(diào)用了。
例如要調(diào)用百度地圖提供的 8 大核心功能:地理編碼、逆地理編碼、地點(diǎn)檢索、路線規(guī)劃、天氣查詢、IP 定位等功能時(shí),我們只需要添加以下 json 就能輕松調(diào)用了:
{
"mcpServers": {
"baidu-map": {
"command": "npx",
"args": [
"-y",
"@baidumap/mcp-server-baidu-map"
],
"env": {
"BAIDU_MAP_API_KEY": "xxx"
}
}
}
}
執(zhí)行結(jié)果如下:
要搞明白調(diào)用的實(shí)現(xiàn)原理,我們需要先從 json 配置文件說起,以上配置文件是 nodejs 的調(diào)用命令,其中“npx”是 “npm execute package” 的縮寫,它的主要功能是運(yùn)行一個(gè)包中的可執(zhí)行文件,而無需先將其全局安裝或添加到項(xiàng)目的依賴中,此時(shí)我們使用傳統(tǒng)的 npm 使用方式,將百度提供的依賴下載到本地:
源碼分析
我們查看其源碼就可以發(fā)現(xiàn):
其主要文件 dist/index.js 的核心源碼如下:
// 啟動(dòng)一個(gè) stdio 服務(wù)器
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Baidu Map MCP Server running on stdio");
}
// 查詢天氣的工具實(shí)現(xiàn)
async function handleWeather(districtId, location) {
const url = new URL("https://api.map.baidu.com/weather/v1/");
url.searchParams.append("data_type", "all");
url.searchParams.append("coordtype", "bd09ll");
url.searchParams.append("ak", BAIDU_MAP_API_KEY);
url.searchParams.append("from", "node_mcp");
if (location) {
url.searchParams.append("location", location);
}
if (districtId) {
url.searchParams.append("district_id", districtId);
}
const response = await fetch(url.toString());
const data = await response.json();
if (data.status !== 0) {
return {
content: [{
type: "text",
text: `Weather searth failed: ${data.message || data.status}`
}],
isError: true
};
}
return {
content: [{
type: "text",
text: JSON.stringify({
location: data.result.location,
now: data.result.now,
forecasts: data.result.forecasts,
forecast_hours: data.result.forecast_hours,
indexes: data.result.indexes,
alerts: data.result.alerts,
}, null, 2)
}],
isError: false
};
}
從以上源碼我們可以大致看出,百度作為 MCP 服務(wù)提供商,幫我們做了以下這些事:
- 啟動(dòng) stdio 服務(wù)端,等待 MCP 客戶端連接。
- 當(dāng)檢測(cè)到客戶端的通訊請(qǐng)求之后,它通過 HTTP 協(xié)議請(qǐng)求自己服務(wù)器的信息,再將返回結(jié)果以 stdio 方式發(fā)送給 MCP 客戶端。
到這里,我們就搞明白了,之所以 MCP 使用比較簡(jiǎn)單,原因是每家 MCP 服務(wù)廠商,幫我們實(shí)現(xiàn)了服務(wù)的具體調(diào)用。
并且他們遵循了 MCP 通訊協(xié)議,因此我們只需要使用 MCP Client 簡(jiǎn)單調(diào)用就可以實(shí)現(xiàn)某個(gè)功能了,它的具體執(zhí)行流程如下:
小結(jié)
MCP 只使用調(diào)用簡(jiǎn)單是每家 MCP 廠商幫我們實(shí)現(xiàn)了服務(wù)調(diào)用的細(xì)節(jié),并且遵循了 MCP 協(xié)議,開啟了 stdio 本地線程通訊的服務(wù),讓我們可以輕松的通過 MCP 客戶端進(jìn)行調(diào)用了。所以,你能自己實(shí)現(xiàn)一個(gè) MCP 帶 UI 的客戶端嗎?