关于 outseta
面向 SaaS 开发者的 Outseta 集成技能,涵盖身份验证、计费、支持和 API 工作流,也介绍用于查询和操作实时 Outseta 账户数据的 MCP 服务。
主要功能
- 01React 身份验证与个人资料组件
- 02Node.js API 和 webhook 辅助工具
- 03JWT 与 webhook 验证
- 04Outseta REST API 指引
- 05用于账户数据的 MCP 工具
适用场景
- 01在 React 应用中添加 Outseta 登录和受限路由
- 02在服务器端验证 JWT 与 webhook 签名
- 03通过 MCP 查询和更新账户记录
MCP 相关
Outseta MCP 服务使用 OAuth,提供文档搜索、只读账户 API 访问,以及创建或更新记录的工具。不支持删除操作。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ outseta/ agent-toolkit --skill outseta安装后在 Claude Code 中输入/outseta确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/rest-api.mdtemplates/emaillist.htmlleadcapture.htmllogin.htmllogout.htmlprofile.htmlsignup.htmlsupport.html详细介绍
Outseta 概述
Outseta 是面向 SaaS 创始人的一体化操作系统,集成了 CRM、身份验证、计费和客户支持。它旨在处理 SaaS 产品的“业务逻辑”,让开发者专注于“功能逻辑”。
核心架构
1. 关系型数据模型(优先支持 B2B)
Outseta 的 CRM 从一开始就支持基于团队的 SaaS:
- Person: 由
Uid标识的单个用户。 - Account: 公司或团队实体。订阅和计费信息都归属于此。
- PersonAccount: 将 Person 与 Account 关联起来的联接实体。这支持复杂的关系,例如一个用户可以属于多个组织。
- 事实来源: 将 Outseta 视为身份和付款状态的主要事实来源。
2. 身份验证与安全
- JWT(JSON Web Token): Outseta 使用 JWT 管理会话。Outseta 专属声明采用命名空间:
sub是 Person 的 Uid,而outseta:accountUid、outseta:planUid、outseta:isPrimary则携带账户/套餐上下文。JWT 中没有PersonUid/AccountUid/planUid声明——进行套餐访问控制时,请读取outseta:planUid。 - 验证: 在服务端通过 Outseta 的 JWKS(JSON Web Key Set) 验证令牌,密钥直接从
/.well-known/jwks获取——该端点是固定的,因此直接从中读取签名密钥即可(验证令牌本身不需要经过发现流程)。另外,将 Outseta 集成为登录(OIDC)提供方时,应从/.well-known/openid-configuration发现端点(authorization_endpoint/token_endpoint/userinfo_endpoint/jwks_uri),不要将这些端点硬编码。 - 受限内容: 使用 Outseta 脚本,根据用户的订阅套餐或登录状态,通过
data-o-*属性自动显示/隐藏 UI 元素。
集成模式
前端(React)
请使用官方的 @outseta/react 包,不要复制此工具包中的 React 模板。
npm install @outseta/react
在渲染 OutsetaProvider 之前,先在应用外壳中加载 Outseta 脚本:
<script>
var o_options = {
domain: "your-company.outseta.com",
// Include the widget modules you render: auth, profile, support, emailList, leadCapture.
load: "auth,profile,support,emailList,leadCapture,nocode",
};
</script>
<script src="https://cdn.outseta.com/outseta.min.js" data-options="o_options"></script>
使用该包导出的功能来处理身份验证状态、小部件、受限路由和附加项购买流程:
import {
OutsetaProvider,
ProtectedRoute,
PurchaseAddonButton,
useOutseta,
} from "@outseta/react";
function Header() {
const { user, isLoading, openLogin, openSignup, openProfile, logout } = useOutseta();
if (isLoading) return null;
return user ? (
<>
<button onClick={() => openProfile({ tab: "profile" })}>Profile</button>
<button onClick={logout}>Logout</button>
</>
) : (
<>
<button onClick={() => openSignup()}>Sign up</button>
<button onClick={() => openLogin()}>Login</button>
</>
);
}
export function App() {
return (
<OutsetaProvider>
<Header />
<ProtectedRoute plans={["plan_uid"]}>
<PremiumFeature />
</ProtectedRoute>
<PurchaseAddonButton addonUid="addon_uid">Buy add-on</PurchaseAddonButton>
</OutsetaProvider>
);
}
@outseta/react 导出:
- 用于身份验证/用户状态的
OutsetaProvider和useOutseta。 - 无头身份验证/个人资料组件:
AuthEmbed、AuthButton、LoginButton、SignupButton、ProfileEmbed、ProfileButton、LogoutButton、ProtectedRoute、AuthCta、UpgradeCta和PurchaseAddonButton。 - 无头支持、邮件列表和潜在客户信息收集组件:
SupportEmbed、SupportButton、EmailListEmbed、EmailListButton、EmailListForm、LeadCaptureEmbed和LeadCaptureButton。 - 用于访问 Outseta REST API 的
createClient和生成的原生 React 数据钩子。
生成的 API 钩子不需要外部数据获取库或提供程序。它们会在挂载时获取数据,提供 refetch,但有意不提供跨组件缓存、请求去重或后台重新获取功能。使用用户的 bearer accessToken 创建浏览器 API 客户端,并通过每个钩子的 request 选项传入该客户端:
import { createClient, useAccountGetAllAccounts } from "@outseta/react";
const client = createClient({
subdomain: "your-company",
accessToken,
});
const { data, error, isLoading, refetch } = useAccountGetAllAccounts(undefined, {
request: client,
});
切勿在浏览器代码中暴露 Outseta API 密钥凭据。
前端(无代码/低代码和纯 HTML)
- Magic Script: 为 Outseta 域名定义
o_options,并在应用外壳中加入<script src="https://cdn.outseta.com/outseta.min.js" data-options="o_options"></script>。 - 小部件: 通过数据属性(例如
data-o-auth="1")或全局对象Outseta触发小部件。 - 生命周期事件: 使用
Outseta.on('event', callback)响应登录、登出或个人资料更新。 - 受限内容: 使用 Outseta 脚本,根据用户的订阅套餐或登录状态,通过
data-o-*属性自动显示/隐藏 UI 元素(例如data-o-anonymous="1"、data-o-authenticated="1")。在 React 应用中,优先使用@outseta/react的状态和组件,以实现更可靠的 SPA 行为。
后端(Node.js)
请使用官方 @outseta/node-sdk 包,而不要复制此工具包中的 Node.js 模板。
npm install @outseta/node-sdk
该包提供用于服务端 API 客户端、JWT 验证、Webhook 签名验证、Express Webhook 路由、生成用户访问令牌和基于用量的计费的辅助函数:
import {
createClient,
createOutsetaWebhookHandler,
generateAccessToken,
outsetaWebhookTextParserOptions,
trackUsage,
verifyJwt,
} from "@outseta/node-sdk";
import express from "express";
const adminClient = createClient({
subdomain: process.env.OUTSETA_SUBDOMAIN!,
apiKey: process.env.OUTSETA_API_KEY!,
apiSecret: process.env.OUTSETA_API_SECRET!,
});
const payload = await verifyJwt(userAccessToken, {
subdomain: process.env.OUTSETA_SUBDOMAIN!,
});
const generatedToken = await generateAccessToken(adminClient, "[email protected]");
await trackUsage(adminClient, {
accountUid: "account_uid",
addOnUid: "addon_uid",
amount: 1,
});
const app = express();
app.post(
"/outseta/webhook",
express.text(outsetaWebhookTextParserOptions),
createOutsetaWebhookHandler({
signingKey: process.env.OUTSETA_WEBHOOK_SIGNING_KEY!,
async onWebhook(payload) {
// Handle Activity Notification payload.
},
}),
);
重要的后端注意事项:
- 仅在服务器上使用 API 密钥凭据。
- 对于用户范围的服务器请求,请使用
{ subdomain, accessToken }创建客户端。 - 请根据完全相同的原始请求正文验证 Webhook 签名。在 Express 中,请在
createOutsetaWebhookHandler之前,为 Webhook 路由使用express.text(outsetaWebhookTextParserOptions)。 - 如需使用完整的生成 REST API 函数,请使用
@outseta/api-client,并在需要时通过withClient(client)传入 SDK 客户端。
REST API
- 用于服务器到服务器通信、自定义引导流程或管理任务。
- 基础 URL:
https://your-domain.outseta.com/api/v1/
请参阅 REST API。
关键开发者概念
- Uid: Outseta 中任何实体的唯一标识符。请将其用作本地数据库(例如 Convex)中的外键。
- Account Stage: 跟踪客户所处的生命周期阶段(例如试用中、活跃、逾期未付、已取消)。
- 嵌入组件: Outseta 对其覆盖层小组件(注册、登录、个人资料、帮助台)的称呼。
MCP 服务
Outseta MCP 服务(https://agent.outseta.com/mcp,OAuth 登录)可让集成基于最新文档运行,并检查或更改实时账户数据。它提供三个工具:
| 工具 | 网络 | 用途 |
|---|---|---|
bash | 无 | 搜索知识库(/root/docs/kb)和 REST API 参考(/root/docs/api) |
javascript_read | 对账户 API 执行 GET/HEAD | 读取人员、账户、订阅、套餐、邮件列表;验证写入结果 |
javascript_write | 对账户 API 执行 POST/PUT/PATCH | 创建和更新记录。必须提供 writeSummary。始终不提供 DELETE。 |
研究工作流
- 概念和操作指南:运行
grep -ril "<term>" /root/docs/kb,然后阅读文章。请引用其 frontmatter 中的sourceArticleUrl,而不是工作区路径。 - REST 约定:
/root/docs/api/README.md介绍Authorization: Outseta {key}:{secret}方案、items/metadata列表封装、作为从零开始的页码索引的offset、limit上限(100;请求子字段时为 25)、筛选运算符,以及 Webhook 活动列表。 - 端点详情:每个端点对应一个页面,例如
/root/docs/api/crm--person-getallpeople.md。Client call: 行给出了 JavaScript 工具使用的生成函数及参数顺序。/root/outseta.d.ts包含准确的类型定义;请使用 grep 搜索,而不要通读整个文件。
账户操作
import { createClient, personGetAllPeople, personUpdatePerson } from "/root/outseta.js";
const client = createClient(); // uses the MCP session's auth
const { items, metadata } = (
await personGetAllPeople({ Email: "[email protected]", fields: "Uid,Email,LastName" }, { client })
).data;
// javascript_write only, with a writeSummary such as "Set LastName to Hopper on person <Uid>":
await personUpdatePerson(items[0].Uid, { LastName: "Hopper" }, { client });
- 优先使用生成函数,而不是
client("/api/v1/...")。{ client }始终放在最后一个options参数中。 - 先读后写:查询更改涉及的确切记录,向用户展示操作范围,并在执行任何批量或不可逆写入之前征求确认。
- 不能通过 MCP 执行删除操作。请引导用户使用 REST
DELETE端点或 Outseta UI。
嵌入示例(仅纯 JS/HTML)
这些模板仍保留在此工具包中,供非 React 或低代码集成使用:
- 登录: 标准登录小组件。请参阅
login.html - 注册: 可选默认值的注册小组件。请参阅
signup.html - 个人资料: 用户个人资料和订阅管理。请参阅
profile.html - 注销: 注销按钮和链接模式。请参阅
logout.html - 潜在客户捕获: 自定义潜在客户捕获表单。请参阅
leadcapture.html - 邮件列表: 邮件列表订阅表单。请参阅
emaillist.html - 支持: 支持工单和知识库集成。请参阅
support.html