> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirobody.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 内置工具

> Mirobody C++ 引擎默认提供的 MCP 工具

## 概览

Mirobody 默认提供 **9 个内置 MCP 工具**。每个都是 [`res/mcp_tools/`](https://github.com/thetahealth/mirobody/tree/main/res/mcp_tools) 中一个小小的 C++ 文件，在编译时自注册（参见 [添加自定义工具](/zh/tools/adding-tools)）。它们通过 [`/mcp` 端点](/zh/tools/mcp-integration) 暴露给外部客户端，同时也作为 function-call 描述符交给内置 Agent，因此 OpenAI 和 Gemini 客户端可以在本地进程内调用它们。

<Info>
  标注 **需要 auth** 的工具只对已认证的调用者运行 —— 引擎会在分发前解析调用者身份（JWT 或个人 MCP secret）并将其作为 `UserInfo` 注入。无需 auth 的工具（如 `echo` 和 `render_chart`）对任何人都可运行。
</Info>

| 工具                                                  | Auth | 作用                                  |
| --------------------------------------------------- | :--: | ----------------------------------- |
| [`list_files`](#list_files)                         |   ✅  | 列出用户已上传的文件                          |
| [`read_file`](#read_file)                           |   ✅  | 按 `file_key` 读取一个上传文件               |
| [`family_health`](#family_health)                   |   ✅  | 读取用户或已共享护理圈成员的近期 FHIR `Observation` |
| [`whoami`](#whoami)                                 |   ✅  | 确认认证状态并返回 session id                |
| [`recall_memory`](#recall_memory)                   |   ✅  | 检索用户最相关的长期记忆                        |
| [`remember`](#remember)                             |   ✅  | 在长期记忆中存储一条事实                        |
| [`render_chart`](#render_chart)                     |   —  | 在聊天界面绘制图表（Apache ECharts）           |
| [`summarize_conversation`](#summarize_conversation) |   ✅  | 为当前对话设置一个简短标题                       |
| [`echo`](#echo)                                     |   —  | 回显文本（示例 / 连通性测试）                    |

## 文件工具

### list\_files

列出已认证用户上传的文件。每个条目包含文件的名称、MIME 类型、`file_key` 和上传时间。当文件在上传时被抽取出文本（图片、PDF、扫描件），该条目的 MIME 会报告为 `text/plain`，且 `read_file` 会将抽取出的文本作为 `content` 返回 —— 即便原始文件并非文本格式。

<ParamField body="(无参数)">
  调用者由 auth 解析得出；无需任何参数。
</ParamField>

返回一个由 `{ filename, file_key, mime, uploaded_at }` 组成的 JSON 数组。

### read\_file

按 `file_key`（由 `list_files` 返回）读取用户的某个上传文件。所有权通过按用户维护的文件索引强制执行，因此调用者无法通过猜测 key 来读取其他用户的对象。文本类文件（以及任何带有抽取文本的文件）会以 `content` 内联返回；其它二进制类型则返回一个临时的签名 `url`，而不是内联模型无法使用的字节。

<ParamField body="file_key" type="string" required>
  要读取文件的 `file_key`，由 `list_files` 返回。
</ParamField>

文本返回 `{ filename, mime, content }`，二进制返回 `{ filename, mime, url, note }`。

## 健康工具

### family\_health

读取近期健康记录 —— FHIR `Observation` 资源 —— 属于用户本人，或已共享其健康数据的护理圈成员。Agent 正是借此回答诸如\*"我睡得怎么样？"*或*"妈妈最近怎么样？"\*之类的问题。

`member` 参数解析到一个目标用户：为空或 `"me"` 表示调用者本人；数字 id、姓名、昵称或邮箱则匹配某位已共享其数据的人。读取会被两次把关 —— 此人必须在调用者的健康共享列表中，且 `can_read_health` 会再次授权此次读取。只有已共享其数据的成员才可访问。

<ParamField body="member" type="string">
  要读取谁的健康数据：某位护理圈成员的姓名 / 昵称 / 邮箱 / id，或 `"me"`（或省略）表示调用者。当聊天输入框的"当前为谁"选择器已选中某位成员时，默认使用该成员。
</ParamField>

<ParamField body="count" type="integer">
  返回多少条近期 observation。默认 `20`，最大 `100`。
</ParamField>

返回 `{ subject, observation_count, observations: [{ code, value, time }, …] }`。

## 记忆工具

### recall\_memory

针对某个查询，检索用户最相关的长期记忆（已存储的事实、偏好和过往上下文），使模型能在作答前基于它对用户已了解的信息来立足。需在服务端启用长期记忆（否则会返回一个干净的工具错误）。

<ParamField body="query" type="string" required>
  要在用户记忆中检索的内容。
</ParamField>

<ParamField body="top_k" type="integer">
  返回记忆的最大数量（默认 5）。
</ParamField>

返回 `{ memories: [{ id, text, kind, score, created_at }, …] }`。

### remember

在长期记忆中存储一条关于用户的持久事实（一个稳定的偏好、目标或值得日后回忆的个人细节），以便未来某一轮可以用 `recall_memory` 取回。由模型决定什么值得保留。

<ParamField body="text" type="string" required>
  要记住的事实，写成一句自包含的话。
</ParamField>

<ParamField body="kind" type="string">
  类别标签：`fact` | `preference` | `episode`（默认 `fact`）。
</ParamField>

返回 `{ id, stored }`。

## 聊天 / UI 工具

### render\_chart

直接在用户的聊天中绘制图表。模型以一个完整的 [Apache ECharts](https://echarts.apache.org/) `option` 对象调用它；聊天流会把该调用转成一个图表事件，前端用 `echarts.setOption()` 渲染。该 option 通过调用参数带外传给客户端，因此模型的上下文不会因回显它而膨胀 —— 工具本身只校验该 option 并返回一个简短确认。

<ParamField body="option" type="object" required>
  一个完整的 Apache ECharts option 对象，例如 `{"xAxis":{"type":"category","data":["Mon","Tue"]},"yAxis":{"type":"value"},"series":[{"type":"line","data":[70.1,70.4]}]}`。
</ParamField>

<ParamField body="title" type="string">
  可选的简短说明文字，显示在图表旁边。
</ParamField>

### summarize\_conversation

为当前对话记录一段简明摘要（一个简短标题，≤ 200 字符），用作用户聊天历史里的标签。它会覆盖引擎根据开场问题生成的占位标题。一旦模型理解了用户的诉求，就会自行撰写这段摘要。

<ParamField body="summary" type="string" required>
  对话的简短、自包含摘要（≤ 200 字符）。
</ParamField>

返回 `{ updated: true }`。

## 示例 / 测试工具

### whoami

确认调用者已认证，并返回其（不透明的）session 标识。当本轮"当前为"某位调用者可读取的护理圈成员时，它还会标记 `acting_for_member`。它从不回显任何内部用户主键。

<ParamField body="(无参数)" />

返回 `{ authenticated: true, session_id, acting_for_member? }`。

### echo

回显所提供的文本。它是参考工具 —— 丢文件即注册模式最小可能的示例（见 [`echo.cpp`](https://github.com/thetahealth/mirobody/blob/main/res/mcp_tools/echo.cpp)）—— 同时兼作连通性检查。

<ParamField body="text" type="string" required>
  要回显的文本。
</ParamField>

返回 `{ echo: "<text>" }`。

## 一个工具是如何定义的

每个工具都是一个 `res/mcp_tools/<name>.cpp`，声明一个 `Tool` —— 名称、描述、一个 `auth` 标志、一张小小的 `Param` 表以及一个 handler —— 然后用 `MIROBODY_REGISTER_TOOL(...)` 自注册。C++11 没有运行时反射，因此参数显式声明（它们会展开成 MCP 的 `inputSchema` 以及 OpenAI / Gemini 的 function 描述符），并在编译期检查。以下是 `echo` 的全部内容：

```cpp res/mcp_tools/echo.cpp theme={null}
#include "mcp/tool.hpp"
#include <rapidjson/document.h>

namespace {
using namespace mirobody::mcp;

Result echo(const Args& args, const UserInfo&, const ToolContext&) {
    const std::string text = args.str("text");
    rapidjson::Document d;
    d.SetObject();
    rapidjson::Document::AllocatorType& a = d.GetAllocator();
    d.AddMember("echo",
                rapidjson::Value(text.c_str(),
                                 static_cast<rapidjson::SizeType>(text.size()), a),
                a);
    return Result::ok(to_json(d));
}

const Tool kEcho = {
    "echo",
    "Echo back the provided text.",
    false,                                                    // auth
    { Param("text", Type::String, Required, "Text to echo back") },
    &echo,
};
}   // namespace

MIROBODY_REGISTER_TOOL(kEcho);
```

完整流程见 [添加自定义工具](/zh/tools/adding-tools)。

## 下一步

<CardGroup cols={2}>
  <Card title="添加自定义工具" icon="plus" href="/zh/tools/adding-tools">
    在 `res/mcp_tools/` 中添加你自己的 C++ 工具
  </Card>

  <Card title="MCP 集成" icon="bolt" href="/zh/tools/mcp-integration">
    将 Claude、Cursor 或 ChatGPT 连接到 `/mcp` 端点
  </Card>

  <Card title="工具与 Agent 概览" icon="wrench" href="/zh/tools/overview">
    Agent、工具与 MCP 如何协同
  </Card>
</CardGroup>
