关于 Sess
Sess SDK 让服务器向真人提问,并在收到经验证的回答后继续处理。它支持类型化问题、签名回执验证和交互式账单等单据,不要求使用 LLM 或 Agent 框架。
主要功能
- 01创建带类型字段的问题
- 02返回专属回答链接
- 03验证签名回执与问题内容
- 04支持发票、收据、报价和退款
- 05生成本地二维码
适用场景
- 01请求人工批准退款
- 02收集表单式决策并继续流程
- 03发送账单或报价供人审核
- 04验证已共享的决策凭证
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.sess.si/mcpclaude mcp add --transport http si-sess-sess https://mcp.sess.si/mcp{"mcpServers":{"si-sess-sess":{"type":"http","url":"https://mcp.sess.si/mcp"}}}在 Cursor 中打开{"servers":{"si-sess-sess":{"type":"http","url":"https://mcp.sess.si/mcp"}}}在 VS Code 中打开{"mcpServers":{"si-sess-sess":{"type":"http","url":"https://mcp.sess.si/mcp"}}}{"mcpServers":{"si-sess-sess":{"serverUrl":"https://mcp.sess.si/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Sess SDK
从你的服务端向某人提问,并继续使用其经过验证的回答。
创建并运行一个小型 Agent:
npm create @sess.si/agent@latest my-agent
**你将看到:**一个 Sess 链接。在手机上回答两个问题后,你的方案会连同经过验证的凭证一起显示在终端中。
在你自己的服务端项目中安装 SDK:
npm install --save-exact @sess.si/[email protected]
向某人提问
使用 Sess 开发者门户提供的开发者 API 密钥。请将其保存在服务端。 无需注册的托管演示是单独的试用流程;Sess 链接或试用凭证都不是所有者 API 密钥。你无需使用大模型、Agent 框架、Docker 或 Sess 源代码检出。
import { Sess } from '@sess.si/sdk';
const sess = new Sess({ apiKey: process.env.SESS_API_KEY });
const question = await sess.ask({
question: 'Approve the synthetic refund?',
fields: [
{ name: 'approved', label: 'Approve it', type: 'boolean' },
{ name: 'amount', label: 'Refund amount', type: 'number', minimum: 0 },
],
});
console.log(`Send this Sess link to the person: ${question.link}`);
const { approved, amount } = await question.answer(); // verified; the Session is now complete
if (approved) console.log(`Refund of ${amount.toFixed(2)} approved.`);
sess.ask() 会在本地检查问题,创建一次 Session,并在任何等待开始前返回 Sess 链接。该链接是一种持有者能力凭证:只将它发送给提问对象,切勿写入日志或分析数据。answer() 会等待提问对象(默认十分钟),根据确切的问题验证签名凭证,检查回答是否仍属于当前步骤,完成 Session,并返回通过你的字段输入的值。完成后会关闭 Session:该链接将不再接受回答。字段类型包括 text、number、integer、boolean、choice、multi_choice 和 rating(API 参考)。
如果等待超时(wait_ended,代码 WAIT_TIMEOUT)或你中止了等待,远程端不会发生任何变化:在同一个句柄上再次调用 answer() 即可。错误中的 outcome: "unknown" 表示无法确认完成状态;再次调用 answer() 会重放相同的完成操作。句柄仅保存在内存中。若要在重启后继续,请持久化 sessionId 和 revision,然后使用下方的 API 继续(集成)。
如果 Sess 拒绝了某次调用,错误会说明发生了什么以及该怎么做。如果 Sess 不接受某个密钥,会显示:“Sess did not accept your API key. Check SESS_API_KEY and the portal you made it on.” 错误消息会先显示,随后是代码和请求 ID:
try {
const question = await sess.ask({
question: 'Approve the synthetic refund?',
fields: [{ name: 'approved', label: 'Approve it', type: 'boolean' }],
});
console.log(`Send this Sess link to the person: ${question.link}`);
} catch (error) {
console.error(error.message); // what happened and what to do
const request = error.requestId ? `, request ${error.requestId}` : '';
console.error(`Details: ${error.code ?? error.kind}${request}`);
process.exitCode = 1;
}
保持简短
提问对象会在手机上阅读页面,因此 Sess 会让页面中的每部分内容都保持简短。长度按字符数(Unicode 码点)计算,Sess 不会截断内容:
| 内容 | 风格 | 最多 |
|---|---|---|
标题(question) | 一个问题或任务,约 40 个字符 | 80 |
按钮(submit_label) | 一个动词,1–3 个词 | 24 |
| 字段标签、选项 | 简短 | 60 |
帮助说明(字段 description) | 一条提示 | 160 |
| 标题下方的描述 | 一或两句话 | 280 |
| 标题 | 简短 | 60 |
| 记录说明文字 | 几个词 | 200 |
| 记录键 / 字符串值 | 按原样填写 | 40 / 200 |
文本(details) | 纯文本 | 4,000 |
按钮最多为 5 个。任何值超出限制时,都会返回一个指出该值的 SessError:
field 是一个 JSON 指针,例如 /question;limit 是允许的最大长度;length 是实际长度。错误消息会说明如何修正:标题的错误消息为“The title can be at most 80 characters. Keep it to a short heading, about 40.”;其他内容的错误消息示例为“/fields/0/label is 72 characters; the limit is 60. Shorten it to at most 60 characters.” 此时尚未创建任何内容(outcome 为 not_sent 或 rejected),因此请缩短该值并重新提问:
import { Sess, SessError } from '@sess.si/sdk';
declare function shorten(text: string, max: number): Promise<string>; // e.g. your model rewrites it
const sess = new Sess({ apiKey: process.env.SESS_API_KEY });
const fields = [{ name: 'approved', label: 'Approve it', type: 'boolean' }] as const;
async function askShort(question: string) {
try {
return await sess.ask({ question, fields });
} catch (error) {
if (!(error instanceof SessError) || error.field !== '/question' || error.limit === undefined)
throw error;
return sess.ask({ question: await shorten(question, error.limit), fields });
}
}
**发布状态:**当前发布版本为 0.2.0,通过 latest dist-tag 提供。此版本为 sess.ask 添加了 rating 字段和答题者。next 仍指向上一个发布候选版本 0.1.0-rc.10。变更日志介绍了各个版本;npm view @sess.si/sdk dist-tags 可查看注册表当前提供的内容。
商务
Sess 不收款:用户在 Sess 页面上批准账单,资金转移仍由你和你的支付处理商负责。
import { Sess, invoice } from '@sess.si/sdk';
const sess = new Sess({ apiKey: process.env.SESS_API_KEY });
const created = await sess.sessions.create({
interaction: invoice({
currency: 'CAD', // whole cents: 420000 is $4,200.00
reference: 'INV-2041',
rows: [{ name: 'Design retainer, October', amount: 420000 }],
lines: [{ label: 'GST 5%', amount: 21000, role: 'tax' }],
}),
});
console.log(`Send this Sess link to the person: ${created.data.human_url}`);
你首先会遇到以下三点:
- 行内容简短。 行名称最多 80 个字符,详情最多 160 个字符。超出长度的值会被拒绝,不会截断:
SessError会通过指针标明该值,例如/interaction/source/components/1/rows/0/name,并提供limit和length。 - 使用完整的最小货币单位。 金额是以该货币最小单位表示的整数:USD 使用美分,JPY 使用日元,BHD 使用 fils。
money(1250, 'USD')表示 12.50 美元;money(12.5, 'USD')会抛出异常,因为 Sess 从不舍入或转换金额。 - 总额必须准确。 构建器会根据你的行项目计算小计、总额和应付金额。你手动编写的
items组件若小计与各行之和不符,会被拒绝并返回 HTTP 400:
{
"error": {
"code": "INVALID_SCHEMA",
"field": "/interaction/source/components/0/totals/0/amount",
"expected": 441250,
"actual": 451248
}
}
invoice()、receipt()、quote()、refund() 和 purchaseOrder() 各自都会返回一个普通的交互式 Surface,可用于 sess.sessions.create({ interaction }):账单以 items 卡片呈现,文档的 reference 使用普通名称显示,并包含用户需要的按钮(Approve 和 Decline;收据上为 Continue;报价单上为 Accept)。refund() 会在“Refund total”下显示正数金额。行项目中的 quantity 允许用户修改数量,并会添加一个 Request changes 按钮;你的 Agent 会通过新版本和更新后的金额进行回复。items() 只构建卡片;lintText() 则会在文本中查找 Markdown 表格,而用户看到的会是竖线。请参阅 API 参考。
Sess 不会:收取或转移款项、转换货币、计算税费或价格、展示你的徽标或品牌,或允许其他网站嵌入该页面(frame-ancestors 'none')。
进阶:完整的 Surface API
import { Sess } from '@sess.si/sdk';
const sess = new Sess({ apiKey: process.env.SESS_API_KEY });
const created = await sess.sessions.create({
interaction: {
mode: 'interactive',
title: 'Review a synthetic invoice',
source: {
kind: 'sess_surface',
components: [
{ type: 'record', label: 'INV-001', fields: { amount: 120 } },
{
type: 'field',
name: 'amount',
label: 'Correct amount',
required: true,
schema: { type: 'number', minimum: 0 },
value: 120,
},
],
},
actions: [{ id: 'submit', label: 'Submit review', intent: 'submit' }],
},
});
// Privately deliver created.data.human_url through your application's handoff.
// It is a bearer capability: do not put it in ordinary logs or analytics.
const answer = await sess.sessions.waitForResponse(created.data.id, {
revision: created.data.revision,
});
const verified = await sess.receipts.verifyResponse({
sessionId: created.data.id,
response: answer.response,
});
const amount = verified.response.data.amount;
if (typeof amount !== 'number' || !Number.isFinite(amount)) {
throw new Error('Expected an accepted numeric amount');
}
验证会检查收据是否由你的工作区签发。Sess 会在已验证的响应中标明你的工作区(Sess-Workspace-Id 标头),因此你无需设置任何内容。如果运行时未发送该标头,请根据可信的部署设置配置 expectedWorkspaceId;否则验证会以 VERIFICATION_CONTEXT_MISSING 失败。SDK 绝不会从未经验证的收据中读取工作区。
快速入门函数包含一个私有交付回调。 三轮续接示例会持久化变更意图,并在发布或完成前检查答案是否仍对应当前预期的业务步骤。其存储和工作器租约由应用负责管理。请参阅集成指南。
验证决策包
决策包是一项由其所有者选择分享的已接受决策,其中包含已签名的收据、精确的 Surface 和输入,以及签发方的公钥。请在你自己的计算机上使用你信任的密钥验证它(切勿使用决策包内的密钥):
npx -p @sess.si/[email protected] sess verify bundle.json --issuer https://api.sess.si --keys sess-receipt-keys.json
sess 命令最早随 0.1.0-rc.5 发布;此后的任何版本(包括 0.2.0)都包含该命令。
如果验证通过,你会看到 Valid decision bundle.,以及已接受的内容、时间和对应版本;否则会看到 Invalid 和第一个失败原因。退出状态码:0 表示有效,1 表示无效,2 表示用法错误;添加 --json 可查看完整结果。不会向任何地方发送数据。在代码中,请使用 @sess.si/sdk/receipts 中的 verifyDecisionBundle(安全性)。格式:receipt-v1 和 bundle-v1。
将链接显示为二维码
当对方使用笔记本电脑,而您希望对方用手机回复时,可在本地将链接绘制为二维码,不发起网络请求:
import { printQr, qr } from '@sess.si/sdk/qr';
const link = 'https://sess.si/s/synthetic-link'; // the link sess.ask() returned
console.log(link);
printQr(link); // prints "Scan to answer on your phone" and the code, on an interactive terminal only
const svg = qr(link, { format: 'svg' }); // also 'png' (bytes) and 'terminal' (text)
在对方能看到屏幕但看不到手机的场景中使用:桌面聊天窗口、仪表板、自助服务终端或打印件。短信中不要使用,或者对方已经在使用手机时也不要使用。Sess 不会显示或发送此代码;由您的 Agent 决定。没有 TTY、在 CI 中(设置了 CI)、在生产环境中(NODE_ENV=production)、使用 --no-qr 或 { qr: false } 时,printQr 不会输出任何内容;设置 NO_COLOR 时会以无颜色的方式绘制。该代码只是私密链接的另一种形式:请与链接一并妥善保管,切勿将其写入日志、分析数据或 URL。
运行时和导入
支持:维护中的 Node 22 版本(不低于 22.14)以及 Node 24(推荐)。
面向 TypeScript 使用者的声明以 5.9 及当前稳定版本为目标。JavaScript 使用者无需编译器。
该软件包只包含一个 ESM 构建版本。CommonJS 应用使用 await import('@sess.si/sdk'),如 CommonJS 示例 所示;同步 require 不属于受支持的约定。
入口点包括 @sess.si/sdk、@sess.si/sdk/receipts、@sess.si/sdk/webhooks 和 @sess.si/sdk/qr。导入或构造 SDK 不会联系服务、启动服务端、读取凭据文件或记录数据。
错误和重试
错误为 SessError,在适用时包含稳定的 kind、API code、status、requestId、attempts 和写入 outcome 字段。默认错误中会省略服务端响应正文和请求机密信息。
创建 Session 只会尝试一次。结果未知可能意味着 Session 已创建,但其私密 URL 已丢失。切勿自动重新创建。如果收到有效的创建响应正文,但响应头有问题,请显式检查 error.getRecoveryResult(),并妥善保护其中的能力信息。
发布和完成操作要求提供强引用形式的 ifMatch。在执行持久化写入前,请持久保存正文、原始 ETag 和显式的 idempotencyKey。内部重试会保留这些值及同一个已解析凭据。收到 409 或 412 时,SDK 会将其返回给调用方;SDK 绝不会刷新 ETag 来强行写入。
仍支持直接使用 HTTP
无需 SDK 即可执行相同的创建操作:
curl --request POST https://api.sess.si/v1/sessions \
--header "Authorization: Bearer $SESS_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @interaction.json
这里的 interaction.json 包含相同的 { "interaction": ... } 请求正文。响应中包含私密的人类可读 URL;请保护终端输出并禁用请求跟踪。完整约定见 OpenAPI。
指南
- API 参考:支持的操作、经过验证的响应、选项和错误。
- 集成:编写、生命周期、验证、持久化和未来边界。
- 安全和收据示例。
- Webhooks和带持久化收件箱边界的 Node 接收器。
- 兼容性、迁移到注册表软件包和发布操作手册。
- 纯 Node 快速入门:从首次调用到验证答案的完整程序。
Sess 会渲染用户看到的页面;此 SDK 不提供外观设置。
贡献 · 安全问题报告 · Apache-2.0
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。