> ## 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.

# 工具与 Agent 概览

> 了解 Mirobody C++ 引擎中的 Agent、MCP 工具与 /mcp 端点

## Agent

Mirobody 运行**一个简单的 Agent** —— "Base"，定义在 [`res/agents/base.cpp`](https://github.com/thetahealth/mirobody/blob/main/res/agents/base.cpp)。它刻意保持极简：没有 Agent 循环，没有 planner，没有中间件。每一轮它会：

1. **按 provider 名称选择一个 LLM 客户端**（使用请求指定的 `provider`，否则用默认值）。
2. **构建 system prompt** —— 一段固定的内联字符串，包含当前时间、回复语言，以及引导去获取上传文件（`list_files` / `read_file`）和健康记录（`family_health`）的说明。
3. **把 provider 的事件直接流式返回**，让模型按需调用内置的 [MCP 工具](/zh/tools/built-in)。

<Note>
  你选择的是一个 **模型**（`provider`），而不是 Agent *类型* —— Mirobody 运行单一 Agent。
</Note>

### 支持的提供商

该 Agent 注册最多四个 provider 客户端（各自以 `/api/providers` 选择器展示的模型名为键）。前三个始终会注册，因此它们会出现在选择器中；其中未配置凭据的那个，只会在调用时报错。

| Provider key       | 模型                              | 客户端                      | 工具执行                                   |
| ------------------ | ------------------------------- | ------------------------ | -------------------------------------- |
| `gemini-2.5-flash` | Google Gemini 2.5 Flash（**默认**） | `GeminiClient`           | 本地，进程内                                 |
| `gpt-5-nano`       | OpenAI GPT-5 nano               | `OpenAIChatClient`       | 本地，进程内                                 |
| `mirothinker-1.7`  | MiroThinker（MiroMind）           | `MiroThinkerClient`      | 通过 `MCP_PUBLIC_URL` 使用 provider 原生 MCP |
| `gemma-4-e2b`      | 端侧 Gemma 4 E2B                  | `OpenAIChatClient`（本地端点） | 取决于服务栈                                 |

原生应用还会在**端侧**运行 **Gemma 4 E2B**（Android/iOS 上用 LiteRT-LM，Electron 上用 llama.cpp）—— 离线、无需密钥。上表中的 `gemma-4-e2b` 是同一个模型，通过本地 OpenAI 兼容端点（Ollama / llama.cpp / vLLM）提供服务，仅在配置了 base URL 时才注册。

<Info>
  **工具的运行方式因 provider 而异。** OpenAI 和 Gemini 把工具作为 function-call 描述符接收，引擎以已认证用户的身份在**本地进程内**执行每次调用。MiroThinker 则在 **provider 侧**运行工具 —— MiroMind 通过公网在 `MCP_PUBLIC_URL` 反向访问你的 `/mcp` 端点。
</Info>

### 配置

Provider 使用 `config.yml` 中的扁平键配置（参见 [配置](/zh/configuration)）。**没有 `PROVIDERS_DEEP`** 块。

```yaml config.yml theme={null}
# OpenAI (gpt-5-nano)
OPENAI_API_KEY: 'your_openai_key'
OPENAI_BASE_URL: 'https://api.openai.com'   # client appends /v1/chat/completions

# Google Gemini (gemini-2.5-flash, the default provider)
GOOGLE_API_KEY: 'your_google_key'

# MiroThinker (mirothinker-1.7) — provider-native MCP
MIROTHINKER_API_KEY: 'your_mirothinker_key'
MIROTHINKER_BASE_URL: ''      # optional override
MIROTHINKER_MODEL: ''         # optional override
MCP_PUBLIC_URL: 'https://your-domain.com/mcp'   # where MiroMind reaches your MCP

# On-device Gemma served over a local OpenAI-compatible endpoint (optional)
GEMMA_CHAT_BASE_URL: 'http://localhost:11434/v1'   # or OLLAMA_BASE_URL
GEMMA_CHAT_API_KEY: ''
GEMMA_CHAT_MODEL: 'gemma-4-e2b'
```

### Agent 覆盖的范围

个人健康类问题几乎总是归结为：*读取用户的记录 → 按需读取上传文件 → 按需检索长期记忆 → 作答，有时渲染一张图表*。内置工具正好一一对应这些步骤，而模型会在单次流式回合内自行编排它们。

## 工具系统

### 什么是工具？

工具是 **[`res/mcp_tools/`](https://github.com/thetahealth/mirobody/tree/main/res/mcp_tools) 中的 C++ 文件**。每个文件声明一个 `Tool`（名称、描述、一个 `auth` 标志、一张小小的 `Param` 表以及一个 handler），并在编译时自注册。`CMakeLists.txt` 会把该目录下的每个 `.cpp` 都 glob 进构建（带 `CONFIGURE_DEPENDS`），因此**只需丢入一个新文件并重新构建即可** —— 无需手动注册，无需手写 JSON schema。

<Info>
  这是**编译期**机制：工具从 `res/mcp_tools/` 编译进程序，而非从运行时目录加载。
</Info>

### 九个内置工具

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

各工具的参数与返回结构见 [内置工具](/zh/tools/built-in)。

### 添加一个工具

创建 `res/mcp_tools/<name>.cpp`，声明一个 `Tool`，并用 `MIROBODY_REGISTER_TOOL(...)` 宏注册 —— 然后重新构建：

```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);
```

Auth 范围内的工具将 `auth = true`，并以 `UserInfo` 接收调用者身份；handler 需要的其它一切（缓存、对象存储、数据库、长期记忆）都通过 `ToolContext` 送达。完整流程：[添加自定义工具](/zh/tools/adding-tools)。

## MCP 端点

引擎通过 `src/mcp/` 提供的 MCP 端点对外暴露其工具。它使用 **JSON-RPC 2.0**。

```
http://localhost:8080/mcp                 # authenticates via bearer JWT
http://localhost:8080/mcp/{secret}        # personal-MCP secret resolving to a user
```

支持的方法包括 `tools/list` 和 `tools/call`。本地开发时，把端口打通隧道（例如 `ngrok http 8080`）并设置 `MCP_PUBLIC_URL`，以便远端客户端 —— 以及 MiroThinker 的 provider 原生 MCP —— 能够访问它。参见 [MCP 集成](/zh/tools/mcp-integration) 连接 Claude、Cursor 和 ChatGPT。

```bash theme={null}
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## 健康数据存放在哪里

像 `family_health` 这样的工具不会命中临时表 —— 它们通过**内嵌的 FHIR R4 存储**（`src/fhir/`）读取，返回 FHIR `Observation` 资源。数据在进入时会被归一化（单位转为 UCUM），而关系型后端是在**构建期**通过 CMake（`-DMIROBODY_DATABASE_BACKEND=`）选定的：SQLite（移动端默认）、PostgreSQL（桌面端默认）、MySQL、DuckDB 或 ClickHouse。SQL schema 位于 [`res/sql/`](https://github.com/thetahealth/mirobody/tree/main/res/sql)（`pg`、`sqlite`、`mysql`、`duckdb`、`clickhouse`）。完整图景见 [架构](/zh/concepts/architecture)。

## 下一步

<CardGroup cols={2}>
  <Card title="内置工具" icon="wrench" href="/zh/tools/built-in">
    默认提供的九个工具
  </Card>

  <Card title="添加自定义工具" icon="plus" href="/zh/tools/adding-tools">
    编写你自己的 C++ 工具
  </Card>

  <Card title="MCP 集成" icon="bolt" href="/zh/tools/mcp-integration">
    连接 Claude、Cursor 和 ChatGPT
  </Card>

  <Card title="添加 MCP" icon="plug" href="/zh/tools/adding-mcps">
    连接外部 MCP 服务器
  </Card>
</CardGroup>
