mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 11:03:27 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A useful app store needs accurate and selectable provider definitions. > - Local brand assets now cover the expanded provider set. > - Provider methods differ in transport, authentication, ownership, and required scope. > - This pull request expands the catalog and encodes those provider contracts. > - The benefit is a larger self-serve store with explicit setup choices. ## Linked Issues or Issue Description Refs #11965 This is stack 6 of 11. It depends on stack 5 and replaces another reviewable part of #11965. ## What Changed - Add and update provider definitions for the self-serve catalog. - Add Google Workspace connection methods and capability profiles. - Add catalog generation, ingestion, URL matching, and contract tests. - Update legacy key tests to use a provider that still uses header credentials. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - Result: 164 tests passed. - `pnpm build` ## Risks - An incorrect provider definition can offer the wrong setup method. - Contract tests verify transport, authentication, and provider URL behavior. - The change does not add a database migration. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Refs #` or (b) described the issue in this pull request - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
42 lines
3.8 KiB
TypeScript
42 lines
3.8 KiB
TypeScript
export const GOOGLE_WORKSPACE_CONNECTOR_PROFILE_IDS = [
|
|
"gmail.read", "gmail.draft", "drive.read", "drive.write", "docs.read", "docs.write",
|
|
"sheets.read", "sheets.write", "slides.read", "slides.write", "calendar.read",
|
|
"calendar.write", "chat.read", "chat.write", "people.read", "workspace-search.read",
|
|
] as const;
|
|
|
|
export type GoogleWorkspaceConnectorProfileId = (typeof GOOGLE_WORKSPACE_CONNECTOR_PROFILE_IDS)[number];
|
|
|
|
const auth = (scope: string) => `https://www.googleapis.com/auth/${scope}`;
|
|
|
|
export const GOOGLE_WORKSPACE_CONNECTOR_PROFILES: Readonly<Record<GoogleWorkspaceConnectorProfileId, {
|
|
appSlug: string;
|
|
serverUrl: string;
|
|
scopes: readonly string[];
|
|
writeTools: readonly string[];
|
|
}>> = {
|
|
"gmail.read": def("gmail", "https://gmailmcp.googleapis.com/mcp/v1", [auth("gmail.readonly")]),
|
|
"gmail.draft": def("gmail", "https://gmailmcp.googleapis.com/mcp/v1", [auth("gmail.readonly"), auth("gmail.compose")], ["create_draft"]),
|
|
"drive.read": def("google-drive", "https://drivemcp.googleapis.com/mcp/v1", [auth("drive.readonly")]),
|
|
"drive.write": def("google-drive", "https://drivemcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("drive.file")], ["copy_file", "create_file"]),
|
|
"docs.read": def("google-docs", "https://docsmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("documents.readonly")]),
|
|
"docs.write": def("google-docs", "https://docsmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("drive.file"), auth("documents")], ["update_doc"]),
|
|
"sheets.read": def("google-sheets", "https://sheetsmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("spreadsheets.readonly")]),
|
|
"sheets.write": def("google-sheets", "https://sheetsmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("drive.file"), auth("spreadsheets")], ["update_spreadsheet", "update_values", "update_formulas", "insert_dimension"]),
|
|
"slides.read": def("google-slides", "https://slidesmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("presentations.readonly")]),
|
|
"slides.write": def("google-slides", "https://slidesmcp.googleapis.com/mcp/v1", [auth("drive.readonly"), auth("drive.file"), auth("presentations")], ["update_presentation"]),
|
|
"calendar.read": def("google-calendar", "https://calendarmcp.googleapis.com/mcp/v1", [auth("calendar.calendarlist.readonly"), auth("calendar.events.freebusy"), auth("calendar.events.readonly")]),
|
|
"calendar.write": def("google-calendar", "https://calendarmcp.googleapis.com/mcp/v1", [auth("calendar.calendarlist.readonly"), auth("calendar.events.freebusy"), auth("calendar.events")], ["create_event", "update_event", "delete_event", "respond_to_event"]),
|
|
"chat.read": def("google-chat", "https://chatmcp.googleapis.com/mcp/v1", [auth("chat.spaces.readonly"), auth("chat.memberships.readonly"), auth("chat.messages.readonly"), auth("chat.users.readstate.readonly")]),
|
|
"chat.write": def("google-chat", "https://chatmcp.googleapis.com/mcp/v1", [auth("chat.spaces.readonly"), auth("chat.memberships.readonly"), auth("chat.messages.readonly"), auth("chat.users.readstate.readonly"), auth("chat.messages.create")], ["send_message"]),
|
|
"people.read": def("google-people", "https://people.googleapis.com/mcp/v1", [auth("directory.readonly"), auth("userinfo.profile"), auth("contacts.readonly")]),
|
|
"workspace-search.read": def("google-workspace-search", "https://workspacemcp.googleapis.com/mcp/v1", [auth("gmail.readonly"), auth("drive.readonly"), auth("calendar.readonly"), auth("chat.messages.readonly")]),
|
|
};
|
|
|
|
export function isGoogleWorkspaceConnectorProfileId(value: string): value is GoogleWorkspaceConnectorProfileId {
|
|
return Object.prototype.hasOwnProperty.call(GOOGLE_WORKSPACE_CONNECTOR_PROFILES, value);
|
|
}
|
|
|
|
function def(appSlug: string, serverUrl: string, scopes: readonly string[], writeTools: readonly string[] = []) {
|
|
return { appSlug, serverUrl, scopes, writeTools };
|
|
}
|