給有多應用需求的開發者:如何用 Microsoft CopilotKit 讓現有 App 變身 MCP Host

Published on: | Last updated:

這可能是你聽過最大的誤解:「把 AI 接進 App = 放一個聊天框,然後它就會自己變聰明」。不會。聊天框只會讓它更會聊天,不會讓它更懂你資料庫裡那堆鬼東西。

真的會讓 AI「懂你家資料」的,是把 App 的資料和工具用一個規矩接起來。Model Context Protocol(MCP)就是那個規矩;Microsoft 的 CopilotKit則是把 MCP 快速塞進 Next.js 的工具包,讓你的 App 直接變成一個 MCP host,能跟 MCP server 對話、拉資料、跑工具,而且還能控權限。

  • 你想要的不是「AI 回答」,而是 AI 真的能「查得到」你 App 的資料
  • MCP 的角色:在 AI 跟你的資料/工具之間,當一個有規格的「中介層」
  • CopilotKit 的角色:把 MCP 連線、Runtime、Chat UI 這些零件直接裝好
  • 最短路徑:Next.js + CopilotKit CLI + 一個 MCP server(現成或自架)
  • 進階可玩:MCPToolCall 把工具呼叫的輸入/輸出攤開來看
把「會聊」變成「會做事」的路徑(總覽)
把「會聊」變成「會做事」的路徑(總覽)

先把名詞釐清:MCP 不是模型,是一套「接線規格」

MCP(Model Context Protocol)是一個開放標準,用來讓 AI 透過一致的協定安全地存取應用程式資料與工具;MCP 把「模型端」和「資料/工具端」的溝通方式標準化,降低整合成本並提高可控性。

我用偵探口吻講:你要查的不是「AI 聰不聰明」,你要查的是「它到底有沒有拿到線索」。

很多人以為把 LLM 接上去就完事,結果 AI 回你一堆看似合理的話,但那種合理很像偵探小說裡的路人推理:聽起來很順,證據呢?沒有。

講到「中介層」這個詞,我突然想到以前看 API Gateway 的架構圖,大家都說要控流量、控權限、控審計;MCP 的味道其實很像,只是它控的是「模型能看什麼、能做什麼」,不是你一般的 HTTP 流量。好,拉回來。

MCP 讓你可以做什麼?原文講得很直白,我翻成比較不假掰的版本:

  • 安全地讓 AI 進你資料:不是把資料整包丟給模型,是透過協定讓它「被允許地查」
  • 做出像內建一樣的功能:使用者覺得 AI 就住在你的 App 裡,不是外掛
  • 鎖好門:該看的才看、該做的才做,不要變成「順便把公司資料送出去」的事故

AI 會不會亂講是一回事;你有沒有把它能查的證據和能用的工具規範好,才是另一回事。

CopilotKit 在幹嘛:把 MCP 變成「你可以用的形狀」

CopilotKit 是一套開源工具,提供 Next.js 的整合腳手架、Chat 介面與 Copilot Runtime,讓你用 MCP 連到 MCP server,快速把「工具呼叫 + 資料存取」做進你的 App。

你如果問我它像什麼:像一盒樂高,而且是那種你不需要先去買螺絲起子就能拼的。你只要照步驟卡扣下去,基本形就有了。

它給你的東西大概兩塊:

  • 後端那條線:把你的 App 接到 MCP server(你用別人的或自己架都行)
  • 前端那個嘴:一個聊天介面,讓使用者直接跟 AI 互動

然後你會開始懷疑:那我到底是在做 App,還是在做一個「可被工具呼叫的世界」?嗯…兩個都算。

CopilotKit + MCP 的核心零件拆解(中段核心拆解)
CopilotKit + MCP 的核心零件拆解(中段核心拆解)

最快上手:Next.js + CopilotKit CLI + 一個 MCP Server

在 Next.js 專案中使用 CopilotKit CLI 初始化 MCP(npx copilotkit@latest init -m MCP),再連上一個 MCP server,最後用 npm run dev 啟動,就能在本機看到聊天視窗並讓 AI 透過 MCP 使用你 App 的資料與工具。

步驟就三個半:我知道你想要「一句指令搞定」,但現實通常是「三句」。也還行啦。

Step 1:你要先有 Next.js

npx create-next-app@latest

如果你本來就有 Next.js 專案,這段就當沒看到。

Step 2:用 CopilotKit CLI 把 MCP 的骨架裝進來

npx copilotkit@latest init -m MCP

這一步其實就是「把該有的東西放到該在的位置」,你不做也行,你就自己慢慢接。很硬。真的很硬。

Step 3:你需要一個 MCP server

原文提到兩條路:

  • 拿現成的:像 Composio 這類有提供 ready-to-roll 的 MCP servers(你就是先求快)
  • 自己架:想控得很細、想內網跑、想做審計,那就自架

Step 4:跑起來看看

npm run dev

打開本機頁面後,你會看到聊天窗。你輸入問題,AI 回你,而且回的內容會「看起來」跟你的 App 有關。

注意喔,這邊的偵探問題來了:它到底是真的查了資料,還是只是很會掰?

所以你下一步通常不是「再調 prompt」,而是要把工具呼叫的過程攤開來看。

現成 MCP Server vs 自架 MCP Server(轉折比較)
現成 MCP Server vs 自架 MCP Server(轉折比較)

我最愛的那段:用 MCPToolCall 把「作案過程」打開給你看

CopilotKit 的 MCPToolCall 元件可以把工具呼叫的狀態、參數(args)與結果(result)用可點開的 UI 顯示,方便你確認 MCP server 真的有被呼叫、呼叫了什麼、回了什麼。

這段超像辦案:你不要只看「嫌犯口供」(AI 回答),你要看「監視器畫面」(tool call inputs/outputs)。不然你會被騙得很開心。

原文的元件大概做了幾件事:

  • Props 很直白:status / name / args / result
  • 可折疊:點一下才展開細節,不會整頁都是 JSON
  • format 函式:把 JSON 轉漂亮、把跳脫字元清乾淨,讓你看得懂
  • 狀態點點:執行中會閃,完成就穩,嗯…很人類很焦慮

原文程式碼我幫你原封不動留著(你要改也好改):

"use client";

import * as React from "react";

interface ToolCallProps {
  status: "complete" | "inProgress" | "executing";
  name?: string;
  args?: any;
  result?: any;
}

export default function MCPToolCall({
  status,
  name = "",
  args,
  result,
}: ToolCallProps) {
  const [isOpen, setIsOpen] = React.useState(false);

  // Format content for display
  const format = (content: any): string => {
    if (!content) return "";
    const text =
      typeof content === "object"
        ? JSON.stringify(content, null, 2)
        : String(content);
    return text
      .replace(/\\n/g, "\n")
      .replace(/\\t/g, "\t")
      .replace(/\\"/g, '"')
      .replace(/\\\\/g, "\\");
  };

  return (
    
setIsOpen(!isOpen)} > {name || "MCP Tool Call"}
{isOpen && (
{args && (
Parameters:
                {format(args)}
              
)} {status === "complete" && result && (
Result:
                {format(result)}
              
)}
)}
); }

有時候你會看到 args 裡面其實根本沒帶你以為會帶的條件,或 result 回來是一坨空值。

那種時候你才知道,問題不是「模型不夠大」,問題是「線索根本沒送到」。

要不要自架 MCP Server?看你是想睡覺,還是想掌控

CopilotKit 支援用 Copilot Runtime 自行建立 MCP client(透過 createMCPClient)並在 Next.js 設定 /api/copilotkit endpoint;自架提供更高控制力但需要更多設定,而 Copilot Cloud 則偏向即開即用。

原文把路線分兩種:

  • Self-hosted:你全管,包含聊天、歷史、狀態;你也全背鍋(更新、維運、資安)
  • Copilot Cloud:像訂閱串流平台,打開就能看;你少操心,但可調的東西相對少

講到「少操心」,我腦袋就自動跳去那種凌晨兩點 on-call 的畫面。嗯。不要。

如果你想自架,原文給了一個 runtime 配置範例:

import {
  CopilotRuntime,
  OpenAIAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} from "@copilotkit/runtime";
import { NextRequest } from "next/server";

const serviceAdapter = new OpenAIAdapter();

const runtime = new CopilotRuntime({
  createMCPClient: async (config) => {
    // Implement your MCP client creation logic here
    // See the MCP SDK docs for implementation details
  },
});

export const POST = async (req: NextRequest) => {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    serviceAdapter,
    endpoint: "/api/copilotkit",
  });

  return handleRequest(req);
};

這段在講什麼?

  • createMCPClient你要在這裡寫「怎麼連到 MCP server」的邏輯(細節去看 MCP SDK)
  • OpenAIAdapter讓 runtime 能跟 OpenAI 類的模型服務協作;你也可以換別的模型 adapter
  • /api/copilotkit前端丟過來的請求會打到這裡,再由 runtime 處理

自架不是比較帥,是比較可控;可控不是比較爽,是比較不會在出事時找不到兇手。

分眾決策:你是哪種人,就走哪條路(If This Then That)

選 Copilot Cloud、現成 MCP server 或自架 MCP server,取決於你對上線速度、控制權與維運負擔的取捨;最快是 CopilotKit CLI + 現成 MCP server,最可控是自架 MCP server + Copilot Runtime。

好,來點群組式的「對號入座」:

  • 如果你是「外包/接案/小團隊快交付」:先用 CopilotKit + 現成 MCP server,目標是 1 天內看到能用的 demo。先活下來再說。
  • 如果你是「公司內部工具、資料敏感」:偏向 自架 MCP server 或至少把 MCP server 放在你能控的環境,然後一定要用 MCPToolCall 做可觀測性,不然你會被問爆。
  • 如果你是「夜班維運/被 on-call 折磨的人」:先選 Copilot Cloud,你少一個服務要顧。睡覺比較實在。
  • 如果你是「喜歡把旋鈕轉到最滿的工程師」:Copilot Runtime 自架,你會得到掌控感,也會得到更多設定檔。嗯,祝福。
  • 如果你是「產品/PM 想驗證需求」:先上線一個最小可行:聊天窗 + 1~2 個工具呼叫就好,別一開始就做成宇宙戰艦。

你看,沒有哪條是「最正確」。只有哪條比較符合你現在的體力。

我現在體力偏低,所以我會先選能跑的那條。

最後一張:你該選哪條路(結尾前總結)
最後一張:你該選哪條路(結尾前總結)

最後留一句:把 AI 變成你 App 的夥伴,不靠嘴砲,靠證據鏈。

Related to this topic:

Comments