Snapshot治理数据协议

一个用于Snapshot平台的模型上下文协议服务器,允许AI助手读取治理数据(如空间、提案、投票、投票权)并代表用户执行操作(如投票、创建提案、关注空间)。

  • by snapshot-labs
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 snapshot-labs/snapshot-mcp

使用说明

快照MCP

A. 模型上下文协议 服务器用于 快照.让人工智能助手读取治理数据(空间、提案、投票、投票权),并通过快照的GraphQL API代表用户行事(投票、创建提案、关注空间)。可作为托管端点在 https://mcp.snapshot.box,或可自住。

工具

snapshot-query

对快照API运行任何GraphQL查询。用户的地址会自动绑定为 $user --在查询中声明它并引用它;不要把它传进去 variables.

输入 类型 描述
query string GraphQL查询字符串
variables object? GraphQL变量

示例--获取空间的活动提案:

query ($space: String!) {
  proposals(first: 10, where: { space: $space, state: "active" }) {
    id
    title
    choices
    scores
    votes
    end
  }
}

snapshot-schema

返回快照GraphQL架构。之前叫这个 snapshot-query 仅当查询在未知字段或筛选器上失败时。响应很大,所以不要先发制人地调用它。

无输入。

snapshot-vote

对Snapshot提案进行投票。该提案的投票 type 和 privacy 从快照中获取并自动应用,因此调用者不需要指定它们。再次呼吁同一提案 替换 上次投票(这是用户更改投票的方式)。

输入 类型 描述
space string 空间ID符号(例如。 "ens.eth")
proposal string 提案ID(十六进制字符串)
choice number | number[] | object 一个数字 basic/single-choice,一组索引 approval/ranked-choice,或 { "1": weight, "2": weight, ... } 为了 weighted/quadratic
reason string? 投票理由。在Shutter加密提案中被忽略。

需要配置钱包以进行签名(请参阅 配置).在HTTP上,这是OAuth管理的CDP别名;在stdio上,它是 ALIAS_PRIVATE_KEY如果用户尚未授权别名,则该工具会返回授权URL供他们访问。

snapshot-propose

创建快照提案。大多数默认值来自空间本身,因此对于典型用途,您只需要 space, title,以及 body。空间的强制投票类型、投票时段、快照块和隐私模式从快照中读取并自动应用。

输入 类型 描述
space string 空间ID符号(例如。 "ens.eth")
title string 建议书标题
body string? 提案正文(标记)
discussion string? 讨论链接
type string? 其中之一 basic, single-choice, approval, ranked-choice, weighted, quadratic默认为空间强制执行的任何内容,或 basic.
choices string[]? 投票选择。默认为 ["For", "Against", "Abstain"] 为了 basic;任何其他类型都需要。
labels string[]? 提案标签ID
start number? 投票以秒为单位的unix时间戳开始。默认为 now + space.voting.delay.
end number? 投票以秒为单位的unix时间戳结束。默认为 start + space.voting.period (如果空间设置为无,则为3天)。
shielded boolean? 选择Shutter加密投票。只有当空间 voting.privacy 是 "any";空间与 voting.privacy === "shutter" 始终加密。

从以下位置读取快照块 https://rpc.snapshot.org/<chainId> 基于空间的网络。需要一个钱包,与 snapshot-vote.

snapshot-follow

在用户的关注列表中添加一个空格。在用户已经关注的空间上再次调用它是安全的——Snapshot不会重复关注。

输入 类型 描述
space string 空间ID符号(例如。 "ens.eth")

需要一个钱包,与 snapshot-vote 和 snapshot-propose.

用法

托管(克劳德桌面/Cloud.ai)

{
  "mcpServers": {
    "snapshot": {
      "type": "http",
      "url": "https://mcp.snapshot.box"
    }
  }
}

自足执行

要求: 包子 ≥ 1.0.0

bun install

HTTP服务器

bun start

监听港口 8080 默认情况下(用覆盖 PORT 有人)。

Stdio(本地)

bun run stdio

Claude桌面配置示例:

{
  "mcpServers": {
    "snapshot": {
      "command": "bun",
      "args": ["src/index.ts", "--stdio"],
      "cwd": "/path/to/snapshot-mcp",
      "env": {
        "ALIAS_PRIVATE_KEY": "0x..."
      }
    }
  }
}

配置

复制 .env.example 到 .env 并配置:

变量 描述
SNAPSHOT_API_KEY 快照API密钥 用于更高的速率限制(可选)
SNAPSHOT_API_URL GraphQL端点(默认 https://hub.snapshot.org/graphql)
PORT HTTP服务器端口(默认值: 8080)
BASE_URL OAuth元数据的公共URL(例如。 https://mcp.snapshot.box)
JWT_SECRET HS256密钥用于对访问令牌进行签名-- HTTP模式需要 (≥32个字符; openssl rand -hex 32)
CDP_API_KEY_ID Coinbase CDP API密钥ID- HTTP模式需要
CDP_API_KEY_SECRET Coinbase CDP API密钥机密- HTTP模式需要
CDP_WALLET_SECRET Coinbase CDP钱包密码-- HTTP模式需要
ALIAS_PRIVATE_KEY 单个私钥-- 仅限stdio模式 (HTTP服务器忽略)

HTTP服务器需要CDP凭据和JWT密钥。通过OAuth连接的每个用户都有自己的CDP管理的别名钱包,因此投票只能由授权特定别名的用户签名。访问令牌是用签名的无状态JWT(HS256) JWT_SECRET旋转这个秘密会使每个发行的代币无效。

认证流程

HTTP(克劳德桌面/Cloud.ai)——OAuth 2.0

HTTP服务器公开OAuth 2.0端点。Claude Desktop和Claude.ai将展示 “连接”按钮 这会自动触发流:

  1. Claude重定向到 /authorize
  2. 服务器创建一个新的每会话CDP别名钱包,并重定向到 snapshot.box/#/settings/alias/authorize/<alias> 带有回调URL
  3. 用户在快照上授权该别名
  4. 快照重定向回 /auth/callback
  5. 服务器从别名解析授权用户,生成身份验证码,并重定向回Claude
  6. Claude将代码交换为JWT(HS256)访问令牌 /token
  7. 所有后续请求都包含令牌——服务器验证签名,并从声明中读取用户及其CDP帐户

每个用户都有自己的CDP别名,因此一个用户不能代表另一个用户签署投票。令牌是可自我验证的,可以在服务器重启后继续使用(直到 JWT_SECRET 旋转)。

Stdio(本地)

  1. 呼叫 snapshot-vote --如果尚未授权,则返回授权URL
  2. 用户访问 snapshot.box/#/settings/alias/authorize/<alias> 授权
  3. 呼叫 snapshot-vote 再次-作品

发展

bun dev      # watch mode
bun test     # run security tests
bun lint     # ESLint
bun format   # Prettier