supp.fit 提出避免 AI 助手誤讀 MCP 工具的七項規則
Seven rules for MCP tools that an AI assistant cannot misread
supp.fit 團隊整理其 MCP 伺服器的七項設計規則,旨在減少 AI 助手選錯工具、誤解空值或錯誤處理數據。伺服器將 40 多個 API 端點整合為 13 個工具,並要求説明空值含義、避免跨單位加總或轉換,以及區分研究劑量與建議劑量。其他做法包括採用唯讀工具、按資料所有者拆分 OAuth 權限,並以研究摘要和 PubMed 連結取代受授權限制的論文全文。
An MCP server is an API whose reader is a language model. The model reads your tool list, picks a tool, and repeats what comes back to a person. It does not read your docs, it does not ask follow-up questions, and it fills every gap with a guess.
We built the MCP server for supp.fit, a database of supplement evidence from randomized controlled trials. The data is easy to misread in ways that matter: doses in different units, labels that could not be matched, intake logs with missing days. Here are the rules we ended up with. They hold for any MCP server, not only for health data.
1. Fewer tools than endpoints
Our API has more than forty endpoints. The MCP server exposes thirteen tools.
A model chooses a tool from its name and its description. When two tools differ by one word, it picks one at random. So we merged endpoints into tools that each answer one kind of question: search a supplement, get one supplement, get its study protocols, get the studies behind one benefit, get one study, search products, get one product, and six tools for the person's own data.
Rule: one tool per question a user asks, not one tool per route.
2. Say what absence means
Two of our fields can be empty for opposite reasons.
- A product without a Supplement Facts panel usually means the barcode could not be matched to a registered label. It does not mean the product has no ingredients.
- A date without an intake answer means nobody answered. It does not mean the dose was missed.
In the data, both look like "nothing". A model will happily say "this product contains nothing" or "you skipped 12 days". So the tool description says it in words:
When has_confirmed_label is false there is no panel, and that means
the match could not be confirmed. It does NOT mean the product has no
ingredients. Never tell a reader a product contains nothing.
Rule: for every field that can be empty, write one sentence that says what the emptiness means.
3. Forbid the arithmetic the model will try
Dose data comes in IU, mg, capsules and millilitres. A model sees numbers and adds them. It also converts IU into milligrams with a guess.
Our descriptions say: each amount keeps its own unit; do not add amounts across units or items; do not convert IU into a mass. The consumption tool returns figures grouped per item and per unit, so there is nothing safe to add.
Rule: if a sum or a conversion would be wrong, say so in the description and shape the response so that the wrong sum is hard to make.
4. Separate "what was studied" from "what to take"
Study groups took a daily dose. Product labels print a dose per serving. Neither is a recommendation.
The tool returns both, with the median, the middle half and the most common band, and the description calls them "printed and studied amounts, not a recommended dose". The model can now answer "what did the trials use?" without turning it into advice.
Rule: name the source of every number in the field name and in the description.
5. Read-only, and say it
Every tool is read-only, and the server has no write path to the database. The server keeps no secret of its own either. It passes on the token the client was issued, and the API decides what that token may read.
This is a security property, but it also helps the model. With no write tools in the list, it never offers to "add this to your stack".
Rule: if a server cannot change anything, it should not list a tool that sounds as if it can.
6. Split scopes by whose data it is
We have two OAuth scopes: evidence.read (supplements, studies, products, nothing about the person) and me.read (the person's stack, history and intake log). They are separate checkboxes on the consent page, so a person can share the evidence half and keep the personal half.
Every tool needs a signed-in account, even the ones that read public evidence. The reason: an assistant mixes both halves in one answer ("what do the studies say, and what am I taking?"). One rule for every tool can be tested. A rule per tool is something someone forgets.
Rule: scope by owner of the data, and keep one auth rule for all tools.
7. Return a summary and a link, not licensed text
Full paper text is licensed, so no tool returns it. The study tool returns the title, year, participant count, our summary and the PubMed link. The model can name the paper and the reader can check it.
Rule: give the model enough to cite, and a link for the person to verify.
The connection itself
The server speaks Streamable HTTP and is stateless: no session id, no event stream. A client needs only the endpoint and follows the OAuth 2.1 sign-in:
{
"mcpServers": {
"supp-fit": {
"type": "http",
"url": "https://mcp.supp.fit/mcp"
}
}
}
Summary
| Rule | Why |
|---|---|
| Fewer tools than endpoints | The model picks by name and description |
| Say what absence means | Empty fields get read as "none" |
| Forbid wrong arithmetic | Models add numbers across units |
| Name the source of every number | Studied amounts are not advice |
| Read-only, and say it | No tool that sounds like a write |
| Scope by owner of the data | Share evidence without personal data |
| Summary plus link | Cite without copying licensed text |
The server and its full tool list are described at mcp.supp.fit. The evidence it reads is the same as on supp.fit.
For information only, not medical advice.
來源:DEV Community · dev.to