# 文件附件指南

TokST 允许您将文件附加到记忆中，在文本之外提供丰富的上下文。文件存储在 Cloudflare R2 中，元数据索引在 Supabase 中。

## 概述

当您将文件附加到记忆时，TokST 会：

1. 将文件上传到 Cloudflare R2 对象存储
2. 在 Supabase 中存储元数据（文件名、大小、MIME 类型、URL）
3. 将附件与记忆关联
4. 生成**预签名上传 URL**（有效期为 1 小时）和**预签名下载 URL**（有效期为 15 分钟）

这意味着文件永远不会直接存储在数据库中——它们保存在 R2 中，使您的数据库保持精简和快速。

## CLI 用法

### 创建时附加

在存储新记忆时使用 `--file` 标志。该标志可重复使用以附加多个文件。

```bash
# 单个文件
tokst remember "Sprint retrospective notes" --file retro-notes.md

# 多个文件
tokst remember "Q3 planning documents" --file roadmap.pdf --file budget.xlsx --file timeline.png
```

CLI 接受本地文件。远程 URL 可使用远端 MCP 的 `fileUrl` 输入，也可以先下载到本地再传给 `--file`。

### 附加到现有记忆

使用 `attach` 子命令：

```bash
tokst memory attach <memory-id> --file document.pdf
```

### 下载附件

使用 `download` 子命令将记忆的文件下载到本地。文件通过 R2 预签名 GET URL 流式传输，并保留原始文件名保存。

```bash
# 下载所有附件到 ~/Downloads
tokst memory download <memory-id>

# 指定输出目录（不存在则自动创建，~ 会展开为 $HOME）
tokst memory download <memory-id> --out ./files

# 按 ID 下载单个附件
tokst memory download <memory-id> --attachment-id <attachment-id>

# JSON 格式输出
tokst memory download <memory-id> --json
```

> 下载仅支持云端模式。本地 SQLite 模式会报错——请先运行 `tokst login --key <api-key>`。

## MCP 用法

使用 MCP 服务器时，在工具调用中传递文件参数：

```json
{
  "content": "Meeting notes with attached diagram",
  "filePath": "/home/user/diagram.png"
}
```

或者使用远程 URL：

```json
{
  "content": "Reference architecture",
  "fileUrl": "https://example.com/architecture.png"
}
```

要通过 MCP 将文件附加到现有记忆，请使用 `tokst_attach_file`：

```json
{
  "memoryId": "mem_abc123",
  "fileUrl": "https://example.com/report.pdf",
  "filename": "report.pdf"
}
```

ChatGPT 上传文件会通过工具的 `openai/fileParams` 元数据自动绑定。再次下载文件时调用 `tokst_download_file`：

```json
{
  "memoryId": "mem_abc123",
  "attachmentId": "attachment-uuid"
}
```

远程 MCP 服务器同时以 JSON 和 MCP `resource_link` 返回 15 分钟有效的签名链接。远程 MCP 单文件上传上限为 50 MB。

## 上传确认

附件在确认前保持 `pending`。确认路由会对 R2 执行 `HEAD` 请求，缺少或为空的对象会返回 `409`，随后以对象的真实大小和 MIME 激活附件。超过两小时的待处理或失败上传会自动清理。

## Web 仪表盘

Web 仪表盘提供了拖放式文件上传界面，带有实时进度指示器。导航到任何记忆并使用附件面板上传文件。

## 存储配额

各套餐的文件附件存储限制如下：

| 套餐 | 存储配额 |
|---|---|
| **免费版** | 500 MB |
| **入门版** | 2 GB |
| **专业版** | 10 GB |
| **团队工作区** | 20 GB 共享 |
| **Legacy Max / Team** | 保留原有权益 |

| 上传渠道 | 单文件行为 |
|---|---|
| 网页控制台 | 客户端最大 500 MB |
| 远端 MCP | 最大 50 MB |
| CLI | 受账户剩余存储配额限制 |

存储使用情况实时更新，可通过 `tokst status` 查看。

## R2 路径结构

文件使用以下路径约定存储在 Cloudflare R2 中：

```
{workspace_id}/{atlas_id}/{memory_id}/{attachment_id}-{filename}
```

例如：

```
ws_abc123/atlas_def456/mem_789abc/att_xyz789-report.pdf
```

这种结构确保：

- **隔离性** — 不同工作区的文件永远不会冲突
- **可发现性** — 您可以通过数据库元数据重建路径
- **清理方便** — 删除记忆或知识库时，会在数据库清理前删除对应 R2 对象

## 安全

文件访问通过**预签名 URL** 保护：

| 操作 | URL 有效期 |
|---|---|
| 上传 | 1 小时 |
| 下载 | 15 分钟 |

预签名 URL 在服务端生成，需要有效的认证。直接 R2 存储桶访问被阻止。这确保只有经过身份验证且具有适当权限的用户才能上传或下载文件。

对象删除仅接受精确匹配的内部服务凭据，或拥有对应附件的用户 Token。超出认证作用域的文件键会被拒绝。

## 最佳实践

- **使用有意义的文件名** — 文件名会成为 R2 路径的一部分，并在仪表盘中显示
- **将文件控制在 100 MB 以下** 以获得更快的上传速度
- **对公开远程资源使用远端 MCP 的 `fileUrl`**
- **使用 `tokst status` 监控配额** 以避免达到存储上限
