跳到正文
DEV Community· thinslatelabs·· 3 小時前AI 評分57

Keepp 團隊分享 Claude 和 ChatGPT 透過 MCP 編輯公開網站的六項經驗

What We Learned Letting Claude and ChatGPT Edit Live Websites Over MCP

AI 導讀

Keepp 團隊分享讓 Claude 和 ChatGPT 透過 MCP 編輯公開網站的實作經驗,並整理六項伺服器設計做法。核心做法包括以版本檢查阻止過期頁面覆寫、把完整區塊目錄放入 MCP resource,並在寫入時下載及儲存圖片。伺服器亦為各工具回傳結構化結果和安全提示,按用戶端篩選工具;創作者可連接 Keepp,要求助理建立商店、預約頁或聯絡表單並取得公開連結。

正文

We run Keepp, a link in bio and website builder for creators and small businesses: one page that holds a website, selling, bookings, forms and chat. A few weeks ago we shipped an MCP server so Claude and ChatGPT can build and edit those pages directly. A person says "add my new class times and a booking button" in a chat, and the assistant changes a real, public page.

That is a different job from most MCP servers, which read data or run a search. Ours writes to something strangers will see. Here is what that taught us.

1. Let the model write the whole document, but make stale writes fail

Our first instinct was a dozen small tools: add a block, move a block, change a colour. Models were bad at it. They lost track of order, half-applied changes, and made the page inconsistent.

What worked was one tool, put_page, that replaces the whole page document. The model calls get_page, edits what it got back, and sends the complete list of blocks. Anything left out is deleted, and the tool description says so plainly.

The risk is obvious: the owner edits the page in the editor while the assistant is mid-change, and the assistant overwrites it. So every get_page returns a version, put_page requires it, and a write against an old version fails with a clear error instead of silently winning. Optimistic concurrency turned out to be the single most important guard on the whole server.

2. Keep the schema out of every tool listing

A page has many block types, each with its own fields. Putting all of that in the put_page input schema bloated every tool listing the host sent to the model, on every turn.

We moved the full block catalogue into an MCP resource. The tool description points at it, so the model reads it once when it needs it, rather than carrying it in every request. Tool listings stayed small and the model still had every field when it built a page.

3. Never trust a URL the model gives you

Models love to put image URLs straight into a page, often from wherever they found them. That makes the public page depend on someone else's server, and some of those images vanish a day later.

Every image URL in a write is now downloaded and stored on our side as part of the write. If one cannot be fetched, the whole write fails and names the block. The model gets told exactly what went wrong and usually fixes it on the next try.

4. Return structured results on every path

Hosts handle tool results differently. Some only show the model the text content, some read structuredContent. We declare an outputSchema on every tool and return structured content on every success path, with a readable sentence in the text as well. A test fails the build if any tool is missing either.

The same goes for safety hints. Each tool declares whether it is read-only, destructive, or touches the outside world, from one table in the codebase, so hosts can decide when to ask the user first.

5. OAuth for native clients needs loopback on any port

Remote MCP over OAuth worked first time in browser hosts. It broke for native clients like Claude Code, which sign in through a callback on localhost with a random port. Our redirect check wanted an exact match.

The fix is in the spec for native apps: loopback redirect URIs are allowed on any port. Once we accepted that, sign-in worked everywhere. Client ID Metadata Documents also meant we did not need dynamic client registration for the hosts we cared about.

6. Different hosts need different tool sets

Not every host wants every tool. Some app directories do not allow selling subscriptions inside the assistant, so for those clients we hide the plan tools entirely rather than letting them fail. Filtering by client at listing time is cleaner than refusing at call time.

What it looks like in practice

The result is that a creator can open Claude or ChatGPT, connect Keepp once, and say what they want: a shop with three products, a booking page for sessions, a contact form and a chat. The assistant reads the catalogue, writes the page, and gets back the live URL and a link for each part that opens as its own page.

If you are building an MCP server that writes to anything public, the short version is: give the model whole documents with a version check, keep big schemas in resources, own every asset it hands you, and return structured results everywhere.

Our developer docs, including how to connect the MCP server, are at keepp.link/developers. Keepp itself is at keepp.link.

來源:DEV Community · dev.to