mcpField
O
outseta

outseta

github.com/outseta开发12110 次安装5 周前更新
代码仓库

关于 outseta

面向 SaaS 开发者的 Outseta 集成技能,涵盖身份验证、计费、支持和 API 工作流,也介绍用于查询和操作实时 Outseta 账户数据的 MCP 服务。

主要功能

  1. 01React 身份验证与个人资料组件
  2. 02Node.js API 和 webhook 辅助工具
  3. 03JWT 与 webhook 验证
  4. 04Outseta REST API 指引
  5. 05用于账户数据的 MCP 工具

适用场景

  1. 01在 React 应用中添加 Outseta 登录和受限路由
  2. 02在服务器端验证 JWT 与 webhook 签名
  3. 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.md
templates/
emaillist.html
leadcapture.html
login.html
logout.html
profile.html
signup.html
support.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。
研究工作流
  1. 概念和操作指南:运行 grep -ril "<term>" /root/docs/kb,然后阅读文章。请引用其 frontmatter 中的 sourceArticleUrl,而不是工作区路径。
  2. REST 约定:/root/docs/api/README.md 介绍 Authorization: Outseta {key}:{secret} 方案、items/metadata 列表封装、作为从零开始的页码索引的 offset、limit 上限(100;请求子字段时为 25)、筛选运算符,以及 Webhook 活动列表。
  3. 端点详情:每个端点对应一个页面,例如 /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

评论

支持 Markdown