内容
# TOC在线MCP
> **非官方。** 本项目是一个独立的、社区驱动的项目。它 **不** 受TOC在线或Cloudware S.A.的任何关联、认可或支持。"TOC在线"是其各自所有者的商标。请自担风险 — 请参阅 [保修免责声明](#license)。
本地 [MCP](https://modelcontextprotocol.io) 服务器,封装了 [TOC在线](https://toconline.pt) 的会计/发票API。允许AI助手列出客户、查找产品、草拟销售文件,并在您授权后代表您调用任意TOC在线端点 — 只需一次性OAuth登录。
## 快速入门
整个设置分为四个步骤。每个步骤都链接到下面的完整部分。
1. **安装启动器** (需要Python 3.11+ 和 [`uv`](https://github.com/astral-sh/uv)):
```bash
git clone https://github.com/themiguelamador/toconline-mcp.git
cd toconline-mcp && uv tool install --from . toconline-mcp
```
→ 将`toconline-mcp`启动器放在您的`PATH`中。 [详情](#安装)。
2. **获取您的TOC在线API凭证** — 在TOC在线网络应用中,
*Empresa → Configurações → Dados API*,请求访问权限并设置重定向
URL为`http://127.0.0.1:53682/callback`。您将获得五个值
(`client_id`,`client_secret`,两个OAuth网址,一个API网址)。
[详情](#获取toc在线api凭证)。
3. **用您的客户端注册服务器** — Claude Code的一行代码,Claude Desktop的一个小JSON块。 [详情](#用claude注册)。
4. **登录** — 询问您的助手“登录到TOC在线”(粘贴五个
值),或运行`toconline-mcp setup`。浏览器打开,您批准,完成。
[详情](#4-登录)。
就这样 — 只读使用在任何计划上都有效。创建/编辑文档需要
有效的GC许可证。 **Gmail是一个单独的可选附加组件** ,用于存档
发票PDF — 跳过它,除非您需要它
([详情](#gmail集成-可选)。
## 状态
Alpha。涵盖客户、供应商、产品和商业销售文档最常见的读取和写入操作,以及一个通用的`api_request`逃生口。
## 先决条件
- macOS或Linux(Windows未经测试)。
- Python 3.11+。
- 具有 **管理员访问权限** 的TOC在线帐户,以及对于`GET`以外请求的 **有效GC(Gestão Comercial)许可证** 。仅`GET`使用在任何计划上都有效。
- 在TOC在线中配置的API集成 — 请参阅
[获取TOC在线API凭证](#获取toc在线api凭证) 以下。
- [`uv`](https://github.com/astral-sh/uv) (推荐)或`pipx`或普通的`python3 -m venv`。
## 安装
尚未发布到PyPI — 从源代码安装:
```bash
git clone https://github.com/themiguelamador/toconline-mcp.git
cd toconline-mcp
# 推荐:uv
uv tool install --from . toconline-mcp
# → 安装到 ~/.local/share/uv/tools/toconline-mcp/
# → 启动器位于 /Users/<you>/.local/bin/toconline-mcp
# 或pipx
pipx install .
# 或普通Python
python3 -m venv ~/.local/toconline-mcp
~/.local/toconline-mcp/bin/pip install .
```
> **macOS沙盒注意。** Claude Desktop是沙盒化的,无法执行
> Python安装位于`~/Documents/`、 `~/Desktop/`或`~/Downloads/`下的二进制文件。服务器将启动失败,出现
> `PermissionError: … /.venv/pyvenv.cfg`。始终通过上述方法之一安装 — 它们都位于TCC保护的文件夹之外。 **不要** 将Claude Desktop指向位于
> `~/Documents/`内的`.venv/bin/toconline-mcp`,如果存储库位于`~/Documents/`。
### 代码更改后更新
当您拉取新提交或编辑源代码时,需要三个步骤 — 您需要的内容取决于更改了什么:
```bash
# 1. 重新构建已安装的启动器(始终)
uv tool install --from . toconline-mcp --reinstall
```
2. **重启服务器** — 完全退出客户端(Claude Desktop:⌘Q,而不是
只是窗口),或杀死正在运行的`toconline-mcp`进程,以便它重新启动并使用新代码。
3. **开始新的聊天** — *仅在您添加或重命名工具时需要。* 聊天缓存了它在启动时获得的工具列表,因此在服务器重启后,新工具不会出现在
现有对话中。
编辑现有工具的行为只需要步骤1-2; **添加或重命名** 工具需要所有三个步骤。有关完整
的解释和如何查找/杀死过时进程,请参阅
[迭代工作流程](#迭代工作流程-获取代码更改)。
## 获取TOC在线API凭证
基于 [TOC在线官方API文档](https://api-docs.toconline.pt/)。
这些步骤是每个公司/租户的一次性操作。
### 1. 请求API访问权限
在TOC在线网络应用中,前往 **Empresa → Configurações → Dados API**
(*公司→设置→API数据*)。填写集成商详细信息(公司
信息+联系邮箱)并提交。
TOC在线将向集成商地址发送 **临时链接** (有效期~72小时)
,您可以在其中查看和编辑API凭证和集成设置。
### 2. 从电子邮件链接页面读取值
链接页面显示您将需要的五个值:
| TOC在线变量 | 内容 | 在此MCP中的用途 |
|---|---|---|
| `OAUTH_CLIENT_ID` | OAuth客户端ID | `client_id` |
| `OAUTH_CLIENT_SECRET` | OAuth客户端密钥 | `client_secret` |
| `OAUTH_URL` | 您的租户的OAuth基本网址 | `auth_url` = `<OAUTH_URL>/auth`,`token_url` = `<OAUTH_URL>/token` |
| `API_URL` | 您的租户的API基本网址 | `api_base` |
| `OAUTH_REDIRECT_URL` | 回调网址(由TOC在线预设;可编辑) | 必须与此MCP使用的网址匹配 — 请参阅下一步 |
> `OAUTH_URL` / `API_URL`值是 **特定于租户的** 。使用电子邮件链接页面上显示的确切
> 值 — 此工具中内置的默认`api_base`(`https://apiv1.toconline.com`)是一个通用占位符,可能与您的租户不匹配。
### 3. 设置重定向网址以匹配此MCP
这是一个步骤,大多数人都会做错。TOC在线预填充
`OAUTH_REDIRECT_URL`为类似`http://127.0.0.1:4080/oauth/callback`的网址。
**此MCP期望`http://127.0.0.1:53682/callback`** (不同的端口,不同的路径)。
在电子邮件链接页面(或稍后,在 *Empresa → Configurações → Dados API* 中),覆盖`OAUTH_REDIRECT_URL`为确切的:
```
http://127.0.0.1:53682/callback
```
保存。就这样。
如果端口53682在您的机器上被占用,请选择任何空闲端口并将其作为
`redirect_port`传递给`login`工具(或 `--port N`传递给CLI)。路径
必须保持`/callback`。
### 4. 登录
两种等效方法 — 选择适合您工作流程的方法。
#### A. 从您的AI客户端内部(推荐)
在 [将服务器注册到Claude](#用claude注册) 后,询问:
> 登录到TOC在线。这里是 *Empresa → Configurações → Dados API* 中的值:
> client_id = `...`,client_secret = `...`,
> auth_url = `<OAUTH_URL>/auth`,token_url = `<OAUTH_URL>/token`,
> api_base = `<API_URL>`。
Claude调用`login`工具,您的浏览器打开到TOC在线同意,
您批准,凭证存储在
`~/.config/toconline-mcp/credentials.json`(模式`0600`)。无需单独
的终端步骤。
以后,您可以随时询问Claude运行`auth_status`以查看凭证是否配置以及访问令牌何时过期,或运行`logout`
清除它们。
#### B. 从命令行
```bash
toconline-mcp setup
```
交互式提示输入每个值,打开浏览器,写入凭证文件。您也可以先在环境中设置它们以跳过
提示:
```bash
export TOCONLINE_CLIENT_ID='...'
export TOCONLINE_CLIENT_SECRET='...'
export TOCONLINE_AUTH_URL='<OAUTH_URL>/auth'
export TOCONLINE_TOKEN_URL='<OAUTH_URL>/token'
export TOCONLINE_API_BASE='<API_URL>'
toconline-mcp setup
```
> 如果MCP服务器已经在您的客户端运行,请在之后重启/重新连接它
> — 它在启动时缓存凭证到内存中,因此`auth_status`
> 将显示新的令牌,而真正的调用仍然会因
> `unauthorized_client`而失败,直到服务器重新加载文件。
### 令牌生命周期
根据TOC在线的 [身份验证文档](https://api-docs.toconline.pt/autenticacao-detalhada),
**访问令牌持续4小时** (`expires_in: 14400`)而 **刷新
令牌8小时** 。此MCP在您发出请求时自动刷新访问令牌(在过期前2分钟),因此在活跃使用期间,您永远不会注意到。
但是有一个问题 — 刷新窗口为8小时:如果服务器 **闲置超过8小时** ,
刷新令牌就会过期,下一次调用将失败,返回401 — 您需要重新运行`login` / `setup`。 (这是TOC在线的限制,而不是此MCP可以扩展的。)您还需要在撤销集成、轮换客户端密钥或更改`OAUTH_REDIRECT_URL`时重新登录。
## 注册到Claude
两个客户端都需要 **绝对路径** 到已安装的启动器。使用以下命令找到您的路径:
```bash
which toconline-mcp
# → 例如 /Users/<you>/.local/bin/toconline-mcp
```
### Claude Code
```bash
claude mcp add toconline -- /Users/<you>/.local/bin/toconline-mcp
```
### Claude Desktop
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json` 并
在`mcpServers`下添加`toconline`条目:
```json
{
"mcpServers": {
"toconline": {
"command": "/Users/<you>/.local/bin/toconline-mcp"
}
}
}
```
**完全退出** Claude Desktop(⌘Q — 关闭窗口是不够的)并
重新打开。`toconline`现在应该在您的连接器列表中出现,带有
`DESKTOP`徽章。
#### 如果服务器不显示
检查日志:
```bash
tail -50 ~/Library/Logs/Claude/mcp-server-toconline.log
```
两个常见错误:
- `PermissionError: … /.venv/pyvenv.cfg` — 沙盒阻止了虚拟环境。安装
通过`uv tool install --from . toconline-mcp` (参见上文)并将配置指向
`~/.local/bin/toconline-mcp`,而不是`~/Documents/`下的`.venv`。
- `ENOENT` / 命令未找到 — 配置中的路径错误。再次运行
`which toconline-mcp`并将确切路径粘贴到配置中。
### 一旦该软件包发布到PyPI
在`uv publish`之后,配置可以使用更短的便携式表单,不依赖于特定用户的 文件系统:
```json
{
"mcpServers": {
"toconline": { "command": "uvx", "args": ["toconline-mcp"] }
}
}
```
## API覆盖
针对 **TOC在线开放API v1.0.0** (JSON:API),在
[api-docs.toconline.pt](https://api-docs.toconline.pt/) 中有完整的
[OpenAPI 3.0.3 规范在SwaggerHub](https://app.swaggerhub.com/apis-docs/toconline.pt/toc-online_open_api/1.0.0)
(68个路径)。基本网址是
区域特定的 — 例如`https://api14.toconline.pt` (数字与您的
帐户的区域匹配)。少数文档操作(完成,电子邮件)使用TOC在线的旧版 **v1操作** 端点,这些端点不在公共文档中,但在 *Empresa → Configurações → Dados API* 中附带的Postman集合中提供。
映射到公共文档 — ✅ 类型工具,⚠️ 部分,❌ 仅`api_request`:
| API部分(文档) | 资源 | 覆盖范围 |
|---|---|---|
| Empresa | Clientes (+ 地址,电子邮件) | ✅ 完整CRUD + 地址/联系人 |
| Empresa | Fornecedores (+ 地址,电子邮件) | ✅ 完整CRUD + 地址/联系人 |
| Empresa | Produtos e Serviços | ✅ 完整CRUD |
| Vendas | Documentos de Venda | ✅ 列表/获取/创建/删除 |
| Vendas | Recibos de Venda | ✅ 列表/获取/创建 + 作废 |
| Vendas | PDF(文档 + 收据) | ✅ `get_document_pdf_url` |
| Vendas | Envio por e-mail | ✅ `send_document_email` |
| Vendas | Comunicação à AT | ✅ `communicate_sales_document_at` |
| Compras | Documentos de Compra | ✅ 列表/获取/创建 + 完成/作废 |
| Compras | Pagamentos | ✅ 列表/获取/创建 |
| Compras | PDF / Comunicação à AT | ✅ pdf网址 + `communicate_purchase_document_at` |
| Auxiliares | Descritores de Taxa | ✅ `list_tax_descriptors` |
| Auxiliares | Família de Itens | ✅ `list_item_families` |
| Auxiliares | Países | ✅ `list_countries` |
| Auxiliares | Unidades de Medida | ✅ `list_units_of_measure` |
| Auxiliares | Contas Bancárias | ✅ `list_bank_accounts` / `get` |
| Auxiliares | Caixa Associada | ✅ `list_cash_accounts` |
| Auxiliares | Unidade Monetária (moedas) | ❌ `api_request` |
| Auxiliares | Taxas (tax rates) | ❌ `api_request` |
| Auxiliares | Categorias de Despesa | ❌ `api_request` |
| Auxiliares | Documentos de Série | ❌ `api_request` |
| Auxiliares | OSS (países e taxas) | ❌ `api_request` |
| Vendas/Compras | Settlement / payment lines | ✅ `create_sales_receipt_line` / `create_purchase_payment_line` |
任何❌ 今日通过`api_request`有效 — 四个
未覆盖的辅助表是只读查找。询问如果您想将任何提升
到类型工具。
### 验证状态
最近添加/更改的每个工具的验证程度 — **实时** = 对API的实际调用成功;**单元** = 有效载荷形状被测试覆盖,但未运行API;**未测试** = 尚未进行自动或实时检查。
| 工具 | 状态 |
|---|---|
| `list_countries`, `list_item_families`, `list_units_of_measure`, `list_tax_descriptors`, `list_cash_accounts` | ✅ live |
| `create_product` (incl. required `type` + `item_family_id`) | ✅ live |
| `delete_product` | ✅ live |
| `create_service`, `delete_service` | ✅ live |
| `update_product`, `update_service` | 🧪 unit |
| `create_customer` / `update_customer` / `delete_customer` | 🧪 unit |
| `create_supplier` / `update_supplier` / `delete_supplier` | 🧪 unit |
| `create_sales_receipt_line`, `create_purchase_payment_line` | 🧪 unit — 货币路径,未实时运行(结算真实文档) |
| `communicate_sales_document_at`, `communicate_purchase_document_at` | ⏳ untested — 绑定AT提交 |
## 工具
54种类型工具 + 通用逃生口。类型工具仅公开确切匹配
过滤器,但底层API
[支持比较运算符](https://api-docs.toconline.pt/caracteristicas-dos-pedidos)
— 例如`filter="documents.pending_total>0"`或
`document_lines.created_at>'2022-01-01'::date`。当您需要范围或日期比较时,请使用原始`filter`参数
。
### 身份验证
| 工具 | 用途 |
|---|---|
| `auth_status` | 检查凭证是否配置以及访问令牌何时过期。 |
| `login` | 运行OAuth浏览器流程并存储凭证。 |
| `logout` | 删除存储的凭证。 |
### 客户,供应商,产品
| 工具 | 用途 |
|---|---|
| `list_customers` / `get_customer` / `create_customer` / `update_customer` / `delete_customer` | 客户CRUD。 |
| `list_suppliers` / `get_supplier` / `create_supplier` / `update_supplier` / `delete_supplier` | 供应商CRUD。 |
| `list_products` / `get_product` / `create_product` / `update_product` / `delete_product` | 产品CRUD。 |
| `list_services` / `get_service` / `create_service` / `update_service` / `delete_service` | 服务CRUD。 |
`delete_*` 需要 `confirm=true`。 创建/更新设置API所需的项目
`type` 属性(`Product`/`Service`)自动。
### 引用表(只读)
查找用于构建文档和项目资源的资源。
| 工具 | 用途 |
|---|---|
| `list_countries` | ISO国家代码和名称。 |
| `list_item_families` | 项目分类(`item_family_id`)。 |
| `list_units_of_measure` | 文档行的单位(unidades)。 |
| `list_tax_descriptors` | 增值税税率及其代码(`NOR`,`INT`,`RED`,`ISE`)。 |
| `list_cash_accounts` | 收款/付款的现金账户(caixas)。 |
| `list_document_series` | 每种类型的文档系列(séries)— `prefix`,编号,`is_default`。传递系列ID作为`series_id`到`create_sales_document`。 |
### 地址和联系人
地址和联系人是具有所有者
`customer_id` 或 `supplier_id` (仅限一个,非两者)的独立JSON:API资源。
| 工具 | 用途 |
|---|---|
| `list_addresses` / `get_address` / `create_address` / `update_address` / `delete_address` | 地址CRUD。根据`customer_id`或`supplier_id`限定列表范围。 |
| `list_contacts` / `get_contact` / `create_contact` / `update_contact` / `delete_contact` | 联系人CRUD,具有相同的范围。 |
`delete_address` / `delete_contact` 需要 `confirm=true`。
### 销售文档和收据
| 工具 | 用途 |
|---|---|
| `list_sales_documents` | 按 `document_type` / `customer_id` / `date` 过滤。 |
| `get_sales_document` | 单个文档,其项目行合并后。 |
| `create_sales_document` | 带有项目行的草稿文档。对于信用/借项凭证,设置 `document_type='NC'` 或 `'ND'` 并传递 `parent_document_id` 以引用原始凭证。 |
| `list_sales_receipts` / `get_sales_receipt` / `create_sales_receipt` | 客户付款收据。 |
| `create_sales_receipt_line` | 将销售凭证与收据结算(结算行)。 |
### 采购
| 工具 | 用途 |
|---|---|
| `list_purchase_documents` / `get_purchase_document` / `create_purchase_document` | 供应商发票。 |
| `list_purchase_payments` / `get_purchase_payment` / `create_purchase_payment` | 供应商付款。 |
| `create_purchase_payment_line` | 将采购凭证行与付款结算(结算行)。 |
### 逃生口
| 工具 | 用途 |
|---|---|
| `api_request` | 通用`/api/*`直通接口,无类型工具的端点。`POST`/`PATCH`/`PUT`/`DELETE`需要`confirm=true`。 |
> **列出父项的子项:** 某些集合无法扁平过滤 —
> `GET /api/commercial_sales_document_lines?filter[document_id]=…` 和
> `/api/addresses?filter[customer_id]=…` 两者都返回 `JA011`。改用
> 嵌套路由:`/api/commercial_sales_documents/{id}/lines`,
> `/api/customers/{id}/addresses`。类型工具已经这样做了。
### 响应形状
响应从JSON:API展平 — `data.attributes.*` 字段提升到
顶级,`relationships.<name>.data.id` 成为 `<name>_id`:
```json
{
"items": [
{"id": "1", "type": "customers", "business_name": "ACME", "country_code": "PT"}
],
"meta": {"total": 1}
}
```
### 文档操作(PDF、电子邮件、完成、作废、AT)
| 工具 | 用途 |
|---|---|
| `get_document_pdf_url` | 获取销售文档、销售收据或采购文档的PDF的签名公共URL。该URL在短时间内无需身份验证即可访问 — 可以与用户分享,用户可以直接下载。 |
| `send_document_email` | 通过TOCO在线邮件服务器将销售文档或收据以电子邮件发送给收件人。 |
| `finalize_sales_document` / `finalize_purchase_document` | 发布草稿文档。不可逆 — 需要 `confirm=true`。 |
| `void_sales_receipt` / `void_purchase_document` | 作废(anular)文档。不可逆 — 需要 `confirm=true`。 |
| `communicate_sales_document_at` / `communicate_purchase_document_at` | 将已完成的文档报告给AT(税务机关)。具有约束力 — 需要 `confirm=true`。 |
这些端点不在公共API文档中,但可以通过TOCO在线提供的Postman集合从 *Empresa → Configurações → Dados API* 中发现。
### 结算链接
`create_sales_receipt_line` / `create_purchase_payment_line` 将收据或付款附加到结算文档(因此文档被标记为已付款)。这两个操作是不对称的,根据API:
- **销售** 结算整个 **文档**:`receivable_type="Document"`,`receivable_id` = 销售文档ID。
- **采购** 结算文档 **行**:`payable_type="Purchases::DocumentLine"`,`payable_id` = 采购文档 **行** ID(不是文档ID)。
工具构建了文档化的有效载荷;结算金额(`received_value` / `paid_value`,`settlement_amount`,`retention_total`,...)由调用者负责。
四个未覆盖的辅助读取表(货币、税款、费用类别、文档系列、OSS)保留在 `api_request` — 请要求,我们将任何一个提升为键入工具。
## Gmail集成(可选)
**大多数人不需要这个。** 它是一个独立的附加组件,用于一种工作流程:从电子邮件中提取供应商发票PDF,并将它们存档到一个文件夹(本地或Google Drive / iCloud同步),这样您就可以在TOCO在线输入它们。它仅限于发票存档 — 不是一个通用的Gmail客户端(无发送,无删除)。与TOCO在线工具完全独立。
> **默认关闭 — 如果不需要则无需操作。** 10个 `gmail_*` 工具仅在存在Gmail凭证时出现(或设置 `TOCONLINE_GMAIL=1`)。如果需要,步骤如下:
>
> 1. **一次性Google Cloud设置** — 创建一个OAuth客户端(您需要自己的Google凭证)。
> 2. **通过CLI登录一次** — `toconline-mcp gmail-setup`。
> 3. **重启客户端** — `gmail_*` 工具现在出现。
### 一次性Google Cloud设置
1. 进入 <https://console.cloud.google.com/> 并创建(或选择)一个项目。
2. **APIs & Services → Library** → 启用 **Gmail API**。
3. **APIs & Services → OAuth同意屏幕** → 设置一个“桌面版”/“外部”同意屏幕,并将您的电子邮件设置为测试用户。
4. **APIs & Services → Credentials → Create Credentials → OAuth客户端ID** → *桌面应用程序*(或*Web应用程序*)。注册 `http://127.0.0.1:53683/callback` 作为授权重定向URI。
5. 复制 **客户端ID** 和 **客户端密钥**。
### 登录
首次登录必须使用CLI(内置的`gmail_*`工具在凭证存在之前不会出现):
```bash
toconline-mcp gmail-setup
```
令牌保存在 `~/.config/toconline-mcp/gmail-credentials.json` (0600)中,与TOCO在线凭证分开。重启客户端后 — `gmail_*` 工具(包括用于重新身份验证的 `gmail_login`)现在出现。
### 范围
`gmail.modify` — 涵盖读取消息、下载附件以及添加/删除标签。它 **不** 允许永久删除或发送消息。更窄的范围(例如 `gmail.readonly` 或 `gmail.labels`)无法标记消息,这会破坏“标记为已导入”的工作流程。
### Gmail工具(10)
| 工具 | 用途 |
|---|---|
| `gmail_auth_status` / `gmail_login` / `gmail_logout` | 身份验证生命周期(镜像TOCO在线的身份验证三元组)。 |
| `gmail_search_messages` | 使用Gmail查询语法搜索(`has:attachment filename:pdf from:billing@…`)。返回每个消息的紧凑元数据+附件列表。 |
| `gmail_get_message` | 获取单个消息的元数据+附件列表。 |
| `gmail_download_attachment` | 下载附件到绝对本地路径。处理文件名冲突,带有 `(2)`,`(3)`…后缀。 |
| `gmail_list_labels` / `gmail_create_label` | 发现和创建标签。 |
| `gmail_add_label_to_message` / `gmail_remove_label_from_message` | 标记消息为已处理(例如,应用`Imported/TOCOnline`标签)。 |
### 示例工作流程:批量下载供应商发票
询问克劳德:
> 在2026-04-01之后搜索我的Gmail中来自 `billing@` 发送者的未读消息,带有PDF附件。对于每个消息,将每个PDF下载到 `/Users/me/Google Drive/Invoices/2026-04/` 并应用标签 `Imported/TOCOnline`。然后打印一个摘要表。
克劳德使用:`gmail_search_messages` → `gmail_list_labels` (或如果丢失则 `gmail_create_label`)→ 对于每个结果,`gmail_download_attachment` + `gmail_add_label_to_message`。使用Google Drive同步的文件夹作为 `save_dir`,您可以免费获得云同步。
### Gmail环境变量
- `TOCONLINE_GMAIL_CREDENTIALS_PATH` — 覆盖凭证文件位置。
- `GMAIL_CLIENT_ID` / `GMAIL_CLIENT_SECRET` — 跳过 `gmail-setup` 期间的CLI提示。
## 配置文件(`~/.config/toconline-mcp/.env`)
与其每次在shell中导出环境变量,不如将它们放入 `.env` 文件中,MCP在启动时加载。如果实际环境变量的值优于 `.env` 文件中的值,则以实际环境变量的值为准。
加载器按顺序检查这些路径(以第一个存在的文件为准):
1. `TOCONLINE_ENV_FILE` 指向的文件(如果设置)。
2. `~/.config/toconline-mcp/.env` — 主要位置(在 `credentials.json` 旁边)。
3. 当前工作目录中的 `./.env` (开发便利)。
示例文件 — 所有字段都是可选的,只需包含您要缓存的内容:
```bash
# ~/.config/toconline-mcp/.env
# --- TOC在线 ---
TOCONLINE_CLIENT_ID=ptNNNNNNNNN_cNNNNNN-xxxxxxxxxxxxxxxx
TOCONLINE_CLIENT_SECRET=您的-轮换-密钥
TOCONLINE_AUTH_URL=https://app14.toconline.pt/oauth/auth
TOCONLINE_TOKEN_URL=https://app14.toconline.pt/oauth/token
TOCONLINE_API_BASE=https://api14.toconline.pt
# --- Gmail(来自console.cloud.google.com的Google OAuth客户端)---
GMAIL_CLIENT_ID=1234...apps.googleusercontent.com
GMAIL_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxx
```
格式:
- 每行 `KEY=VALUE`。
- `#`注释和空行可以。
- 用引号括住带有空格的值:`NAME="with spaces"`。
- 接受 `export KEY=VALUE` (为了与shell兼容)。
- **无变量插值**(`$VAR` / `${VAR}`)— 如果需要,请从shell导出。
创建文件后,`toconline-mcp setup` 和 `toconline-mcp gmail-setup` 跳过任何已经提供字段的交互式提示。
**权限**:文件包含OAuth客户端密钥,这些密钥比访问令牌的敏感度低,但仍然不公开。将其设为:
```bash
chmod 600 ~/.config/toconline-mcp/.env
```
如果MCP检测到权限过松,则在标准错误上打印 `warning:`。
## 开发
```bash
uv venv --python 3.11
uv pip install -e '.[dev]'
pytest
```
环境变量:
- `TOCONLINE_CREDENTIALS_PATH` — 覆盖凭证文件位置。
- `TOCONLINE_LOG_LEVEL` — `DEBUG`,`INFO`,`WARNING` 等。日志输出到标准错误。
### 迭代工作流程(获取代码更改)
`uv tool install --reinstall` 更新磁盘上的二进制文件,但 **不会重启已经运行的MCP进程** — Python在启动时导入模块,因此实时服务器在被杀死之前继续提供旧代码。在编辑源代码后:
```bash
# 1. 运行测试套件(在将回归问题推送到实时服务器之前捕获)
pytest
# 2. 刷新已安装的启动器
uv tool install --from . toconline-mcp --reinstall
# 3. 查找克劳德桌面版的MCP服务器进程并杀死它
ps aux | grep toconline-mcp | grep -v grep
kill <pid>
# 4. 在克劳德桌面版中启动一个新的聊天(Cmd-N)。新聊天中的第一个工具调用将导致克劳德桌面版重新启动MCP并使用新代码 — 而新聊天的LLM将获得新的工具列表。
```
#### 为什么“新聊天”比“杀死服务器”更重要
有两个缓存层:
1. **MCP服务器进程** 在内存中缓存已注册的工具列表(模块在启动时导入)。杀死进程强制重启,重新导入最新代码。
2. **聊天会话** 缓存它从服务器获得的工具列表,嵌入到LLM的上下文中。新添加的工具甚至在服务器重启后也不会出现在 **现有** 聊天中。
因此,如果您添加了一个工具(例如 `list_services`),并且希望LLM能够调用它,您需要同时:
- 杀死+重启(这样服务器公开新的工具),并且
- 一个新的聊天(这样LLM被告知新工具存在)。
编辑现有工具的行为或修复错误是不同的 — 工具名称相同,LLM已经知道它,因此只需杀死+重启就足够了;下一个调用就会命中新代码。 **添加** 或 **重命名** 工具需要一个新的聊天。
这也适用于克劳德代码:聊天开始时显示的延迟工具列表在此聊天中固定。新的工具需要一个新的克劳德代码会话(`/clear` 或重新开始)。
#### 旧进程
来自旧终端的 `uvx toconline-mcp` 进程可能会徘徊并提供过时的代码。 `ps aux | grep toconline-mcp` 显示它们; `kill <pid>` 清除它们。当空闲时,它们是无害的,但如果您 `claude mcp add` 多于一个指向相同二进制文件的服务器,则会造成混淆。
## 安全
- 存储在 `~/.config/toconline-mcp/credentials.json` (`0600`)中的令牌和客户端密钥。服务器拒绝以宽松的权限启动。
- 所有日志输出到标准错误(标准输出保留用于MCP标准输入/输出框架)。授权头和令牌字段从日志消息中删除。
- `api_request` 路径限制为 `^/api/...`,无 `..`;写入方法需要明确的 `confirm=true`。
## 许可证
MIT。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器