mcpField
T
tres-import-contacts

tres-import-contacts

github.com/anthropics数据与数据库4.8k49 次安装2 周前更新
代码仓库

关于 tres-import-contacts

tres-import-contacts 是用于将 CSV 或 XLSX 中的地址标签导入 TRES 通讯录的技能,适合需要批量整理联系人信息的用户。它会校验并去重数据,并在导入前提供预览。

主要功能

  1. 01解析 CSV 和 XLSX 文件
  2. 02按地址去重并校验字段
  3. 03导入联系人名称与标签
  4. 04导入前展示数据预览
  5. 05处理重复项及导入失败

适用场景

  1. 01将填写好的地址映射表导入 TRES
  2. 02为多个区块链地址添加联系人名称
  3. 03批量更新联系人标签

MCP 相关

通过 user-tres-finance MCP 服务的 execute 工具调用 GraphQL,以查询会话和写入 TRES 通讯录联系人及标签。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anthropics/claude-plugins-community --skill tres-import-contacts

安装后在 Claude Code 中输入/tres-import-contacts确认已加载。

详细介绍

TRES Finance — 从 CSV/XLSX 导入联系人

目标

读取用户提供的 CSV 或 XLSX 文件,其中包含地址到名称的映射,并将其作为联系人导入 TRES 地址簿。这是联系人工作流的后半部分:用户之前通过导出技能导出了未识别的地址,填写了名称和标签,现在希望将这些标签导入 TRES。

MCP 服务

所有 GraphQL 调用均使用 user-tres-finance MCP 服务(execute 工具)。

预期文件格式

文件应包含以下列(按列标题名称进行不区分大小写的匹配):

联系人名称联系人地址联系人标签
Binance 热钱包0xABC...交易所
Vendor X0xDEF...供应商
  • 联系人名称 — 分配给地址的标签(导入时必填;没有名称的行将被跳过)
  • 联系人地址 — 区块链地址(必填)
  • 联系人标签 — 联系人的可选标签。多个标签可以用逗号分隔(例如 Exchange, Custodian)

列的顺序不限 — 此技能会根据列标题名称进行匹配。文件可以包含其他列(例如导出技能中的“地址详情”补充列),这些列会被忽略。

工作流

步骤 1 — 身份验证

调用 get_viewer(不带参数)以确认会话处于活动状态,并记录组织名称。

步骤 2 — 读取并解析文件

用户会提供 CSV 或 XLSX 文件。根据文件扩展名检测格式。

对于 XLSX 文件: 使用 Python 和 openpyxl==3.1.5。如果未安装,请停止并显示:

"openpyxl is not installed. Please run: python3 -m venv .venv && .venv/bin/pip install openpyxl==3.1.5"

  • 如果工作簿有多个工作表,请查找名为 "Contacts" 的工作表(不区分大小写)。如果未找到,则使用第一个工作表。
  • 读取标题行,查找“联系人名称”、“联系人地址”和“联系人标签”列的索引(不区分大小写匹配,并去除空白字符)。
  • 读取所有数据行。
  • 过滤掉末尾的空行 — openpyxl 有时会在工作表底部读取到多余的 None 行。跳过所有单元格均为 None 或空字符串的行。

对于 CSV 文件: 使用 Python 内置的 csv 模块。

  • 使用 encoding='utf-8-sig' 打开文件,以处理 Excel 保存 CSV 时添加的 BOM(字节顺序标记)。否则,第一个标题可能显示为 \ufeffContact Name,导致匹配失败。
  • 首先尝试使用逗号作为分隔符。如果标题行不包含预期列,则改用分号分隔符重试(常见于欧洲区域设置下的 Excel 导出)。
  • 读取标题行以查找列索引,匹配逻辑同上。
  • 读取所有数据行。
步骤 3 — 验证并筛选

对于每一行:

  1. 如果联系人名称为空或缺失,则跳过 — 用户尚未识别此地址,因此无需导入。
  2. 如果联系人地址为空或缺失,则跳过 — 无法为不存在的地址添加标签。
  3. 对名称、地址和标签值去除空白字符。
  4. 解析标签:如果联系人标签包含逗号,则拆分为多个标签。去除每个标签的首尾空白字符,并移除空字符串。
  5. 按地址去重(不区分大小写):如果同一地址出现多次,则保留最后一次出现的记录(用户很可能已修正记录)。提示用户存在重复项。

筛选后,向用户报告:

  • 文件中的总行数
  • 跳过的行数(名称为空)
  • 待导入的行数
  • 发现的重复项

然后显示前 10 条待导入记录的预览表格(地址、名称、标签),并在继续前征求用户确认。

第 4 步 — 检查现有联系人(仅适用于 50 行及以上的导入)

对于小型导入(少于 50 行),跳过此步骤,直接开始导入——仅为少数联系人获取整个通讯录会造成不必要的延迟。

对于较大的导入,获取当前通讯录,以识别哪些地址已有标签。这有助于用户了解哪些联系人将被新建,哪些将被更新。

query AddressBook($limit: Int, $offset: Int) {
  customAccountNameLabel(limit: $limit, offset: $offset) {
    results {
      originalIdentifier
      labelValue
      tags
    }
    totalCount
  }
}

每次获取 500 条,分页遍历所有结果。构建一个以 originalIdentifier.lower() 为键的查找字典。

将导入列表与之比对,并报告:

  • 新联系人 — 当前通讯录中不存在的地址
  • 更新 — 已存在、但将获得新名称或标签的地址

重要:setCustomAccountNameLabelTags 是替换操作,而非追加。如果某个联系人当前的标签为 ["Exchange", "Custodian"],而导入文件中是 ["Vendor"],旧标签将被覆盖。对于任何已有标签且即将更新的联系人,请向用户发出警告。

继续操作前,先向用户展示此明细。如果有更新,请列出几个示例,展示旧名称 → 新名称,供用户检查确认。

第 5 步 — 导入联系人

对每一行通过验证的数据,调用两次 API:

5a. 设置联系人名称:

mutation SetContactName($identifier: String, $labelValue: String) {
  setCustomAccountName(identifier: $identifier, labelValue: $labelValue) {
    accountTxsSummary {
      accountIdentifier
      displayName
    }
  }
}

变量:

{
  "identifier": "<the address>",
  "labelValue": "<the contact name>"
}

5b. 设置标签(仅当该行包含标签时):

mutation SetContactTags($identifier: String!, $tags: [String]!) {
  setCustomAccountNameLabelTags(identifier: $identifier, tags: $tags) {
    accountTxsSummary {
      accountIdentifier
      displayName
    }
  }
}

变量:

{
  "identifier": "<the address>",
  "tags": ["Exchange", "Custodian"]
}

**批处理策略:**API 没有批量端点。对于小型导入(少于 20 个联系人),并行执行所有名称变更,然后并行执行所有标签变更——这样既快速又安全。对于较大的导入,每批并行处理 10 次调用,避免 API 负载过高,并每处理 25 个联系人向用户显示一次进度(例如:“已导入 25/142……”)。

**错误处理:**如果某个地址的变更失败,记录错误并继续处理下一行。不要中止整个导入。汇总所有失败项,以便生成摘要。

第 6 步 — 摘要

所有变更完成后,提供摘要:

  • 成功导入的联系人总数(已设置名称)
  • 已设置标签的联系人总数
  • 任何失败项(列出地址和错误消息)

如果有失败项,建议用户使用同一文件再次运行此技能进行重试——已导入的联系人只会被更新(名称变更操作具有幂等性)。

边缘情况

  • 文件没有标题行:如果首行不包含可识别的列名,请告知用户预期的格式,并让他们修正文件。
  • 文件列不正确:如果找不到“Contact Address”列,则文件不可用。请报告找到的列以及预期的列。
  • 文件为空:如果文件有标题但没有数据行,请告知用户。
  • 所有名称均为空:如果每一行的 Contact Name 都为空,请告知用户——他们可能误传了未填写的模板。
  • 文件非常大(>500 行):提醒用户这需要一些时间,并征求确认。
  • 名称中含有特殊字符:原样传递——TRES 能处理标签中的 Unicode。
  • 地址大小写混杂:setCustomAccountName mutation 接受原样传入的地址。不要统一大小写——传递文件中的原始值。
  • 标签含有多余空格:" Exchange , Custodian " → 修剪为 ["Exchange", "Custodian"]。
  • 地址未出现在任何交易中:即使 TRES 从未在交易中见过这些地址,mutations 也能正常工作——它们会创建相应的地址簿条目。
  • 标签会被覆盖:setCustomAccountNameLabelTags 会完全替换现有标签。如果用户只想添加标签,需要先与现有标签合并(此技能不会自动执行此操作——它会直接替换)。更新已有标签的联系人时,请提醒用户这一点。
  • CSV BOM 前缀:由 Excel 保存的 CSV 包含 UTF-8 BOM(\ufeff),会破坏第一列的列标题。始终使用 encoding='utf-8-sig' 打开 CSV。
  • 分号分隔的 CSV:欧洲地区的 Excel 导出文件使用 ; 而非 ,。如果按逗号解析时未找到预期的标题,请改用分号重试。
  • XLSX 文件末尾的空行:openpyxl 会读取工作表末尾的空行。跳过所有值均为 None 或空字符串的行。

评论

支持 Markdown