Подключение аккаунтов конечных пользователей с ProjectConnector
Используйте ProjectConnector, когда каждому пользователю продукта нужно подключить собственный аккаунт провайдера. Backend идентифицирует каждого пользователя по externalUserId, создаёт authorization links, хранит ID подключённых аккаунтов и выполняет actions для этого пользователя.
Этот путь использует project API key вида oo_proj_…. Он отличается от personal key api_…, который используется с Connector.
Подключите свой Agent
ProjectConnector предоставляет вызовы сервиса подключений. OOMOL обрабатывает авторизацию провайдеров, хранение учётных данных, обновление token и выполнение операций. Ваш продукт отвечает за аутентификацию пользователей, привязку аккаунтов и обработчики инструментов Agent.
Если Agent работает на бэкенде, обработчики могут вызывать ProjectConnector напрямую. Если он работает на устройстве пользователя, отправляйте запросы инструментов на бэкенд продукта с аутентификацией. Project API key всегда остаётся на этом бэкенде.
Конфигурация размещённого MCP для личных и командных подключений использует аккаунты пользователей и команд OOMOL. Для аккаунтов пользователей SaaS используйте ProjectConnector или SaaS HTTP API. Клиенту, требующему MCP, нужен MCP-адаптер вашего продукта на бэкенде с аутентификацией пользователей.
Подготовьте project
Перед реализацией runtime flow создайте в OOMOL Console следующие ресурсы:
- Project Connector.
- Provider config для каждого сервиса, доступного пользователям.
- Project API key, сохранённый в менеджере секретов backend.
В руководстве Connector for SaaS описаны настройка Console и соответствующие REST-запросы.
Установите и инициализируйте
npm install @oomol-lab/connector
import { ProjectConnector } from "@oomol-lab/connector";
const project = new ProjectConnector({
apiKey: process.env.OOMOL_PROJECT_API_KEY!,
});
Создайте запрос авторизации OAuth
Используйте стабильный ID из собственной базы пользователей как externalUserId:
const request = await project.connect.oauth("user_42", {
service: "gmail",
connectionName: "work",
returnUri: "https://app.example.com/connected",
});
redirectUserTo(request.authorizationUrl);
После авторизации пользователя дождитесь конечного состояния запроса:
const connected = await project.waitForConnection(request);
if (connected.status === "connected") {
saveConnectedAccountId(connected.connectedAccountId);
}
project.connect.oauth возвращает запрос авторизации, ожидающий действия пользователя. Только после успешной авторизации waitForConnection возвращает connectedAccountId в результате запроса.
Для провайдеров с API key и custom credential используйте connect.apiKey или connect.customCredential. Эти методы проверяют credential и синхронно возвращают подключённый аккаунт.
Выполните action для одного пользователя
const result = await project.execute(
"user_42",
"gmail.search_threads",
{ query: "is:unread" },
{ connectedAccountId: "ca-1" },
);
Передавайте connectedAccountId, когда он известен. Он выбирает конкретный аккаунт и не зависит от последнего активного аккаунта. Если продукт использует стабильные aliases, доступен connectionName.
Если несколько операций относятся к одному запросу или job, один раз привяжите пользователя с помощью forUser:
Для примера Slack требуется существующее подключение этого пользователя с именем «work». Используйте имя, сохранённое вашим backend для этой учётной записи Slack. forUser привязывает только пользователя; учётная запись выбирается в параметрах execute.
const user = project.forUser("user_42");
await user.execute(
"slack.post_message",
{ channel: "#general", text: "shipped" },
{ connectionName: "work" },
);
Предоставьте операцию как инструмент Agent
Этот независимый от фреймворка дескриптор показывает schema и обработчик для регистрации в вашем Agent-фреймворке. Перед созданием проверьте аутентификацию запроса, право пользователя на операцию и загрузите привязку его Gmail-аккаунта из базы данных. currentUser.id — external user ID, определённый бэкендом; storedAccount.connectedAccountId принадлежит этому пользователю. Эти значения не берутся из аргументов модели.
const searchMailTool = {
name: "search_mail",
description: "Search the current user's Gmail threads.",
inputSchema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
additionalProperties: false,
},
execute: async (input: { query: string }) =>
project.forUser(currentUser.id).execute(
"gmail.search_threads",
input,
{ connectedAccountId: storedAccount.connectedAccountId },
),
};
Проверяйте аргументы по schema перед вызовом обработчика. Модель передаёт только поисковый запрос. Начните с нужных продукту операций и фильтруйте их по подключённым сервисам пользователя; SDK не регистрирует все операции как инструменты Agent автоматически.
Сохраняйте явные границы продукта
Ваш продукт аутентифицирует собственных пользователей и контролирует доступные им провайдеры и actions. Храните project API key на backend, передавайте постоянный externalUserId и сохраняйте полученный selector аккаунта рядом с соответствующим пользователем продукта.
В справочнике TypeScript SDK описаны поля жизненного цикла authorization requests и connected accounts, точные типы actions, ошибки, повторные попытки, параметры ожидания и полный API ProjectConnector.