MCP 伺服器
@graftland/plugin-mcp-server
透過 Effect 的 MCP 伺服器提供工具、資源和提示詞。核心釋出
Server,同級傳輸外掛消費它。貢獻外掛載入或卸載時,用戶端無需重新連線。
執行 stdio
Section titled “執行 stdio”- name: "@graftland/plugin-mcp-server" config: { name: notes, version: 1.0.0 }- name: "@graftland/plugin-mcp-server/stdio"- name: ./plugins/notes.ts執行 graft start --stdio。使用 Effect.log*
記錄日誌;stdout 屬於協定。範例包含可執行的用戶端設定。
| 條目 | 短名稱 | 職責 |
|---|---|---|
@graftland/plugin-mcp-server |
mcp-server |
釋出伺服器選項 |
@graftland/plugin-mcp-server/stdio |
mcp-server/stdio |
執行 Effect 的 stdio 伺服器 |
@graftland/plugin-mcp-server/http |
mcp-server/http |
掛載 Streamable HTTP 路由 |
提供 HTTP
Section titled “提供 HTTP”將共用的 HTTP 路由器和監聽器與核心放在一起,並以一個長期執行的
graft start
執行這份設定。stdio 放在單獨的設定中:MCP 用戶端每個工作階段啟動一個 stdio 行程,固定連接埠會衝突。兩份設定可以列出相同的貢獻外掛。
- name: "@graftland/plugin-http/router"- name: "@graftland/plugin-http" config: { port: 8080 }- name: "@graftland/plugin-mcp-server" config: { name: notes, version: 1.0.0 }- name: "@graftland/plugin-mcp-server/http" config: path: /mcp allowedOrigins: [https://app.example.com]- name: ./plugins/notes.ts| 欄位 | 預設值 | 規則 |
|---|---|---|
path |
/mcp |
共用路由器上的端點 |
allowedOrigins |
無 | 拒絕未明確列出的 Origin;沒有該請求標頭的請求仍可存取 |
authorization.scopes |
無 | 設定後要求共用的 Authorization 服務及全部列出的權限範圍 |
用下方受保護的條目取代上方的 HTTP 條目,並加入 OAuth 外掛。JWT 驗證器還需要已發布的
HttpClient;見 HTTP 授權。
- name: "@graftland/plugin-http/oauth/jwt" config: issuer: https://auth.example.com audience: https://mcp.example.com/mcp jwksUrl: https://auth.example.com/jwks- name: "@graftland/plugin-http/oauth" config: resource: https://mcp.example.com/mcp authorizationServers: [https://auth.example.com]- name: "@graftland/plugin-mcp-server/http" config: path: /mcp authorization: { scopes: ["notes:read"] }| 狀態 | 結果 |
|---|---|
Authorization 缺少或撤回 |
受保護路徑回傳 404 |
| 授權可用,但缺少權杖 | 401,帶 WWW-Authenticate 和受保護資源後設資料 |
| 缺少要求的權限範圍 | 403 insufficient_scope |
| 權杖有效 | Principal 到達工具處理函式,並覆蓋外掛中的同鍵服務 |
| OAuth 外掛載入或卸載 | 未保護的傳輸保持目前啟用狀態 |
| 監聽器連接埠改變 | MCP 路由保持目前啟用狀態 |
| 舊版工作階段 DELETE | 回傳 204,之後存取該工作階段回傳 404。受保護端點仍檢查授權。 |
| 欄位 | 預設值 | 規則 |
|---|---|---|
name, version |
graft, 0.0.0 |
伺服器身分 |
description, websiteUrl, icons, instructions |
無 | Effect 伺服器後設資料 |
protocols |
全部 Effect 介面卡,最新優先 | 包含 2026-07-28 和 2025-11-25;不能為空 |
cache |
無 | discover, tools, resources, resourceTemplates, prompts |
cache.<list>.ttl |
設定時必填 | 非負毫秒數;接受數字或數字字串 |
cache.<list>.cacheScope |
private |
僅支援 private |
resources/read
的快取提示始終為私有,存活時間為零。清單回傳全部條目,不分頁。工具、資源和提示詞即使清單為空,也始終宣告為可用能力。
| 變化 | 結果 |
|---|---|
| 貢獻外掛載入、重新載入或停止 | 清單改變;下次呼叫使用當前處理函式 |
| 貢獻外掛停止 | 中斷其正在執行的呼叫並等待結束 |
| 同一清單中的兩個貢獻衝突 | 隱藏所有衝突貢獻;每個傳輸記錄 Conflict |
| 一個貢獻註冊失敗 | 該項保持隱藏;其他項仍然可用 |
| 核心設定改變 | 所有傳輸重啟;用戶端重新連線;貢獻外掛繼續執行 |
| 一個傳輸改變或停止 | 僅重啟或停止該傳輸 |
| 擴充宣告改變 | 記錄警告;該傳輸下次啟動時生效 |
| stdin 結束 | 等待正在執行的工作結束,再由 Application.finish 停止應用 |
取消尚未結束的
subscriptions/listen,stdio 才能在 EOF 後排空。重新載入核心或傳輸不會結束應用。在
graft start 下,Application.claimProtocol
保證 stdio 獨佔。嵌入時,由嵌入方決定誰讀取 stdio。每個行程最多執行一個 stdio 傳輸。
在包含核心、傳輸和貢獻外掛的組上,一起隔離以下七個鍵。所有鍵都帶有
@graftland/plugin-mcp-server/ 字首。
| 鍵字尾 | 型別 | 用途 |
|---|---|---|
Server/Server |
服務 | 每個領域一個核心 |
Catalog/Offered |
事件 | 拉取當前貢獻 |
Catalog/Changed |
事件 | 等待每個投影同步 |
Resources/Updated |
事件 | 通知資源訂閱者 |
Middleware/Middleware |
瀑布流 | 呼叫策略 |
Middleware/Visible |
事件 | 按請求判斷可見性 |
Extensions/Declared |
事件 | 取得擴充宣告快照 |
import { Array } from "effect"
import { isolate } from "@graftland/plugin-mcp-server/Server"
export const serverIsolation = { isolate: Array.map(isolate, (key) => ({ key })),}在 YAML 中,在組的 isolate 下將每個完整鍵對映到
true。第二個組可以用錨點複用該對映。要向兩個伺服器提供同一個貢獻外掛,在兩個組中都列出它。省略某個鍵就會共享它;省略
Middleware 或 Visible 就會共享對應策略。同一領域中的第二個核心會報
ServiceConflict。
核心、傳輸和貢獻外掛必須執行在同一個行程中。不要放在 Remote 下:Server
攜帶 Effect 層。
兩個組可以共用一個監聽器。保留共用的 HTTP 路由鍵,將七個 MCP 鍵一起隔離:
- name: "@graftland/plugin-http/router"- name: "@graftland/plugin-http" config: { port: 8080 }- name: public id: public group: true isolate: &mcp "@graftland/plugin-mcp-server/Server/Server": true "@graftland/plugin-mcp-server/Catalog/Offered": true "@graftland/plugin-mcp-server/Catalog/Changed": true "@graftland/plugin-mcp-server/Resources/Updated": true "@graftland/plugin-mcp-server/Middleware/Middleware": true "@graftland/plugin-mcp-server/Middleware/Visible": true "@graftland/plugin-mcp-server/Extensions/Declared": true config: - name: "@graftland/plugin-mcp-server" config: { name: notes-public } - name: "@graftland/plugin-mcp-server/http" config: { path: /mcp } - name: ./plugins/search.ts- name: admin id: admin group: true isolate: *mcp config: - name: "@graftland/plugin-mcp-server" config: { name: notes-admin } - name: "@graftland/plugin-mcp-server/http" config: { path: /admin/mcp } - name: ./plugins/search.ts - name: ./plugins/admin.ts