veryfront 0.1.589 → 0.1.591
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/cli/commands/styles/command.d.ts +1 -0
- package/esm/cli/commands/styles/command.d.ts.map +1 -1
- package/esm/cli/commands/styles/command.js +13 -1
- package/esm/cli/templates/manifest.d.ts +4 -13
- package/esm/cli/templates/manifest.js +5 -14
- package/esm/deno.js +1 -1
- package/esm/src/integrations/_data.d.ts.map +1 -1
- package/esm/src/integrations/_data.js +6 -8
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ interface StyleBuildContentContext {
|
|
|
5
5
|
environmentName?: string;
|
|
6
6
|
releaseId?: string;
|
|
7
7
|
}
|
|
8
|
+
export declare function normalizeStyleArtifactBuildConfigInput(parsed: unknown): unknown;
|
|
8
9
|
export declare function getUnderlyingVeryfrontClient(adapter: Awaited<ReturnType<typeof enhanceAdapterWithFS>>): {
|
|
9
10
|
client: VeryfrontApiClient;
|
|
10
11
|
contentContext: StyleBuildContentContext | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/styles/command.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,oBAAoB,EAIpB,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AAOxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAyB/C,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/styles/command.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,oBAAoB,EAIpB,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AAOxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAyB/C,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+BD,wBAAgB,sCAAsC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAU/E;AAoED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,GACxD;IACD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,cAAc,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CAC7E,CAyBA;AAwBD,wBAAsB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4GtE"}
|
|
@@ -21,6 +21,18 @@ const getStyleArtifactBuildConfigSchema = defineSchema((v) => v.object({
|
|
|
21
21
|
}
|
|
22
22
|
}));
|
|
23
23
|
const StyleArtifactBuildConfigSchema = lazySchema(getStyleArtifactBuildConfigSchema);
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
export function normalizeStyleArtifactBuildConfigInput(parsed) {
|
|
28
|
+
if (!isRecord(parsed)) {
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
if (parsed.source === "webhook" && isRecord(parsed.payload)) {
|
|
32
|
+
return parsed.payload;
|
|
33
|
+
}
|
|
34
|
+
return parsed;
|
|
35
|
+
}
|
|
24
36
|
function parseStyleArtifactBuildConfig(rawConfig) {
|
|
25
37
|
if (!rawConfig) {
|
|
26
38
|
throw new Error("Missing --config JSON");
|
|
@@ -32,7 +44,7 @@ function parseStyleArtifactBuildConfig(rawConfig) {
|
|
|
32
44
|
catch {
|
|
33
45
|
throw new Error("Invalid --config JSON");
|
|
34
46
|
}
|
|
35
|
-
return StyleArtifactBuildConfigSchema.parse(parsed);
|
|
47
|
+
return StyleArtifactBuildConfigSchema.parse(normalizeStyleArtifactBuildConfigInput(parsed));
|
|
36
48
|
}
|
|
37
49
|
function resolveStyleArtifactSelector(config) {
|
|
38
50
|
if (config.branch) {
|
|
@@ -246,19 +246,6 @@ declare namespace _default {
|
|
|
246
246
|
"tools/upload-file.ts": string;
|
|
247
247
|
};
|
|
248
248
|
};
|
|
249
|
-
"integration:dropbox": {
|
|
250
|
-
files: {
|
|
251
|
-
".env.example": string;
|
|
252
|
-
"app/api/auth/dropbox/callback/route.ts": string;
|
|
253
|
-
"app/api/auth/dropbox/route.ts": string;
|
|
254
|
-
"lib/dropbox-client.ts": string;
|
|
255
|
-
"tools/get-account.ts": string;
|
|
256
|
-
"tools/get-file.ts": string;
|
|
257
|
-
"tools/list-files.ts": string;
|
|
258
|
-
"tools/search-files.ts": string;
|
|
259
|
-
"tools/upload-file.ts": string;
|
|
260
|
-
};
|
|
261
|
-
};
|
|
262
249
|
"integration:figma": {
|
|
263
250
|
files: {
|
|
264
251
|
".env.example": string;
|
|
@@ -281,12 +268,16 @@ declare namespace _default {
|
|
|
281
268
|
"lib/user-id.ts": string;
|
|
282
269
|
"tools/add-issue-comment.ts": string;
|
|
283
270
|
"tools/create-issue.ts": string;
|
|
271
|
+
"tools/create-pr.ts": string;
|
|
284
272
|
"tools/get-issue.ts": string;
|
|
285
273
|
"tools/get-pr-diff.ts": string;
|
|
274
|
+
"tools/get-pr.ts": string;
|
|
286
275
|
"tools/get-repo.ts": string;
|
|
276
|
+
"tools/list-commits.ts": string;
|
|
287
277
|
"tools/list-issues.ts": string;
|
|
288
278
|
"tools/list-prs.ts": string;
|
|
289
279
|
"tools/list-repos.ts": string;
|
|
280
|
+
"tools/merge-pr.ts": string;
|
|
290
281
|
"tools/update-issue.ts": string;
|
|
291
282
|
};
|
|
292
283
|
};
|
|
@@ -246,19 +246,6 @@ export default {
|
|
|
246
246
|
"tools/upload-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createDriveClient } from \"../../lib/drive-client.ts\";\n\nconst DEFAULT_USER_ID = \"demo-user\";\n\nexport default tool({\n id: \"upload-file\",\n description:\n \"Upload or create a text file in Google Drive. Supports plain text, JSON, CSV, Markdown, and other text formats. Returns the new file ID and details.\",\n inputSchema: defineSchema((v) => v.object({\n name: v\n .string()\n .describe(\"Name of the file including extension (e.g., 'report.txt', 'data.json')\"),\n content: v.string().describe(\"Text content of the file\"),\n mimeType: v\n .string()\n .default(\"text/plain\")\n .describe(\n \"MIME type of the file. Examples: 'text/plain', 'application/json', 'text/csv', 'text/markdown'\",\n ),\n parentId: v\n .string()\n .optional()\n .describe(\"ID of the parent folder. If not provided, creates in root.\"),\n description: v.string().optional().describe(\"Optional description for the file\"),\n }))(),\n async execute({ name, content, mimeType, parentId, description }) {\n const client = createDriveClient(DEFAULT_USER_ID);\n const file = await client.uploadFile({ name, content, mimeType, parentId, description });\n\n return {\n id: file.id,\n name: file.name,\n mimeType: file.mimeType,\n size: file.size,\n createdTime: file.createdTime,\n modifiedTime: file.modifiedTime,\n webViewLink: file.webViewLink,\n webContentLink: file.webContentLink,\n };\n },\n});\n"
|
|
247
247
|
}
|
|
248
248
|
},
|
|
249
|
-
"integration:dropbox": {
|
|
250
|
-
"files": {
|
|
251
|
-
".env.example": "# Dropbox Integration Environment Variables\n\n# Dropbox App Key (Client ID)\n# Get this from https://www.dropbox.com/developers/apps\nDROPBOX_APP_KEY=your_app_key_here\n\n# Dropbox App Secret\n# Get this from https://www.dropbox.com/developers/apps\nDROPBOX_APP_SECRET=your_app_secret_here\n\n# Setup Instructions:\n# 1. Go to https://www.dropbox.com/developers/apps\n# 2. Create a new app or select an existing one\n# 3. Choose \"Scoped access\" as the API type\n# 4. Select \"Full Dropbox\" or \"App folder\" access\n# 5. Copy the App Key and App Secret\n# 6. Add the OAuth2 redirect URI: http://localhost:3000/api/auth/dropbox/callback\n# 7. Enable the following permissions in the Permissions tab:\n# - files.content.read\n# - files.content.write\n# - files.metadata.read\n# - files.metadata.write\n# - account_info.read\n# 8. Submit the app for production use if needed\n",
|
|
252
|
-
"app/api/auth/dropbox/callback/route.ts": "import { createOAuthCallbackHandler, dropboxConfig } from \"veryfront/oauth\";\nimport { tokenStore } from \"../../../../../lib/token-store.ts\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\n\nconst hybridTokenStore = {\n getTokens(serviceId: string, userId: string) {\n return tokenStore.getToken(userId, serviceId);\n },\n async setTokens(\n serviceId: string,\n userId: string,\n tokens: { accessToken: string; refreshToken?: string; expiresAt?: number },\n ) {\n await tokenStore.setToken(userId, serviceId, tokens);\n },\n async clearTokens(serviceId: string, userId: string) {\n await tokenStore.revokeToken(userId, serviceId);\n },\n setState(\n state: string,\n meta: {\n userId: string;\n serviceId: string;\n codeVerifier?: string;\n redirectUri?: string;\n scopes?: string[];\n createdAt: number;\n },\n ) {\n return oauthMemoryTokenStore.setState(state, meta);\n },\n consumeState(state: string) {\n return oauthMemoryTokenStore.consumeState(state);\n },\n};\n\nexport const GET = createOAuthCallbackHandler(dropboxConfig, { tokenStore: hybridTokenStore });\n",
|
|
253
|
-
"app/api/auth/dropbox/route.ts": "import { createOAuthInitHandler, dropboxConfig } from \"veryfront/oauth\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\nimport { requireUserIdFromRequest } from \"../../../../../lib/user-id.ts\";\n\nfunction getUserId(request: Request): string {\n return requireUserIdFromRequest(request);\n}\n\nexport const GET = createOAuthInitHandler(dropboxConfig, {\n tokenStore: oauthMemoryTokenStore,\n getUserId,\n});",
|
|
254
|
-
"lib/dropbox-client.ts": "import { getAccessToken } from \"./token-store.ts\";\n\nconst DROPBOX_API_URL = \"https://api.dropboxapi.com/2\";\nconst DROPBOX_CONTENT_URL = \"https://content.dropboxapi.com/2\";\n\nexport interface DropboxMetadata {\n \".tag\": \"file\" | \"folder\" | \"deleted\";\n name: string;\n path_lower?: string;\n path_display?: string;\n id: string;\n}\n\nexport interface DropboxFileMetadata extends DropboxMetadata {\n \".tag\": \"file\";\n client_modified: string;\n server_modified: string;\n rev: string;\n size: number;\n is_downloadable: boolean;\n content_hash?: string;\n}\n\nexport interface DropboxFolderMetadata extends DropboxMetadata {\n \".tag\": \"folder\";\n}\n\nexport interface ListFolderResult {\n entries: Array<DropboxFileMetadata | DropboxFolderMetadata>;\n cursor: string;\n has_more: boolean;\n}\n\nexport interface SearchResult {\n matches: Array<{\n match_type: {\n \".tag\": \"filename\" | \"content\" | \"both\";\n };\n metadata: {\n \".tag\": \"metadata\";\n metadata: DropboxFileMetadata | DropboxFolderMetadata;\n };\n }>;\n has_more: boolean;\n cursor?: string;\n}\n\nexport interface AccountInfo {\n account_id: string;\n name: {\n given_name: string;\n surname: string;\n familiar_name: string;\n display_name: string;\n };\n email: string;\n email_verified: boolean;\n disabled: boolean;\n country: string;\n locale: string;\n account_type: {\n \".tag\": \"basic\" | \"pro\" | \"business\";\n };\n}\n\nexport interface SpaceUsage {\n used: number;\n allocation: {\n \".tag\": \"individual\" | \"team\";\n allocated?: number;\n };\n}\n\nexport interface SharedLinkMetadata {\n url: string;\n id: string;\n name: string;\n path_lower?: string;\n link_permissions: {\n can_revoke: boolean;\n resolved_visibility?: {\n \".tag\": \"public\" | \"team_only\" | \"password\";\n };\n };\n}\n\nasync function requireAccessToken(): Promise<string> {\n const token = await getAccessToken();\n if (token) return token;\n throw new Error(\"Not authenticated with Dropbox. Please connect your account.\");\n}\n\nasync function parseDropboxError(response: Response): Promise<any> {\n return response.json().catch(() => ({}));\n}\n\nfunction throwDropboxError(response: Response, error: any): never {\n throw new Error(\n `Dropbox API error: ${response.status} ${error?.error_summary ?? response.statusText}`,\n );\n}\n\nasync function dropboxRPC<T>(\n endpoint: string,\n body: Record<string, unknown> = {},\n): Promise<T> {\n const token = await requireAccessToken();\n\n const response = await fetch(`${DROPBOX_API_URL}${endpoint}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throwDropboxError(response, await parseDropboxError(response));\n }\n\n return response.json();\n}\n\nasync function dropboxContent<T>(\n endpoint: string,\n args: Record<string, unknown>,\n content?: string | Uint8Array,\n): Promise<T> {\n const token = await requireAccessToken();\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Dropbox-API-Arg\": JSON.stringify(args),\n };\n\n if (content != null) {\n headers[\"Content-Type\"] = \"application/octet-stream\";\n }\n\n const response = await fetch(`${DROPBOX_CONTENT_URL}${endpoint}`, {\n method: \"POST\",\n headers,\n body: content,\n });\n\n if (!response.ok) {\n throwDropboxError(response, await parseDropboxError(response));\n }\n\n return response.json();\n}\n\nexport function getCurrentAccount(): Promise<AccountInfo> {\n return dropboxRPC<AccountInfo>(\"/users/get_current_account\");\n}\n\nexport function getSpaceUsage(): Promise<SpaceUsage> {\n return dropboxRPC<SpaceUsage>(\"/users/get_space_usage\");\n}\n\nexport function listFolder(\n path: string = \"\",\n options?: {\n recursive?: boolean;\n includeDeleted?: boolean;\n includeHasExplicitSharedMembers?: boolean;\n limit?: number;\n },\n): Promise<ListFolderResult> {\n return dropboxRPC<ListFolderResult>(\"/files/list_folder\", {\n path: path || \"\",\n recursive: options?.recursive ?? false,\n include_deleted: options?.includeDeleted ?? false,\n include_has_explicit_shared_members: options?.includeHasExplicitSharedMembers ?? false,\n limit: options?.limit ?? 100,\n });\n}\n\nexport function listFolderContinue(cursor: string): Promise<ListFolderResult> {\n return dropboxRPC<ListFolderResult>(\"/files/list_folder/continue\", { cursor });\n}\n\nexport function getMetadata(\n path: string,\n options?: {\n includeMediaInfo?: boolean;\n includeDeleted?: boolean;\n },\n): Promise<DropboxFileMetadata | DropboxFolderMetadata> {\n return dropboxRPC<DropboxFileMetadata | DropboxFolderMetadata>(\"/files/get_metadata\", {\n path,\n include_media_info: options?.includeMediaInfo ?? false,\n include_deleted: options?.includeDeleted ?? false,\n });\n}\n\nexport async function downloadFile(path: string): Promise<{\n content: string;\n metadata: DropboxFileMetadata;\n}> {\n const token = await requireAccessToken();\n\n const response = await fetch(`${DROPBOX_CONTENT_URL}/files/download`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Dropbox-API-Arg\": JSON.stringify({ path }),\n },\n });\n\n if (!response.ok) {\n throwDropboxError(response, await parseDropboxError(response));\n }\n\n const content = await response.text();\n const metadataHeader = response.headers.get(\"Dropbox-API-Result\");\n const metadata = metadataHeader ? JSON.parse(metadataHeader) : {};\n\n return { content, metadata };\n}\n\nexport function uploadFile(\n path: string,\n content: string | Uint8Array,\n options?: {\n mode?: \"add\" | \"overwrite\" | \"update\";\n autorename?: boolean;\n mute?: boolean;\n },\n): Promise<DropboxFileMetadata> {\n return dropboxContent<DropboxFileMetadata>(\n \"/files/upload\",\n {\n path,\n mode: options?.mode ?? \"add\",\n autorename: options?.autorename ?? false,\n mute: options?.mute ?? false,\n },\n content,\n );\n}\n\nexport function deleteFile(\n path: string,\n): Promise<DropboxFileMetadata | DropboxFolderMetadata> {\n return dropboxRPC<{ metadata: DropboxFileMetadata | DropboxFolderMetadata }>(\n \"/files/delete_v2\",\n { path },\n ).then((result) => result.metadata);\n}\n\nexport function moveFile(\n fromPath: string,\n toPath: string,\n options?: {\n allowSharedFolder?: boolean;\n autorename?: boolean;\n allowOwnershipTransfer?: boolean;\n },\n): Promise<DropboxFileMetadata | DropboxFolderMetadata> {\n return dropboxRPC<{ metadata: DropboxFileMetadata | DropboxFolderMetadata }>(\n \"/files/move_v2\",\n {\n from_path: fromPath,\n to_path: toPath,\n allow_shared_folder: options?.allowSharedFolder ?? false,\n autorename: options?.autorename ?? false,\n allow_ownership_transfer: options?.allowOwnershipTransfer ?? false,\n },\n ).then((result) => result.metadata);\n}\n\nexport function copyFile(\n fromPath: string,\n toPath: string,\n options?: {\n allowSharedFolder?: boolean;\n autorename?: boolean;\n allowOwnershipTransfer?: boolean;\n },\n): Promise<DropboxFileMetadata | DropboxFolderMetadata> {\n return dropboxRPC<{ metadata: DropboxFileMetadata | DropboxFolderMetadata }>(\n \"/files/copy_v2\",\n {\n from_path: fromPath,\n to_path: toPath,\n allow_shared_folder: options?.allowSharedFolder ?? false,\n autorename: options?.autorename ?? false,\n allow_ownership_transfer: options?.allowOwnershipTransfer ?? false,\n },\n ).then((result) => result.metadata);\n}\n\nexport function createFolder(\n path: string,\n autorename?: boolean,\n): Promise<DropboxFolderMetadata> {\n return dropboxRPC<{ metadata: DropboxFolderMetadata }>(\"/files/create_folder_v2\", {\n path,\n autorename: autorename ?? false,\n }).then((result) => result.metadata);\n}\n\nexport function searchFiles(\n query: string,\n options?: {\n path?: string;\n maxResults?: number;\n fileCategories?: Array<\n | \"image\"\n | \"document\"\n | \"pdf\"\n | \"spreadsheet\"\n | \"presentation\"\n | \"audio\"\n | \"video\"\n | \"folder\"\n | \"paper\"\n | \"others\"\n >;\n fileExtensions?: string[];\n },\n): Promise<SearchResult> {\n return dropboxRPC<SearchResult>(\"/files/search_v2\", {\n query,\n options: {\n path: options?.path ?? \"\",\n max_results: options?.maxResults ?? 20,\n file_categories: options?.fileCategories,\n filename_only: false,\n },\n });\n}\n\nexport async function createSharedLink(\n path: string,\n settings?: {\n requestedVisibility?: \"public\" | \"team_only\" | \"password\";\n linkPassword?: string;\n expires?: string;\n },\n): Promise<SharedLinkMetadata> {\n try {\n return await dropboxRPC<SharedLinkMetadata>(\"/sharing/create_shared_link_with_settings\", {\n path,\n settings: settings ?? {},\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"shared_link_already_exists\")) {\n const links = await listSharedLinks(path);\n if (links.length > 0) return links[0];\n }\n throw error;\n }\n}\n\nexport async function listSharedLinks(path?: string): Promise<SharedLinkMetadata[]> {\n const result = await dropboxRPC<{ links: SharedLinkMetadata[] }>(\"/sharing/list_shared_links\", {\n path: path ?? \"\",\n });\n return result.links;\n}\n\nexport function formatFileSize(bytes: number): string {\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n let size = bytes;\n let unitIndex = 0;\n\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n return `${size.toFixed(2)} ${units[unitIndex]}`;\n}\n\nexport function isFile(metadata: DropboxMetadata): metadata is DropboxFileMetadata {\n return metadata[\".tag\"] === \"file\";\n}\n\nexport function isFolder(metadata: DropboxMetadata): metadata is DropboxFolderMetadata {\n return metadata[\".tag\"] === \"folder\";\n}\n",
|
|
255
|
-
"tools/get-account.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport {\n formatFileSize,\n getCurrentAccount,\n getSpaceUsage,\n} from \"../../lib/dropbox-client.ts\";\n\nexport default tool({\n id: \"get-account\",\n description:\n \"Get current Dropbox account information including user details and storage usage.\",\n inputSchema: defineSchema((v) => v.object({\n includeSpaceUsage: v\n .boolean()\n .default(true)\n .describe(\"Whether to include storage usage information\"),\n }))(),\n async execute({ includeSpaceUsage }): Promise<Record<string, unknown>> {\n const account = await getCurrentAccount();\n\n const result: Record<string, unknown> = {\n accountId: account.account_id,\n name: {\n displayName: account.name.display_name,\n givenName: account.name.given_name,\n surname: account.name.surname,\n familiarName: account.name.familiar_name,\n },\n email: account.email,\n emailVerified: account.email_verified,\n accountType: account.account_type[\".tag\"],\n country: account.country,\n locale: account.locale,\n disabled: account.disabled,\n };\n\n if (!includeSpaceUsage) return result;\n\n try {\n const spaceUsage = await getSpaceUsage();\n const used = spaceUsage.used;\n const allocated = spaceUsage.allocation.allocated ?? 0;\n const hasAllocated = allocated > 0;\n\n result.storage = {\n used,\n usedFormatted: formatFileSize(used),\n allocated,\n allocatedFormatted: hasAllocated ? formatFileSize(allocated) : \"N/A\",\n allocationType: spaceUsage.allocation[\".tag\"],\n percentUsed: hasAllocated ? Math.round((used / allocated) * 100) : 0,\n available: hasAllocated ? allocated - used : 0,\n availableFormatted: hasAllocated\n ? formatFileSize(allocated - used)\n : \"N/A\",\n };\n } catch (error) {\n result.storageError =\n error instanceof Error ? error.message : \"Failed to get storage usage\";\n }\n\n return result;\n },\n});\n",
|
|
256
|
-
"tools/get-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { downloadFile, formatFileSize, getMetadata, isFile } from \"../../lib/dropbox-client.ts\";\n\nexport default tool({\n id: \"get-file\",\n description:\n \"Get file metadata and optionally download file content from Dropbox. Use this to read file information or retrieve file contents.\",\n inputSchema: defineSchema((v) => v.object({\n path: v.string().describe('Path to the file in Dropbox (e.g., \"/Documents/file.txt\")'),\n includeContent: v\n .boolean()\n .default(false)\n .describe(\"Whether to download and return the file content (only works for text files and small files)\"),\n }))(),\n async execute({ path, includeContent }): Promise<Record<string, unknown>> {\n const metadata = await getMetadata(path);\n\n if (!isFile(metadata)) {\n throw new Error(`Path \"${path}\" is not a file, it's a ${metadata[\".tag\"]}`);\n }\n\n const result: Record<string, unknown> = {\n name: metadata.name,\n path: metadata.path_display ?? metadata.path_lower ?? \"\",\n id: metadata.id,\n size: metadata.size,\n sizeFormatted: formatFileSize(metadata.size),\n modified: metadata.server_modified,\n clientModified: metadata.client_modified,\n isDownloadable: metadata.is_downloadable,\n rev: metadata.rev,\n };\n\n if (!includeContent) {\n return result;\n }\n\n if (!metadata.is_downloadable) {\n throw new Error(`File \"${path}\" is not downloadable`);\n }\n\n const maxSize = 1024 * 1024;\n if (metadata.size > maxSize) {\n throw new Error(\n `File is too large to download content (${formatFileSize(\n metadata.size,\n )}). Maximum size is 1MB. Use includeContent: false to get metadata only.`,\n );\n }\n\n try {\n const { content } = await downloadFile(path);\n result.content = content;\n result.contentLength = content.length;\n } catch (error) {\n result.contentError = error instanceof Error ? error.message : \"Failed to download content\";\n }\n\n return result;\n },\n});\n",
|
|
257
|
-
"tools/list-files.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { formatFileSize, isFile, listFolder } from \"../../lib/dropbox-client.ts\";\n\nexport default tool({\n id: \"list-files\",\n description:\n \"List files and folders in a Dropbox folder. Returns file/folder names, types, sizes, and modification dates.\",\n inputSchema: defineSchema((v) => v.object({\n path: v\n .string()\n .default(\"\")\n .describe(\n 'Path to the folder to list (empty string for root, or \"/FolderName\" for specific folder)',\n ),\n recursive: v.boolean().default(false).describe(\"Whether to list files recursively in subfolders\"),\n limit: v.number().min(1).max(500).default(100).describe(\"Maximum number of items to return\"),\n }))(),\n async execute({ path, recursive, limit }) {\n const result = await listFolder(path, { recursive, limit });\n\n const items = result.entries.map((entry) => {\n const baseInfo = {\n name: entry.name,\n path: entry.path_display ?? entry.path_lower ?? \"\",\n id: entry.id,\n type: entry[\".tag\"],\n };\n\n if (!isFile(entry)) {\n return baseInfo;\n }\n\n return {\n ...baseInfo,\n size: entry.size,\n sizeFormatted: formatFileSize(entry.size),\n modified: entry.server_modified,\n clientModified: entry.client_modified,\n isDownloadable: entry.is_downloadable,\n rev: entry.rev,\n };\n });\n\n return {\n items,\n count: items.length,\n hasMore: result.has_more,\n cursor: result.cursor,\n };\n },\n});\n",
|
|
258
|
-
"tools/search-files.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { formatFileSize, isFile, searchFiles } from \"../../lib/dropbox-client.ts\";\n\nexport default tool({\n id: \"search-files\",\n description:\n \"Search for files and folders in Dropbox by name or content. Returns matching items with their paths and metadata.\",\n inputSchema: defineSchema((v) => v.object({\n query: v.string().describe(\"Search query to find files or folders\"),\n path: v.string().optional().describe(\"Optional path to limit search to a specific folder\"),\n maxResults: v.number().min(1).max(100).default(20).describe(\"Maximum number of results to return\"),\n fileCategories: v\n .array(\n v.enum([\n \"image\",\n \"document\",\n \"pdf\",\n \"spreadsheet\",\n \"presentation\",\n \"audio\",\n \"video\",\n \"folder\",\n \"paper\",\n \"others\",\n ]),\n )\n .optional()\n .describe(\"Filter by file categories\"),\n }))(),\n async execute({ query, path, maxResults, fileCategories }) {\n const result = await searchFiles(query, { path, maxResults, fileCategories });\n\n const matches = result.matches.map((match) => {\n const metadata = match.metadata.metadata;\n const baseInfo = {\n name: metadata.name,\n path: metadata.path_display ?? metadata.path_lower ?? \"\",\n id: metadata.id,\n type: metadata[\".tag\"],\n matchType: match.match_type[\".tag\"],\n };\n\n if (!isFile(metadata)) {\n return baseInfo;\n }\n\n return {\n ...baseInfo,\n size: metadata.size,\n sizeFormatted: formatFileSize(metadata.size),\n modified: metadata.server_modified,\n clientModified: metadata.client_modified,\n isDownloadable: metadata.is_downloadable,\n };\n });\n\n return {\n matches,\n count: matches.length,\n hasMore: result.has_more,\n query,\n };\n },\n});\n",
|
|
259
|
-
"tools/upload-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { formatFileSize, uploadFile } from \"../../lib/dropbox-client.ts\";\n\nexport default tool({\n id: \"upload-file\",\n description:\n \"Upload or update a file in Dropbox. Can create new files or overwrite existing ones.\",\n inputSchema: defineSchema((v) => v.object({\n path: v\n .string()\n .describe(\n 'Full path where the file should be saved in Dropbox (e.g., \"/Documents/notes.txt\")',\n ),\n content: v.string().describe(\"The content to write to the file\"),\n mode: v\n .enum([\"add\", \"overwrite\", \"update\"])\n .default(\"add\")\n .describe(\n 'Upload mode: \"add\" (fail if exists), \"overwrite\" (replace if exists), \"update\" (update specific revision)',\n ),\n autorename: v\n .boolean()\n .default(false)\n .describe(\"If true and file exists, automatically rename to avoid conflicts\"),\n }))(),\n async execute({ path, content, mode, autorename }) {\n if (!path.startsWith(\"/\")) {\n throw new Error('Path must start with \"/\" (e.g., \"/Documents/file.txt\")');\n }\n\n const result = await uploadFile(path, content, { mode, autorename, mute: false });\n const displayPath = result.path_display ?? result.path_lower ?? \"\";\n\n let message = `File updated successfully at ${result.path_display}`;\n if (mode === \"add\") {\n message = `File created successfully at ${result.path_display}`;\n }\n\n return {\n success: true,\n name: result.name,\n path: displayPath,\n id: result.id,\n size: result.size,\n sizeFormatted: formatFileSize(result.size),\n modified: result.server_modified,\n rev: result.rev,\n message,\n };\n },\n});\n"
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
249
|
"integration:figma": {
|
|
263
250
|
"files": {
|
|
264
251
|
".env.example": "# Figma OAuth Integration\n# Get these credentials from https://www.figma.com/developers/apps\n\nFIGMA_CLIENT_ID=your_figma_client_id\nFIGMA_CLIENT_SECRET=your_figma_client_secret\n",
|
|
@@ -277,16 +264,20 @@ export default {
|
|
|
277
264
|
"files": {
|
|
278
265
|
"app/api/auth/github/callback/route.ts": "import { createOAuthCallbackHandler, githubConfig } from \"veryfront/oauth\";\nimport { tokenStore } from \"../../../../../lib/token-store.ts\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\n\nconst hybridTokenStore = {\n async getTokens(serviceId: string, userId: string) {\n return tokenStore.getToken(userId, serviceId);\n },\n async setTokens(\n serviceId: string,\n userId: string,\n tokens: { accessToken: string; refreshToken?: string; expiresAt?: number },\n ) {\n await tokenStore.setToken(userId, serviceId, tokens);\n },\n async clearTokens(serviceId: string, userId: string) {\n await tokenStore.revokeToken(userId, serviceId);\n },\n setState(\n state: string,\n meta: {\n userId: string;\n serviceId: string;\n codeVerifier?: string;\n redirectUri?: string;\n scopes?: string[];\n createdAt: number;\n },\n ) {\n return oauthMemoryTokenStore.setState(state, meta);\n },\n consumeState(state: string) {\n return oauthMemoryTokenStore.consumeState(state);\n },\n};\n\nexport const GET = createOAuthCallbackHandler(githubConfig, { tokenStore: hybridTokenStore });\n",
|
|
279
266
|
"app/api/auth/github/route.ts": "import { createOAuthInitHandler, githubConfig } from \"veryfront/oauth\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\nimport { requireUserIdFromRequest } from \"../../../../../lib/user-id.ts\";\n\nfunction getUserId(request: Request): string {\n return requireUserIdFromRequest(request);\n}\n\nexport const GET = createOAuthInitHandler(githubConfig, {\n tokenStore: oauthMemoryTokenStore,\n getUserId,\n});",
|
|
280
|
-
"lib/github-client.ts": "/**\n * GitHub API Client\n *\n * Provides a type-safe interface to GitHub API operations.\n */\n\nimport { getValidToken } from \"./oauth.ts\";\n\nfunction getEnv(key: string): string | undefined {\n // @ts-ignore - Deno global\n if (typeof Deno !== \"undefined\") return Deno.env.get(key);\n\n // @ts-ignore - process global\n if (typeof process !== \"undefined\" && process.env) return process.env[key];\n\n return undefined;\n}\n\nconst GITHUB_API_BASE = \"https://api.github.com\";\n\nexport interface GitHubRepo {\n id: number;\n name: string;\n full_name: string;\n description: string | null;\n private: boolean;\n html_url: string;\n default_branch: string;\n language: string | null;\n stargazers_count: number;\n forks_count: number;\n open_issues_count: number;\n updated_at: string;\n}\n\nexport interface GitHubPullRequest {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string; avatar_url: string };\n created_at: string;\n updated_at: string;\n head: { ref: string; sha: string };\n base: { ref: string };\n mergeable: boolean | null;\n additions: number;\n deletions: number;\n changed_files: number;\n draft: boolean;\n labels: Array<{ name: string; color: string }>;\n}\n\nexport interface GitHubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string; color: string }>;\n assignees: Array<{ login: string }>;\n}\n\nexport interface GitHubCommit {\n sha: string;\n commit: {\n message: string;\n author: { name: string; date: string };\n };\n html_url: string;\n author: { login: string; avatar_url: string } | null;\n}\n\n/**\n * GitHub OAuth provider configuration\n */\nexport const githubOAuthProvider = {\n name: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n clientId: getEnv(\"GITHUB_CLIENT_ID\") ?? \"\",\n clientSecret: getEnv(\"GITHUB_CLIENT_SECRET\") ?? \"\",\n scopes: [\"repo\", \"read:user\", \"read:org\"],\n callbackPath: \"/api/auth/github/callback\",\n};\n\nexport function createGitHubClient(userId: string): {\n listRepos(options?: {\n sort?: \"created\" | \"updated\" | \"pushed\" | \"full_name\";\n perPage?: number;\n type?: \"all\" | \"owner\" | \"public\" | \"private\" | \"member\";\n }): Promise<GitHubRepo[]>;\n getRepo(owner: string, repo: string): Promise<GitHubRepo>;\n listPullRequests(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubPullRequest[]>;\n getPullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<GitHubPullRequest>;\n getPullRequestDiff(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<string>;\n createIssue(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue>;\n updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n addIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<\n {\n id: number;\n html_url: string;\n body: string;\n user: { login: string };\n created_at: string;\n }\n >;\n listIssues(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubIssue[]>;\n listCommits(\n owner: string,\n repo: string,\n options?: { sha?: string; perPage?: number },\n ): Promise<GitHubCommit[]>;\n getUser(): Promise<{ login: string; name: string; email: string }>;\n} {\n async function getAccessToken(): Promise<string> {\n const token = await getValidToken(githubOAuthProvider, userId, \"github\");\n if (!token) {\n throw new Error(\n \"GitHub not connected. Please connect your GitHub account first.\",\n );\n }\n return token;\n }\n\n async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n ...options,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`GitHub API error: ${response.status} - ${error}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n async function apiTextRequest(\n endpoint: string,\n accept: string,\n ): Promise<string> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: accept,\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n },\n });\n\n if (!response.ok) throw new Error(`GitHub API error: ${response.status}`);\n\n return response.text();\n }\n\n function toQueryString(params: URLSearchParams): string {\n const query = params.toString();\n return query ? `?${query}` : \"\";\n }\n\n return {\n listRepos(options = {}): Promise<GitHubRepo[]> {\n const params = new URLSearchParams();\n if (options.sort) params.set(\"sort\", options.sort);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n if (options.type) params.set(\"type\", options.type);\n\n return apiRequest<GitHubRepo[]>(`/user/repos${toQueryString(params)}`);\n },\n\n getRepo(owner, repo): Promise<GitHubRepo> {\n return apiRequest<GitHubRepo>(`/repos/${owner}/${repo}`);\n },\n\n listPullRequests(owner, repo, options = {}): Promise<GitHubPullRequest[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubPullRequest[]>(\n `/repos/${owner}/${repo}/pulls${toQueryString(params)}`,\n );\n },\n\n getPullRequest(owner, repo, pullNumber): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n );\n },\n\n getPullRequestDiff(owner, repo, pullNumber): Promise<string> {\n return apiTextRequest(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n \"application/vnd.github.diff\",\n );\n },\n\n createIssue(owner, repo, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(`/repos/${owner}/${repo}/issues`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n getIssue(owner, repo, issueNumber): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n );\n },\n\n updateIssue(owner, repo, issueNumber, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(options),\n },\n );\n },\n\n addIssueComment(owner, repo, issueNumber, body) {\n return apiRequest(\n `/repos/${owner}/${repo}/issues/${issueNumber}/comments`,\n {\n method: \"POST\",\n body: JSON.stringify({ body }),\n },\n );\n },\n\n listIssues(owner, repo, options = {}): Promise<GitHubIssue[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubIssue[]>(\n `/repos/${owner}/${repo}/issues${toQueryString(params)}`,\n );\n },\n\n listCommits(owner, repo, options = {}): Promise<GitHubCommit[]> {\n const params = new URLSearchParams();\n if (options.sha) params.set(\"sha\", options.sha);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubCommit[]>(\n `/repos/${owner}/${repo}/commits${toQueryString(params)}`,\n );\n },\n\n getUser(): Promise<{ login: string; name: string; email: string }> {\n return apiRequest(\"/user\");\n },\n };\n}\n\nexport type GitHubClient = ReturnType<typeof createGitHubClient>;\n",
|
|
267
|
+
"lib/github-client.ts": "/**\n * GitHub API Client\n *\n * Provides a type-safe interface to GitHub API operations.\n */\n\nimport { getValidToken } from \"./oauth.ts\";\n\nfunction getEnv(key: string): string | undefined {\n // @ts-ignore - Deno global\n if (typeof Deno !== \"undefined\") return Deno.env.get(key);\n\n // @ts-ignore - process global\n if (typeof process !== \"undefined\" && process.env) return process.env[key];\n\n return undefined;\n}\n\nconst GITHUB_API_BASE = \"https://api.github.com\";\n\nexport interface GitHubRepo {\n id: number;\n name: string;\n full_name: string;\n description: string | null;\n private: boolean;\n html_url: string;\n default_branch: string;\n language: string | null;\n stargazers_count: number;\n forks_count: number;\n open_issues_count: number;\n updated_at: string;\n}\n\nexport interface GitHubPullRequest {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string; avatar_url: string };\n created_at: string;\n updated_at: string;\n head: { ref: string; sha: string };\n base: { ref: string };\n mergeable: boolean | null;\n additions: number;\n deletions: number;\n changed_files: number;\n draft: boolean;\n labels: Array<{ name: string; color: string }>;\n}\n\nexport interface GitHubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string; color: string }>;\n assignees: Array<{ login: string }>;\n}\n\nexport interface GitHubCommit {\n sha: string;\n commit: {\n message: string;\n author: { name: string; date: string };\n };\n html_url: string;\n author: { login: string; avatar_url: string } | null;\n}\n\nexport interface GitHubMergeResult {\n sha: string;\n merged: boolean;\n message: string;\n}\n\n/**\n * GitHub OAuth provider configuration\n */\nexport const githubOAuthProvider = {\n name: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n clientId: getEnv(\"GITHUB_CLIENT_ID\") ?? \"\",\n clientSecret: getEnv(\"GITHUB_CLIENT_SECRET\") ?? \"\",\n scopes: [\"repo\", \"read:user\", \"read:org\"],\n callbackPath: \"/api/auth/github/callback\",\n};\n\nexport function createGitHubClient(userId: string): {\n listRepos(options?: {\n sort?: \"created\" | \"updated\" | \"pushed\" | \"full_name\";\n perPage?: number;\n type?: \"all\" | \"owner\" | \"public\" | \"private\" | \"member\";\n }): Promise<GitHubRepo[]>;\n getRepo(owner: string, repo: string): Promise<GitHubRepo>;\n listPullRequests(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubPullRequest[]>;\n getPullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<GitHubPullRequest>;\n getPullRequestDiff(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<string>;\n createIssue(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue>;\n updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n addIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<\n {\n id: number;\n html_url: string;\n body: string;\n user: { login: string };\n created_at: string;\n }\n >;\n listIssues(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubIssue[]>;\n listCommits(\n owner: string,\n repo: string,\n options?: { sha?: string; path?: string; perPage?: number },\n ): Promise<GitHubCommit[]>;\n createPullRequest(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n head: string;\n base: string;\n draft?: boolean;\n },\n ): Promise<GitHubPullRequest>;\n mergePullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n options?: {\n commit_title?: string;\n commit_message?: string;\n merge_method?: \"merge\" | \"squash\" | \"rebase\";\n },\n ): Promise<GitHubMergeResult>;\n getUser(): Promise<{ login: string; name: string; email: string }>;\n} {\n async function getAccessToken(): Promise<string> {\n const token = await getValidToken(githubOAuthProvider, userId, \"github\");\n if (!token) {\n throw new Error(\n \"GitHub not connected. Please connect your GitHub account first.\",\n );\n }\n return token;\n }\n\n async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n ...options,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`GitHub API error: ${response.status} - ${error}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n async function apiTextRequest(\n endpoint: string,\n accept: string,\n ): Promise<string> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: accept,\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n },\n });\n\n if (!response.ok) throw new Error(`GitHub API error: ${response.status}`);\n\n return response.text();\n }\n\n function toQueryString(params: URLSearchParams): string {\n const query = params.toString();\n return query ? `?${query}` : \"\";\n }\n\n return {\n listRepos(options = {}): Promise<GitHubRepo[]> {\n const params = new URLSearchParams();\n if (options.sort) params.set(\"sort\", options.sort);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n if (options.type) params.set(\"type\", options.type);\n\n return apiRequest<GitHubRepo[]>(`/user/repos${toQueryString(params)}`);\n },\n\n getRepo(owner, repo): Promise<GitHubRepo> {\n return apiRequest<GitHubRepo>(`/repos/${owner}/${repo}`);\n },\n\n listPullRequests(owner, repo, options = {}): Promise<GitHubPullRequest[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubPullRequest[]>(\n `/repos/${owner}/${repo}/pulls${toQueryString(params)}`,\n );\n },\n\n getPullRequest(owner, repo, pullNumber): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n );\n },\n\n getPullRequestDiff(owner, repo, pullNumber): Promise<string> {\n return apiTextRequest(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n \"application/vnd.github.diff\",\n );\n },\n\n createIssue(owner, repo, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(`/repos/${owner}/${repo}/issues`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n getIssue(owner, repo, issueNumber): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n );\n },\n\n updateIssue(owner, repo, issueNumber, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(options),\n },\n );\n },\n\n addIssueComment(owner, repo, issueNumber, body) {\n return apiRequest(\n `/repos/${owner}/${repo}/issues/${issueNumber}/comments`,\n {\n method: \"POST\",\n body: JSON.stringify({ body }),\n },\n );\n },\n\n listIssues(owner, repo, options = {}): Promise<GitHubIssue[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubIssue[]>(\n `/repos/${owner}/${repo}/issues${toQueryString(params)}`,\n );\n },\n\n listCommits(owner, repo, options = {}): Promise<GitHubCommit[]> {\n const params = new URLSearchParams();\n if (options.sha) params.set(\"sha\", options.sha);\n if (options.path) params.set(\"path\", options.path);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubCommit[]>(\n `/repos/${owner}/${repo}/commits${toQueryString(params)}`,\n );\n },\n\n createPullRequest(owner, repo, options): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(`/repos/${owner}/${repo}/pulls`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n mergePullRequest(owner, repo, pullNumber, options = {}): Promise<GitHubMergeResult> {\n return apiRequest<GitHubMergeResult>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}/merge`,\n {\n method: \"PUT\",\n body: JSON.stringify(options),\n },\n );\n },\n\n getUser(): Promise<{ login: string; name: string; email: string }> {\n return apiRequest(\"/user\");\n },\n };\n}\n\nexport type GitHubClient = ReturnType<typeof createGitHubClient>;\n",
|
|
281
268
|
"lib/user-id.ts": "import type { ToolExecutionContext } from \"veryfront/tool\";\n\nexport function requireUserIdFromContext(\n context?: ToolExecutionContext,\n): string {\n const userId = context?.userId;\n if (!userId) {\n throw new Error(\"GitHub tool execution requires an authenticated user.\");\n }\n return userId;\n}\n",
|
|
282
269
|
"tools/add-issue-comment.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"add-issue-comment\",\n description: \"Add a comment to a GitHub issue or pull request\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v.string().describe(\"Repository in format 'owner/repo'\"),\n issueNumber: v.number().int().positive().describe(\n \"Issue or pull request number\",\n ),\n body: v.string().min(1).describe(\"Comment body (supports Markdown)\"),\n })\n )(),\n execute: async ({ repo, issueNumber, body }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const comment = await github.addIssueComment(\n owner,\n repoName,\n issueNumber,\n body,\n );\n return {\n success: true,\n comment: {\n id: comment.id,\n url: comment.html_url,\n body: comment.body,\n author: comment.user.login,\n createdAt: comment.created_at,\n },\n message: `Comment added to issue #${issueNumber} in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
283
270
|
"tools/create-issue.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"create-issue\",\n description: \"Create a new issue in a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n title: v.string().min(1).describe(\"Issue title\"),\n body: v\n .string()\n .optional()\n .describe(\"Issue body/description (supports Markdown)\"),\n labels: v.array(v.string()).optional().describe(\n \"Labels to add to the issue\",\n ),\n assignees: v\n .array(v.string())\n .optional()\n .describe(\"GitHub usernames to assign to the issue\"),\n })\n )(),\n execute: async ({ repo, title, body, labels, assignees }, context) => {\n const userId = requireUserIdFromContext(context);\n\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issue = await github.createIssue(owner, repoName, {\n title,\n body,\n labels,\n assignees,\n });\n\n return {\n success: true,\n issue: {\n number: issue.number,\n title: issue.title,\n url: issue.html_url,\n state: issue.state,\n labels: issue.labels.map((l: { name: string }) => l.name),\n assignees: issue.assignees.map((a: { login: string }) => a.login),\n },\n message: `Issue #${issue.number} created successfully in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
271
|
+
"tools/create-pr.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"create-pr\",\n description: \"Create a new pull request in a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n title: v.string().min(1).describe(\"Pull request title\"),\n head: v\n .string()\n .describe(\n \"Branch to merge from (e.g., 'feature-branch' or 'owner:feature-branch')\",\n ),\n base: v.string().describe(\"Branch to merge into (e.g., 'main')\"),\n body: v\n .string()\n .optional()\n .describe(\"Pull request description (supports Markdown)\"),\n draft: v\n .boolean()\n .default(false)\n .optional()\n .describe(\"Create as a draft pull request\"),\n })\n )(),\n execute: async ({ repo, title, head, base, body, draft }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const pr = await github.createPullRequest(owner, repoName, {\n title,\n head,\n base,\n body,\n draft,\n });\n\n return {\n success: true,\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n state: pr.state,\n isDraft: pr.draft,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n message: `Pull request #${pr.number} created successfully in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
284
272
|
"tools/get-issue.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-issue\",\n description: \"Get details of a GitHub issue\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v.string().describe(\"Repository in format 'owner/repo'\"),\n issueNumber: v.number().int().positive().describe(\"Issue number\"),\n })\n )(),\n execute: async ({ repo, issueNumber }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issue = await github.getIssue(owner, repoName, issueNumber);\n return {\n issue: {\n number: issue.number,\n title: issue.title,\n body: issue.body,\n state: issue.state,\n url: issue.html_url,\n author: issue.user.login,\n labels: issue.labels.map((label: { name: string }) => label.name),\n assignees: issue.assignees.map((assignee: { login: string }) =>\n assignee.login\n ),\n updatedAt: issue.updated_at,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
285
273
|
"tools/get-pr-diff.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-pr-diff\",\n description: \"Get the diff for a pull request to review code changes\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n prNumber: v.number().int().positive().describe(\"Pull request number\"),\n })\n )(),\n execute: async ({ repo, prNumber }, context) => {\n const userId = requireUserIdFromContext(context);\n\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n\n const pr = await github.getPullRequest(owner, repoName, prNumber);\n const diff = await github.getPullRequestDiff(owner, repoName, prNumber);\n\n const maxDiffLength = 50000;\n let truncatedDiff = diff;\n\n if (diff.length > maxDiffLength) {\n truncatedDiff = `${\n diff.substring(0, maxDiffLength)\n }\\n\\n... (diff truncated, ${\n diff.length - maxDiffLength\n } characters remaining)`;\n }\n\n return {\n pullRequest: {\n number: pr.number,\n title: pr.title,\n author: pr.user.login,\n url: pr.html_url,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n isDraft: pr.draft,\n state: pr.state,\n },\n diff: truncatedDiff,\n stats: {\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n },\n message:\n `Retrieved diff for PR #${prNumber} (${pr.additions} additions, ${pr.deletions} deletions across ${pr.changed_files} files).`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
274
|
+
"tools/get-pr.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-pr\",\n description: \"Get details of a specific GitHub pull request\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n pull_number: v.number().int().positive().describe(\"Pull request number\"),\n })\n )(),\n execute: async ({ repo, pull_number }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const pr = await github.getPullRequest(owner, repoName, pull_number);\n\n return {\n number: pr.number,\n title: pr.title,\n body: pr.body,\n state: pr.state,\n isDraft: pr.draft,\n url: pr.html_url,\n author: pr.user.login,\n createdAt: pr.created_at,\n updatedAt: pr.updated_at,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n mergeable: pr.mergeable,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n labels: pr.labels.map(({ name }) => name),\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
286
275
|
"tools/get-repo.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-repo\",\n description: \"Get details of a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n })\n )(),\n execute: async ({ repo }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const result = await github.getRepo(owner, repoName);\n\n return {\n repository: {\n name: result.name,\n fullName: result.full_name,\n description: result.description ?? null,\n isPrivate: result.private,\n url: result.html_url,\n defaultBranch: result.default_branch,\n language: result.language,\n stars: result.stargazers_count,\n forks: result.forks_count,\n openIssues: result.open_issues_count,\n updatedAt: result.updated_at,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
276
|
+
"tools/list-commits.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient, type GitHubCommit } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"list-commits\",\n description: \"List commits for a repository, branch, or file path\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n sha: v\n .string()\n .optional()\n .describe(\"Branch name or commit SHA to list commits from\"),\n path: v\n .string()\n .optional()\n .describe(\"Only include commits that touch this file path\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(30)\n .describe(\"Maximum number of commits to return\"),\n })\n )(),\n execute: async ({ repo, sha, path, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const commits = await github.listCommits(owner, repoName, {\n sha,\n path,\n perPage: limit,\n });\n\n return {\n commits: commits.map((c: GitHubCommit) => ({\n sha: c.sha.slice(0, 7),\n message: c.commit.message.split(\"\\n\")[0],\n author: c.author?.login ?? c.commit.author.name,\n date: c.commit.author.date,\n url: c.html_url,\n })),\n count: commits.length,\n repository: repo,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
287
277
|
"tools/list-issues.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\ntype GitHubIssueListItem = {\n number: number;\n title: string;\n body: string | null;\n state: string;\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string }>;\n assignees: Array<{ login: string }>;\n};\n\nexport default tool({\n id: \"list-issues\",\n description: \"List issues for a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n state: v\n .enum([\"open\", \"closed\", \"all\"])\n .default(\"open\")\n .describe(\"State of issues to list\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(20)\n .describe(\"Maximum number of issues to return\"),\n })\n )(),\n execute: async ({ repo, state, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issues = await github.listIssues(owner, repoName, {\n state,\n perPage: limit,\n });\n\n return {\n issues: issues.map((issue: GitHubIssueListItem) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body,\n state: issue.state,\n url: issue.html_url,\n author: issue.user.login,\n labels: issue.labels.map((label) => label.name),\n assignees: issue.assignees.map((assignee) => assignee.login),\n createdAt: issue.created_at,\n updatedAt: issue.updated_at,\n })),\n count: issues.length,\n repository: repo,\n message: `Found ${issues.length} ${state} issue(s) in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
288
278
|
"tools/list-prs.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\ntype PullRequest = {\n number: number;\n title: string;\n state: string;\n draft: boolean;\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n head: { ref: string };\n base: { ref: string };\n additions: number;\n deletions: number;\n changed_files: number;\n labels: Array<{ name: string }>;\n};\n\nexport default tool({\n id: \"list-prs\",\n description: \"List pull requests for a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n state: v\n .enum([\"open\", \"closed\", \"all\"])\n .default(\"open\")\n .describe(\"State of pull requests to list\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(10)\n .describe(\"Maximum number of pull requests to return\"),\n })\n )(),\n execute: async ({ repo, state, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const prs = await github.listPullRequests(owner, repoName, {\n state,\n perPage: limit,\n });\n\n return {\n pullRequests: prs.map((pr: PullRequest) => ({\n number: pr.number,\n title: pr.title,\n state: pr.state,\n isDraft: pr.draft,\n url: pr.html_url,\n author: pr.user.login,\n createdAt: pr.created_at,\n updatedAt: pr.updated_at,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n labels: pr.labels.map(({ name }) => name),\n })),\n count: prs.length,\n repository: repo,\n message: `Found ${prs.length} ${state} pull request(s) in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
289
279
|
"tools/list-repos.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\ntype GitHubRepo = {\n name: string;\n full_name: string;\n description: string | null;\n private: boolean;\n html_url: string;\n default_branch: string;\n language: string | null;\n stargazers_count: number;\n forks_count: number;\n open_issues_count: number;\n updated_at: string;\n};\n\nexport default tool({\n id: \"list-repos\",\n description: \"List GitHub repositories for the authenticated user\",\n inputSchema: defineSchema((v) =>\n v.object({\n type: v\n .enum([\"all\", \"owner\", \"public\", \"private\", \"member\"])\n .default(\"all\")\n .describe(\"Type of repositories to list\"),\n sort: v\n .enum([\"created\", \"updated\", \"pushed\", \"full_name\"])\n .default(\"updated\")\n .describe(\"How to sort the repositories\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(20)\n .describe(\"Maximum number of repositories to return\"),\n })\n )(),\n execute: async ({ type, sort, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n\n try {\n const github = createGitHubClient(userId);\n const repos = await github.listRepos({ type, sort, perPage: limit });\n\n return {\n repositories: repos.map((repo: GitHubRepo) => ({\n name: repo.name,\n fullName: repo.full_name,\n description: repo.description ?? null,\n isPrivate: repo.private,\n url: repo.html_url,\n defaultBranch: repo.default_branch,\n language: repo.language,\n stars: repo.stargazers_count,\n forks: repo.forks_count,\n openIssues: repo.open_issues_count,\n updatedAt: repo.updated_at,\n })),\n count: repos.length,\n message: `Found ${repos.length} repository(s).`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
280
|
+
"tools/merge-pr.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"merge-pr\",\n description: \"Merge an open GitHub pull request\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n pull_number: v\n .number()\n .int()\n .positive()\n .describe(\"Pull request number to merge\"),\n merge_method: v\n .enum([\"merge\", \"squash\", \"rebase\"])\n .default(\"merge\")\n .optional()\n .describe(\"Merge method: merge, squash, or rebase\"),\n commit_title: v\n .string()\n .optional()\n .describe(\"Title for the merge commit\"),\n commit_message: v\n .string()\n .optional()\n .describe(\"Extra detail for the merge commit message\"),\n })\n )(),\n execute: async (\n { repo, pull_number, merge_method, commit_title, commit_message },\n context,\n ) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const result = await github.mergePullRequest(owner, repoName, pull_number, {\n merge_method,\n commit_title,\n commit_message,\n });\n\n return {\n success: result.merged,\n sha: result.sha,\n message: result.message,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
290
281
|
"tools/update-issue.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"update-issue\",\n description: \"Update, close, or reopen a GitHub issue\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v.string().describe(\"Repository in format 'owner/repo'\"),\n issueNumber: v.number().int().positive().describe(\"Issue number\"),\n title: v.string().optional().describe(\"Updated issue title\"),\n body: v.string().optional().describe(\"Updated issue body\"),\n state: v.enum([\"open\", \"closed\"]).optional().describe(\"Issue state\"),\n labels: v.array(v.string()).optional().describe(\n \"Replacement label names\",\n ),\n assignees: v.array(v.string()).optional().describe(\n \"Replacement assignee usernames\",\n ),\n })\n )(),\n execute: async (\n { repo, issueNumber, title, body, state, labels, assignees },\n context,\n ) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issue = await github.updateIssue(owner, repoName, issueNumber, {\n title,\n body,\n state,\n labels,\n assignees,\n });\n return {\n success: true,\n issue: {\n number: issue.number,\n title: issue.title,\n state: issue.state,\n url: issue.html_url,\n labels: issue.labels.map((label: { name: string }) => label.name),\n assignees: issue.assignees.map((assignee: { login: string }) =>\n assignee.login\n ),\n },\n message: `Issue #${issue.number} updated successfully in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n"
|
|
291
282
|
}
|
|
292
283
|
},
|
package/esm/deno.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_data.d.ts","sourceRoot":"","sources":["../../../src/src/integrations/_data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,UAAU,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"_data.d.ts","sourceRoot":"","sources":["../../../src/src/integrations/_data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,UAAU,EAAE,iBAAiB,EAqCzC,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqCxC,CAAC"}
|
|
@@ -4,18 +4,17 @@ export const connectors = [
|
|
|
4
4
|
{ "name": "asana", "displayName": "Asana", "icon": "asana.svg", "description": "Manage tasks, projects, and teams in Asana", "auth": { "type": "oauth2", "provider": "asana", "authorizationUrl": "https://app.asana.com/-/oauth_authorize", "tokenUrl": "https://app.asana.com/-/oauth_token", "scopes": ["default"], "requiredApis": [{ "name": "Asana Developer Console", "enableUrl": "https://app.asana.com/0/developer-console" }] }, "envVars": [{ "name": "ASANA_CLIENT_ID", "description": "Asana OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://developers.asana.com/docs/oauth" }, { "name": "ASANA_CLIENT_SECRET", "description": "Asana OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://developers.asana.com/docs/oauth" }], "tools": [{ "id": "list_tasks", "name": "List Tasks", "description": "List tasks in a project or assigned to a user", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/tasks", "params": { "project": { "type": "string", "in": "query", "description": "Asana project GID to list tasks from" }, "assignee": { "type": "string", "in": "query", "description": "Assignee user GID, 'me', or omit when project is provided" }, "workspace": { "type": "string", "in": "query", "description": "Workspace GID for assignee-based task lists" }, "completed_since": { "type": "string", "in": "query", "description": "Only return tasks completed since this ISO timestamp", "default": "now" }, "limit": { "type": "number", "in": "query", "description": "Maximum tasks to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" } }, "response": { "transform": "data" } } }, { "id": "get_task", "name": "Get Task", "description": "Get details of a specific task", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/tasks/{taskGid}", "params": { "taskGid": { "type": "string", "in": "path", "description": "Asana task GID", "required": true }, "opt_fields": { "type": "string", "in": "query", "description": "Comma-separated task fields to return" } }, "response": { "transform": "data" } } }, { "id": "create_task", "name": "Create Task", "description": "Create a new task in a project", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://app.asana.com/api/1.0/tasks", "body": { "data": { "type": "object", "description": "Asana task payload with name, projects, workspace, assignee, notes, due_on, etc.", "required": true } }, "response": { "transform": "data" } } }, { "id": "update_task", "name": "Update Task", "description": "Update an existing task", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://app.asana.com/api/1.0/tasks/{taskGid}", "params": { "taskGid": { "type": "string", "in": "path", "description": "Asana task GID", "required": true } }, "body": { "data": { "type": "object", "description": "Asana task fields to update", "required": true } }, "response": { "transform": "data" } } }, { "id": "list_projects", "name": "List Projects", "description": "List all projects in the workspace", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/projects", "params": { "workspace": { "type": "string", "in": "query", "description": "Workspace GID to list projects from" }, "team": { "type": "string", "in": "query", "description": "Team GID to list projects from" }, "archived": { "type": "boolean", "in": "query", "description": "Whether to include archived projects", "default": false }, "limit": { "type": "number", "in": "query", "description": "Maximum projects to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" } }, "response": { "transform": "data" } } }, { "id": "list_workspaces", "name": "List Workspaces", "description": "List Asana workspaces accessible to the authenticated user", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/workspaces", "params": { "limit": { "type": "number", "in": "query", "description": "Maximum workspaces to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" } }, "response": { "transform": "data" } } }, { "id": "list_users", "name": "List Users", "description": "List users in an Asana workspace", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/users", "params": { "workspace": { "type": "string", "in": "query", "description": "Workspace GID", "required": true }, "team": { "type": "string", "in": "query", "description": "Optional team GID" }, "limit": { "type": "number", "in": "query", "description": "Maximum users to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" }, "opt_fields": { "type": "string", "in": "query", "description": "Comma-separated user fields", "default": "gid,name,email" } }, "response": { "transform": "data" } } }, { "id": "list_teams", "name": "List Teams", "description": "List teams in an Asana workspace", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/workspaces/{workspaceGid}/teams", "params": { "workspaceGid": { "type": "string", "in": "path", "description": "Workspace GID", "required": true }, "limit": { "type": "number", "in": "query", "description": "Maximum teams to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" }, "opt_fields": { "type": "string", "in": "query", "description": "Comma-separated team fields", "default": "gid,name,description" } }, "response": { "transform": "data" } } }, { "id": "add_task_comment", "name": "Add Task Comment", "description": "Add a story/comment to an Asana task", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://app.asana.com/api/1.0/tasks/{taskGid}/stories", "params": { "taskGid": { "type": "string", "in": "path", "description": "Asana task GID", "required": true } }, "body": { "data": { "type": "object", "description": "Story payload, e.g. { text: 'Comment text' }", "required": true } }, "response": { "transform": "data" } } }, { "id": "list_task_comments", "name": "List Task Comments", "description": "List comment stories for an Asana task", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://app.asana.com/api/1.0/tasks/{taskGid}/stories", "params": { "taskGid": { "type": "string", "in": "path", "description": "Asana task GID", "required": true }, "limit": { "type": "number", "in": "query", "description": "Maximum stories to return", "default": 50 }, "offset": { "type": "string", "in": "query", "description": "Pagination offset from Asana" }, "opt_fields": { "type": "string", "in": "query", "description": "Comma-separated story fields", "default": "gid,type,text,created_at,created_by.name" } }, "response": { "transform": "data" } } }], "prompts": [{ "id": "my_tasks", "title": "Show my tasks", "prompt": "List all tasks assigned to me in Asana with their due dates and priorities.", "category": "productivity", "icon": "list" }, { "id": "create_task", "title": "Create a task", "prompt": "Create a new task with a title, description, due date, and assignee.", "category": "productivity", "icon": "plus" }], "suggestedWith": ["slack", "notion", "calendar"] },
|
|
5
5
|
{ "name": "aws", "displayName": "Amazon Web Services", "icon": "aws.svg", "description": "Integration with AWS services including S3, EC2, and Lambda", "auth": { "type": "api-key", "fields": [{ "name": "accessKeyId", "label": "AWS Access Key ID", "type": "string", "required": true, "envVar": "AWS_ACCESS_KEY_ID" }, { "name": "secretAccessKey", "label": "AWS Secret Access Key", "type": "password", "required": true, "envVar": "AWS_SECRET_ACCESS_KEY" }, { "name": "region", "label": "AWS Region", "type": "string", "required": true, "envVar": "AWS_REGION", "default": "us-east-1" }] }, "envVars": [{ "name": "AWS_ACCESS_KEY_ID", "description": "AWS Access Key ID", "required": true }, { "name": "AWS_SECRET_ACCESS_KEY", "description": "AWS Secret Access Key", "required": true, "sensitive": true }, { "name": "AWS_REGION", "description": "AWS Region (e.g. us-east-1)", "required": true, "default": "us-east-1" }], "tools": [{ "name": "list-s3-buckets", "description": "List all S3 buckets in your AWS account", "file": "tools/list-s3-buckets.ts" }, { "name": "list-s3-objects", "description": "List objects in a specific S3 bucket", "file": "tools/list-s3-objects.ts" }, { "name": "get-s3-object", "description": "Get the contents of an object from S3", "file": "tools/get-s3-object.ts" }, { "name": "list-ec2-instances", "description": "List EC2 instances in your AWS account", "file": "tools/list-ec2-instances.ts" }, { "name": "list-lambda-functions", "description": "List Lambda functions in your AWS account", "file": "tools/list-lambda-functions.ts" }], "dependencies": { "@aws-sdk/client-s3": "^3.600.0", "@aws-sdk/client-ec2": "^3.600.0", "@aws-sdk/client-lambda": "^3.600.0", "@aws-sdk/credential-providers": "^3.600.0" } },
|
|
6
6
|
{ "name": "bitbucket", "displayName": "Bitbucket", "icon": "bitbucket.svg", "description": "Manage repositories, pull requests, and issues on Bitbucket", "auth": { "type": "oauth2", "provider": "bitbucket", "authorizationUrl": "https://bitbucket.org/site/oauth2/authorize", "tokenUrl": "https://bitbucket.org/site/oauth2/access_token", "scopes": ["repository", "pullrequest", "issue", "account"] }, "envVars": [{ "name": "BITBUCKET_CLIENT_ID", "description": "Bitbucket OAuth Consumer Key", "required": true, "sensitive": false, "docsUrl": "https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/" }, { "name": "BITBUCKET_CLIENT_SECRET", "description": "Bitbucket OAuth Consumer Secret", "required": true, "sensitive": true, "docsUrl": "https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/" }], "tools": [{ "id": "list_repositories", "name": "List Repositories", "description": "Get list of user's repositories", "requiresWrite": false }, { "id": "list_pull_requests", "name": "List Pull Requests", "description": "Get pull requests for a repository", "requiresWrite": false }, { "id": "create_pull_request", "name": "Create Pull Request", "description": "Create a new pull request", "requiresWrite": true }, { "id": "list_issues", "name": "List Issues", "description": "Get issues for a repository", "requiresWrite": false }], "prompts": [{ "id": "review_prs", "title": "Review my pull requests", "prompt": "Show me my open pull requests on Bitbucket and help me review them. Summarize the changes and any comments.", "category": "development", "icon": "git-pull-request" }, { "id": "list_repos", "title": "List my repositories", "prompt": "Show me all my Bitbucket repositories with their details and recent activity.", "category": "development", "icon": "folder" }, { "id": "check_issues", "title": "Check repository issues", "prompt": "Show me the open issues in my repositories and help me prioritize them.", "category": "development", "icon": "bug" }], "suggestedWith": ["github", "gitlab", "jira"] },
|
|
7
|
-
{ "name": "calendar", "displayName": "Google Calendar", "icon": "calendar.svg", "description": "Manage events, find free time, and schedule meetings", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/calendar.events"], "requiredApis": [{ "name": "Google Calendar API", "enableUrl": "https://console.cloud.google.com/apis/library/calendar-json.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_events", "name": "List Events", "description": "Get upcoming calendar events", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID (use 'primary' for main calendar)", "required": true, "default": "primary" }, "timeMin": { "type": "string", "in": "query", "description": "Start time (RFC3339)" }, "timeMax": { "type": "string", "in": "query", "description": "End time (RFC3339)" }, "maxResults": { "type": "number", "in": "query", "description": "Maximum events", "default": 10 }, "orderBy": { "type": "string", "in": "query", "description": "Order by: startTime or updated", "default": "startTime" }, "singleEvents": { "type": "boolean", "in": "query", "description": "Expand recurring events", "default": true } }, "response": { "transform": "items" } } }, { "id": "create_event", "name": "Create Event", "description": "Schedule a new calendar event", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" } }, "body": { "summary": { "type": "string", "description": "Event title", "required": true }, "description": { "type": "string", "description": "Event description" }, "start": { "type": "object", "description": "Start time: {dateTime: 'RFC3339', timeZone: 'TZ'}", "required": true }, "end": { "type": "object", "description": "End time: {dateTime: 'RFC3339', timeZone: 'TZ'}", "required": true }, "attendees": { "type": "array", "description": "Array of {email: string} objects" }, "location": { "type": "string", "description": "Event location" } } } }, { "id": "get_event", "name": "Get Event", "description": "Get details of a specific calendar event", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID", "required": true } } } }, { "id": "update_event", "name": "Update Event", "description": "Update an existing calendar event", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID to update", "required": true }, "sendUpdates": { "type": "string", "in": "query", "description": "Whether to send update notifications: all, externalOnly, or none", "default": "none" } }, "body": { "summary": { "type": "string", "description": "Updated event title" }, "description": { "type": "string", "description": "Updated event description" }, "start": { "type": "object", "description": "Updated start time: {dateTime: 'RFC3339', timeZone: 'TZ'}" }, "end": { "type": "object", "description": "Updated end time: {dateTime: 'RFC3339', timeZone: 'TZ'}" }, "attendees": { "type": "array", "description": "Updated array of {email: string} attendees" }, "location": { "type": "string", "description": "Updated event location" } } } }, { "id": "delete_event", "name": "Delete Event", "description": "Delete a calendar event by ID", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID to delete", "required": true }, "sendUpdates": { "type": "string", "in": "query", "description": "Whether to send cancellation notifications: all, externalOnly, or none", "default": "none" } } } }, { "id": "find_free_time", "name": "Find Free Time", "description": "Find available time slots in calendar", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/calendar/v3/freeBusy", "body": { "timeMin": { "type": "string", "description": "Start of window (RFC3339)", "required": true }, "timeMax": { "type": "string", "description": "End of window (RFC3339)", "required": true }, "items": { "type": "array", "description": "Array of {id: calendarId} to check", "required": true } } } }], "prompts": [{ "id": "block_deep_work", "title": "Block time for deep work", "prompt": "Find a 2-hour block for focused work this week and add it to my calendar.", "category": "productivity", "icon": "clock" }, { "id": "schedule_meeting", "title": "Schedule a meeting", "prompt": "Help me schedule a meeting. Find available time slots and create the calendar event.", "category": "productivity", "icon": "users" }, { "id": "today_agenda", "title": "What's on my calendar today?", "prompt": "Show me my calendar for today and summarize my schedule.", "category": "productivity", "icon": "calendar" }], "suggestedWith": ["gmail", "slack"] },
|
|
7
|
+
{ "name": "calendar", "displayName": "Google Calendar", "icon": "calendar.svg", "description": "Manage events, find free time, and schedule meetings", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/calendar.events"], "requiredApis": [{ "name": "Google Calendar API", "enableUrl": "https://console.cloud.google.com/apis/library/calendar-json.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_calendars", "name": "List Calendars", "description": "List all calendars in the authenticated user's calendar list", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/users/me/calendarList", "params": { "maxResults": { "type": "number", "in": "query", "description": "Maximum calendars to return", "default": 100 } }, "response": { "transform": "items" } } }, { "id": "list_events", "name": "List Events", "description": "Get upcoming calendar events", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID (use 'primary' for main calendar)", "required": true, "default": "primary" }, "timeMin": { "type": "string", "in": "query", "description": "Start time (RFC3339)" }, "timeMax": { "type": "string", "in": "query", "description": "End time (RFC3339)" }, "maxResults": { "type": "number", "in": "query", "description": "Maximum events", "default": 10 }, "orderBy": { "type": "string", "in": "query", "description": "Order by: startTime or updated", "default": "startTime" }, "singleEvents": { "type": "boolean", "in": "query", "description": "Expand recurring events", "default": true } }, "response": { "transform": "items" } } }, { "id": "create_event", "name": "Create Event", "description": "Schedule a new calendar event", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" } }, "body": { "summary": { "type": "string", "description": "Event title", "required": true }, "description": { "type": "string", "description": "Event description" }, "start": { "type": "object", "description": "Start time: {dateTime: 'RFC3339', timeZone: 'TZ'}", "required": true }, "end": { "type": "object", "description": "End time: {dateTime: 'RFC3339', timeZone: 'TZ'}", "required": true }, "attendees": { "type": "array", "description": "Array of {email: string} objects" }, "location": { "type": "string", "description": "Event location" } } } }, { "id": "get_event", "name": "Get Event", "description": "Get details of a specific calendar event", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID", "required": true } } } }, { "id": "update_event", "name": "Update Event", "description": "Update an existing calendar event", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID to update", "required": true }, "sendUpdates": { "type": "string", "in": "query", "description": "Whether to send update notifications: all, externalOnly, or none", "default": "none" } }, "body": { "summary": { "type": "string", "description": "Updated event title" }, "description": { "type": "string", "description": "Updated event description" }, "start": { "type": "object", "description": "Updated start time: {dateTime: 'RFC3339', timeZone: 'TZ'}" }, "end": { "type": "object", "description": "Updated end time: {dateTime: 'RFC3339', timeZone: 'TZ'}" }, "attendees": { "type": "array", "description": "Updated array of {email: string} attendees" }, "location": { "type": "string", "description": "Updated event location" } } } }, { "id": "delete_event", "name": "Delete Event", "description": "Delete a calendar event by ID", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events/{eventId}", "params": { "calendarId": { "type": "string", "in": "path", "description": "Calendar ID", "required": true, "default": "primary" }, "eventId": { "type": "string", "in": "path", "description": "Event ID to delete", "required": true }, "sendUpdates": { "type": "string", "in": "query", "description": "Whether to send cancellation notifications: all, externalOnly, or none", "default": "none" } } } }, { "id": "find_free_time", "name": "Find Free Time", "description": "Find available time slots in calendar", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/calendar/v3/freeBusy", "body": { "timeMin": { "type": "string", "description": "Start of window (RFC3339)", "required": true }, "timeMax": { "type": "string", "description": "End of window (RFC3339)", "required": true }, "items": { "type": "array", "description": "Array of {id: calendarId} to check", "required": true } } } }], "prompts": [{ "id": "block_deep_work", "title": "Block time for deep work", "prompt": "Find a 2-hour block for focused work this week and add it to my calendar.", "category": "productivity", "icon": "clock" }, { "id": "schedule_meeting", "title": "Schedule a meeting", "prompt": "Help me schedule a meeting. Find available time slots and create the calendar event.", "category": "productivity", "icon": "users" }, { "id": "today_agenda", "title": "What's on my calendar today?", "prompt": "Show me my calendar for today and summarize my schedule.", "category": "productivity", "icon": "calendar" }], "suggestedWith": ["gmail", "slack"] },
|
|
8
8
|
{ "name": "confluence", "displayName": "Confluence", "icon": "confluence.svg", "description": "Search, read, and create documentation in Confluence", "auth": { "type": "oauth2", "provider": "atlassian", "authorizationUrl": "https://auth.atlassian.com/authorize", "tokenUrl": "https://auth.atlassian.com/oauth/token", "scopes": ["read:confluence-content.all", "write:confluence-content"], "tokenAuthMethod": "client_secret_post", "requiredApis": [{ "name": "Atlassian OAuth 2.0 App", "enableUrl": "https://developer.atlassian.com/console/myapps/" }], "additionalParams": { "audience": "api.atlassian.com", "prompt": "consent" }, "additionalAuthParams": { "audience": "api.atlassian.com", "prompt": "consent" } }, "envVars": [{ "name": "ATLASSIAN_CLIENT_ID", "description": "Atlassian OAuth Client ID (from your OAuth 2.0 app)", "required": true, "sensitive": false, "docsUrl": "https://developer.atlassian.com/console/myapps/" }, { "name": "ATLASSIAN_CLIENT_SECRET", "description": "Atlassian OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://developer.atlassian.com/console/myapps/" }], "tools": [{ "id": "list_sites", "name": "List Atlassian Sites", "description": "List Atlassian cloud sites/resources the OAuth token can access; use the returned id as cloudId for Jira and Confluence tools", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/oauth/token/accessible-resources", "response": { "transform": "" } } }, { "id": "search_content", "name": "Search Confluence", "description": "Search for pages and blog posts in Confluence", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/confluence/{cloudId}/wiki/rest/api/content/search", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "cql": { "type": "string", "in": "query", "description": "Confluence Query Language expression", "required": true }, "limit": { "type": "number", "in": "query", "description": "Maximum results to return", "default": 25 }, "start": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 }, "expand": { "type": "string", "in": "query", "description": "Comma-separated expansions", "default": "space,version" } }, "response": { "transform": "results" } } }, { "id": "get_page", "name": "Get Page", "description": "Get the content of a specific Confluence page (uses v2 API)", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/confluence/{cloudId}/wiki/api/v2/pages/{pageId}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "pageId": { "type": "string", "in": "path", "description": "Confluence page ID", "required": true }, "body-format": { "type": "string", "in": "query", "description": "Body representation format", "default": "storage" } } } }, { "id": "create_page", "name": "Create Page", "description": "Create a new page in a Confluence space (uses v2 API; requires spaceId from list_spaces)", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.atlassian.com/ex/confluence/{cloudId}/wiki/api/v2/pages", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true } }, "body": { "spaceId": { "type": "string", "description": "Numeric space ID (use list_spaces to get the id field)", "required": true }, "title": { "type": "string", "description": "Page title", "required": true }, "status": { "type": "string", "description": "Page status", "default": "current" }, "parentId": { "type": "string", "description": "Parent page ID (optional)" }, "body": { "type": "object", "description": "Page body, e.g. {representation: 'storage', value: '<p>content</p>'}", "required": true } } } }, { "id": "update_page", "name": "Update Page", "description": "Update the content of an existing Confluence page (uses v2 API; version.number must be current+1)", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://api.atlassian.com/ex/confluence/{cloudId}/wiki/api/v2/pages/{pageId}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "pageId": { "type": "string", "in": "path", "description": "Confluence page ID", "required": true } }, "body": { "id": { "type": "string", "description": "Page ID (must match pageId path param)", "required": true }, "status": { "type": "string", "description": "Page status", "default": "current" }, "title": { "type": "string", "description": "New page title (omit to keep existing)" }, "version": { "type": "object", "description": "Version object; number must be current version + 1", "required": true }, "body": { "type": "object", "description": "Updated body, e.g. {representation: 'storage', value: '<p>...</p>'}" } } } }, { "id": "list_spaces", "name": "List Spaces", "description": "List all accessible Confluence spaces", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/confluence/{cloudId}/wiki/rest/api/space", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "limit": { "type": "number", "in": "query", "description": "Maximum spaces to return", "default": 25 }, "start": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 } }, "response": { "transform": "results" } } }], "prompts": [{ "id": "search_docs", "title": "Search documentation", "prompt": "Search Confluence for documentation about a specific topic or feature.", "category": "productivity", "icon": "search" }, { "id": "summarize_page", "title": "Summarize a page", "prompt": "Read and summarize a Confluence page. Extract key information and action items.", "category": "productivity", "icon": "document" }, { "id": "create_doc", "title": "Create documentation", "prompt": "Create a new documentation page in Confluence with structured content.", "category": "productivity", "icon": "plus" }, { "id": "update_doc", "title": "Update documentation", "prompt": "Update an existing Confluence page with new information while preserving existing content.", "category": "productivity", "icon": "edit" }], "suggestedWith": ["jira", "slack", "notion"] },
|
|
9
9
|
{ "name": "discord", "displayName": "Discord", "icon": "discord.svg", "description": "Read messages, send messages, and interact with Discord servers", "auth": { "type": "oauth2", "provider": "discord", "authorizationUrl": "https://discord.com/api/oauth2/authorize", "tokenUrl": "https://discord.com/api/oauth2/token", "scopes": ["identify", "guilds", "guilds.members.read", "messages.read"], "tokenAuthMethod": "body", "requiredApis": [{ "name": "Discord Application", "enableUrl": "https://discord.com/developers/applications" }] }, "envVars": [{ "name": "DISCORD_CLIENT_ID", "description": "Discord OAuth Client ID (from your application)", "required": true, "sensitive": false, "docsUrl": "https://discord.com/developers/applications" }, { "name": "DISCORD_CLIENT_SECRET", "description": "Discord OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://discord.com/developers/applications" }, { "name": "DISCORD_BOT_TOKEN", "description": "Discord Bot Token (optional, for advanced bot features)", "required": false, "sensitive": true, "docsUrl": "https://discord.com/developers/applications" }], "tools": [{ "id": "list_guilds", "name": "List Guilds", "description": "List Discord servers (guilds) the user is a member of", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://discord.com/api/v10/users/@me/guilds", "params": { "limit": { "type": "number", "in": "query", "description": "Maximum guilds to return", "default": 100 }, "before": { "type": "string", "in": "query", "description": "Return guilds before this guild ID" }, "after": { "type": "string", "in": "query", "description": "Return guilds after this guild ID" } } } }, { "id": "list_channels", "name": "List Channels", "description": "List channels in a Discord server", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://discord.com/api/v10/guilds/{guildId}/channels", "params": { "guildId": { "type": "string", "in": "path", "description": "Discord guild/server ID", "required": true } }, "response": { "transform": "value" } } }, { "id": "get_messages", "name": "Get Messages", "description": "Get recent messages from a Discord channel", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://discord.com/api/v10/channels/{channelId}/messages", "params": { "channelId": { "type": "string", "in": "path", "description": "Discord channel ID", "required": true }, "limit": { "type": "number", "in": "query", "description": "Maximum messages to return", "default": 50 }, "before": { "type": "string", "in": "query", "description": "Only messages before this message ID" }, "after": { "type": "string", "in": "query", "description": "Only messages after this message ID" } } } }, { "id": "send_message", "name": "Send Message", "description": "Send a message to a Discord channel", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://discord.com/api/v10/channels/{channelId}/messages", "params": { "channelId": { "type": "string", "in": "path", "description": "Discord channel ID", "required": true } }, "body": { "content": { "type": "string", "description": "Message content, max 2000 characters", "required": true }, "tts": { "type": "boolean", "description": "Whether to send as text-to-speech", "default": false } } } }, { "id": "get_user", "name": "Get User", "description": "Get information about the authenticated Discord user", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://discord.com/api/v10/users/@me" } }], "prompts": [{ "id": "check_messages", "title": "Check my Discord messages", "prompt": "Check my recent Discord messages across all servers and summarize any important updates or mentions.", "category": "communication", "icon": "message" }, { "id": "send_announcement", "title": "Send an announcement", "prompt": "Send an announcement message to a specific Discord channel.", "category": "communication", "icon": "megaphone" }, { "id": "list_servers", "title": "List my servers", "prompt": "Show me all the Discord servers I'm a member of with their details.", "category": "communication", "icon": "list" }], "suggestedWith": ["slack", "github", "notion"] },
|
|
10
10
|
{ "name": "docs-google", "displayName": "Google Docs", "icon": "docs-google.svg", "description": "Read, create, and manage Google Docs documents", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/documents.readonly", "https://www.googleapis.com/auth/documents", "https://www.googleapis.com/auth/drive.readonly"], "requiredApis": [{ "name": "Google Docs API", "enableUrl": "https://console.cloud.google.com/apis/library/docs.googleapis.com" }, { "name": "Google Drive API", "enableUrl": "https://console.cloud.google.com/apis/library/drive.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_documents", "name": "List Documents", "description": "List recent Google Docs documents from Drive", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Drive query limited to Google Docs documents", "default": "mimeType='application/vnd.google-apps.document' and trashed=false" }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of documents to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, webViewLink, modifiedTime)" } }, "response": { "transform": "files" } } }, { "id": "get_document", "name": "Get Document", "description": "Get document content and metadata", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://docs.googleapis.com/v1/documents/{documentId}", "params": { "documentId": { "type": "string", "in": "path", "description": "Google Docs document ID", "required": true }, "suggestionsViewMode": { "type": "string", "in": "query", "description": "Suggestions view mode to use when reading the document" } } } }, { "id": "create_document", "name": "Create Document", "description": "Create a new document with optional initial content", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://docs.googleapis.com/v1/documents", "body": { "title": { "type": "string", "description": "Document title", "required": true } } } }, { "id": "update_document", "name": "Update Document", "description": "Update document content using batch requests", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://docs.googleapis.com/v1/documents/{documentId}:batchUpdate", "params": { "documentId": { "type": "string", "in": "path", "description": "Google Docs document ID", "required": true } }, "body": { "requests": { "type": "array", "description": "Google Docs batchUpdate requests, e.g. insertText/updateTextStyle requests", "required": true }, "writeControl": { "type": "object", "description": "Optional Google Docs write control" } } } }, { "id": "search_documents", "name": "Search Documents", "description": "Search for documents by query string", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Drive query expression for Google Docs documents", "required": true }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of documents to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, webViewLink, modifiedTime)" } }, "response": { "transform": "files" } } }], "prompts": [{ "id": "summarize_doc", "title": "Summarize a document", "prompt": "Read a Google Docs document and provide a concise summary of its contents, key points, and main themes.", "category": "productivity", "icon": "file-text" }, { "id": "create_report", "title": "Create a report document", "prompt": "Create a new Google Docs document with a well-formatted report including headings, bullet points, and structured content.", "category": "productivity", "icon": "plus" }, { "id": "edit_document", "title": "Edit a document", "prompt": "Update an existing Google Docs document with new content, formatting changes, or corrections.", "category": "productivity", "icon": "edit" }], "suggestedWith": ["gmail", "calendar", "drive", "sheets"] },
|
|
11
|
-
{ "name": "drive", "displayName": "Google Drive", "icon": "drive.svg", "description": "Access, search, and manage files and folders in Google Drive", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/drive.file"], "requiredApis": [{ "name": "Google Drive API", "enableUrl": "https://console.cloud.google.com/apis/library/drive.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_files", "name": "List Files", "description": "List files and folders in a Google Drive folder or root", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Optional Drive query expression" }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of files to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, mimeType, webViewLink, modifiedTime, size, parents)" } }, "response": { "transform": "files" } } }, { "id": "get_file", "name": "Get File", "description": "Get metadata and details about a specific file or folder", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files/{fileId}", "params": { "fileId": { "type": "string", "in": "path", "description": "Google Drive file ID", "required": true }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "id, name, mimeType, webViewLink, modifiedTime, size, parents" } } } }, { "id": "search_files", "name": "Search Files", "description": "Search for files and folders using queries", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Drive query expression used to search files", "required": true }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of files to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, mimeType, webViewLink, modifiedTime, size, parents)" } }, "response": { "transform": "files" } } }, { "id": "create_folder", "name": "Create Folder", "description": "Create a new folder in Google Drive", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/drive/v3/files", "body": { "name": { "type": "string", "description": "Folder name", "required": true }, "mimeType": { "type": "string", "description": "Google Drive MIME type for folders", "default": "application/vnd.google-apps.folder" }, "parents": { "type": "array", "description": "Optional parent folder IDs" } } } }, { "id": "upload_file", "name": "Upload File", "description": "Upload or create a file in Google Drive", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/upload/drive/v3/files", "params": { "uploadType": { "type": "string", "in": "query", "description": "Google Drive upload mode", "default": "media" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "id, name, mimeType, webViewLink, modifiedTime, size, parents" } }, "body": { "content": { "type": "string", "description": "Text content to upload", "required": true }, "mimeType": { "type": "string", "description": "Content MIME type", "default": "text/plain" }, "name": { "type": "string", "description": "Desired file name; use create_folder for folders", "required": false }, "parents": { "type": "array", "description": "Optional parent folder IDs" } } } }], "prompts": [{ "id": "organize_files", "title": "Organize Drive files", "prompt": "Help me organize files in Google Drive by creating folders and moving files based on file types or names.", "category": "productivity", "icon": "folder" }, { "id": "find_document", "title": "Find a document", "prompt": "Search Google Drive for a specific file or document by name, type, or content.", "category": "productivity", "icon": "search" }, { "id": "backup_files", "title": "Create backup structure", "prompt": "Create a backup folder structure in Google Drive and organize important files.", "category": "productivity", "icon": "upload" }], "suggestedWith": ["gmail", "calendar", "sheets"] },
|
|
12
|
-
{ "name": "
|
|
13
|
-
{ "name": "figma", "displayName": "Figma", "icon": "figma.svg", "description": "Access Figma designs, files, comments, and collaborate on design projects", "auth": { "type": "oauth2", "provider": "figma", "authorizationUrl": "https://www.figma.com/oauth", "tokenUrl": "https://api.figma.com/v1/oauth/token", "scopes": ["file_content:read", "file_comments:write"], "tokenAuthMethod": "client_secret_basic", "requiredApis": [{ "name": "Figma OAuth App", "enableUrl": "https://www.figma.com/developers/apps" }] }, "envVars": [{ "name": "FIGMA_CLIENT_ID", "description": "Figma OAuth Client ID (from your app settings)", "required": true, "sensitive": false, "docsUrl": "https://www.figma.com/developers/apps" }, { "name": "FIGMA_CLIENT_SECRET", "description": "Figma OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://www.figma.com/developers/apps" }], "tools": [{ "id": "list_files", "name": "List Files", "description": "List recent Figma files accessible to the user", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/projects/{projectId}/files", "params": { "projectId": { "type": "string", "in": "path", "description": "Figma project ID whose files should be listed", "required": true }, "branch_data": { "type": "boolean", "in": "query", "description": "Include branch metadata", "default": false } } } }, { "id": "get_file", "name": "Get File", "description": "Get detailed information about a Figma file including components and styles", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/files/{fileKey}", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true }, "ids": { "type": "string", "in": "query", "description": "Comma-separated node IDs to include" }, "depth": { "type": "number", "in": "query", "description": "Traversal depth for document tree" }, "geometry": { "type": "string", "in": "query", "description": "Set to paths to export vector data" }, "plugin_data": { "type": "string", "in": "query", "description": "Plugin data namespace to include" } } } }, { "id": "get_comments", "name": "Get Comments", "description": "Get all comments on a Figma file", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/files/{fileKey}/comments", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true } }, "response": { "transform": "comments" } } }, { "id": "post_comment", "name": "Post Comment", "description": "Post a comment on a Figma file", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.figma.com/v1/files/{fileKey}/comments", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true } }, "body": { "message": { "type": "string", "description": "Comment text", "required": true }, "client_meta": { "type": "object", "description": "Optional Figma comment position metadata" } } } }, { "id": "list_projects", "name": "List Projects", "description": "List all projects in a team", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/teams/{teamId}/projects", "params": { "teamId": { "type": "string", "in": "path", "description": "Figma team ID", "required": true } }, "response": { "transform": "projects" } } }], "prompts": [{ "id": "review_design", "title": "Review a design", "prompt": "Review a Figma design file and provide feedback on the components, layout, and design system usage.", "category": "design", "icon": "eye" }, { "id": "summarize_comments", "title": "Summarize comments", "prompt": "Read all comments on a Figma file and summarize the feedback, action items, and unresolved discussions.", "category": "design", "icon": "message" }, { "id": "extract_components", "title": "Extract components", "prompt": "List all components in a Figma file and describe their structure, variants, and properties.", "category": "design", "icon": "component" }, { "id": "design_feedback", "title": "Give design feedback", "prompt": "Review the design file and post constructive feedback as comments on specific elements.", "category": "design", "icon": "plus" }], "suggestedWith": ["linear", "slack", "notion"] },
|
|
14
|
-
{ "name": "github", "displayName": "GitHub", "icon": "github.svg", "description": "Manage repositories, issues, and pull requests", "auth": { "type": "oauth2", "provider": "github", "authorizationUrl": "https://github.com/login/oauth/authorize", "tokenUrl": "https://github.com/login/oauth/access_token", "scopes": ["repo", "read:user", "read:org"] }, "envVars": [{ "name": "GITHUB_CLIENT_ID", "description": "GitHub OAuth App Client ID", "required": true, "sensitive": false, "docsUrl": "https://github.com/settings/developers" }, { "name": "GITHUB_CLIENT_SECRET", "description": "GitHub OAuth App Client Secret", "required": true, "sensitive": true, "docsUrl": "https://github.com/settings/developers" }], "tools": [{ "id": "list_repos", "name": "List Repositories", "description": "Get list of user's repositories", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/user/repos", "params": { "type": { "type": "string", "in": "query", "description": "Type: all, owner, public, private, member" }, "sort": { "type": "string", "in": "query", "description": "Sort: created, updated, pushed, full_name", "default": "updated" }, "per_page": { "type": "number", "in": "query", "description": "Results per page (max 100)", "default": 30 } } } }, { "id": "get_repo", "name": "Get Repository", "description": "Get details of a specific repository", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true } } } }, { "id": "list_prs", "name": "List Pull Requests", "description": "Get pull requests for a repository", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/pulls", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "state": { "type": "string", "in": "query", "description": "State: open, closed, all", "default": "open" }, "per_page": { "type": "number", "in": "query", "description": "Results per page", "default": 30 } } } }, { "id": "create_issue", "name": "Create Issue", "description": "Create a new issue in a repository", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.github.com/repos/{owner}/{repo}/issues", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true } }, "body": { "title": { "type": "string", "description": "Issue title", "required": true }, "body": { "type": "string", "description": "Issue body (markdown)" }, "labels": { "type": "array", "description": "Label names" }, "assignees": { "type": "array", "description": "Usernames to assign" } } } }, { "id": "get_pr_diff", "name": "Get PR Diff", "description": "Get the diff for a pull request", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "pull_number": { "type": "number", "in": "path", "description": "Pull request number", "required": true }, "Accept": { "type": "string", "in": "header", "description": "Response format", "default": "application/vnd.github.v3.diff" } } } }, { "id": "list_issues", "name": "List Issues", "description": "List issues for a repository", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.github.com/graphql", "query": "query($owner: String!, $repo: String!, $first: Int, $states: [IssueState!]) { repository(owner: $owner, name: $repo) { issues(first: $first, states: $states, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { id number title body state url createdAt updatedAt author { login } labels(first: 10) { nodes { name } } assignees(first: 10) { nodes { login } } } } } }", "params": { "owner": { "type": "string", "in": "body", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "body", "description": "Repository name", "required": true }, "states": { "type": "string[]", "in": "body", "description": "Issue states to include (e.g. OPEN, CLOSED)", "default": ["OPEN"] }, "first": { "type": "number", "in": "body", "description": "Results per page", "default": 30 } }, "response": { "transform": "repository.issues.nodes" } } }, { "id": "get_issue", "name": "Get Issue", "description": "Get details of a GitHub issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue number", "required": true } } } }, { "id": "update_issue", "name": "Update Issue", "description": "Update, close, or reopen a GitHub issue", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue number", "required": true } }, "body": { "title": { "type": "string", "description": "Updated issue title" }, "body": { "type": "string", "description": "Updated issue body (markdown)" }, "state": { "type": "string", "description": "Issue state: open or closed" }, "labels": { "type": "array", "description": "Replacement label names" }, "assignees": { "type": "array", "description": "Replacement assignee usernames" } } } }, { "id": "add_issue_comment", "name": "Add Issue Comment", "description": "Add a comment to a GitHub issue or pull request", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/comments", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue or pull request number", "required": true } }, "body": { "body": { "type": "string", "description": "Comment body (markdown)", "required": true } } } }], "prompts": [{ "id": "review_prs", "title": "Review my open PRs", "prompt": "Show me my open pull requests and help me review them. Summarize the changes and any comments.", "category": "development", "icon": "git-pull-request" }, { "id": "create_issue", "title": "Create GitHub issue", "prompt": "Help me create a new GitHub issue with a clear description and appropriate labels.", "category": "development", "icon": "circle-dot" }, { "id": "summarize_commits", "title": "Summarize recent commits", "prompt": "Summarize the recent commits in my repository and highlight significant changes.", "category": "development", "icon": "git-commit" }], "suggestedWith": ["jira", "slack"] },
|
|
11
|
+
{ "name": "drive", "displayName": "Google Drive", "icon": "drive.svg", "description": "Access, search, and manage files and folders in Google Drive", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/drive.file"], "requiredApis": [{ "name": "Google Drive API", "enableUrl": "https://console.cloud.google.com/apis/library/drive.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_files", "name": "List Files", "description": "List files and folders in a Google Drive folder or root", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Optional Drive query expression" }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of files to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, mimeType, webViewLink, modifiedTime, size, parents)" } }, "response": { "transform": "files" } } }, { "id": "get_file", "name": "Get File", "description": "Get metadata and details about a specific file or folder", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files/{fileId}", "params": { "fileId": { "type": "string", "in": "path", "description": "Google Drive file ID", "required": true }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "id, name, mimeType, webViewLink, modifiedTime, size, parents" } } } }, { "id": "search_files", "name": "Search Files", "description": "Search for files and folders using queries", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Drive query expression used to search files", "required": true }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of files to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, mimeType, webViewLink, modifiedTime, size, parents)" } }, "response": { "transform": "files" } } }, { "id": "create_folder", "name": "Create Folder", "description": "Create a new folder in Google Drive", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/drive/v3/files", "body": { "name": { "type": "string", "description": "Folder name", "required": true }, "mimeType": { "type": "string", "description": "Google Drive MIME type for folders", "default": "application/vnd.google-apps.folder" }, "parents": { "type": "array", "description": "Optional parent folder IDs" } } } }, { "id": "upload_file", "name": "Upload File", "description": "Upload or create a file in Google Drive", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://www.googleapis.com/upload/drive/v3/files", "params": { "uploadType": { "type": "string", "in": "query", "description": "Google Drive upload mode", "default": "media" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "id, name, mimeType, webViewLink, modifiedTime, size, parents" } }, "body": { "content": { "type": "string", "description": "Text content to upload", "required": true }, "mimeType": { "type": "string", "description": "Content MIME type", "default": "text/plain" }, "name": { "type": "string", "description": "Desired file name; use create_folder for folders", "required": false }, "parents": { "type": "array", "description": "Optional parent folder IDs" } } } }, { "id": "update_file", "name": "Update File", "description": "Rename a file, update its description, or move it to a different folder in Google Drive", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://www.googleapis.com/drive/v3/files/{fileId}", "params": { "fileId": { "type": "string", "in": "path", "description": "Google Drive file ID to update", "required": true }, "addParents": { "type": "string", "in": "query", "description": "Comma-separated parent folder IDs to add (use with removeParents to move)" }, "removeParents": { "type": "string", "in": "query", "description": "Comma-separated parent folder IDs to remove (use with addParents to move)" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "id, name, mimeType, webViewLink, modifiedTime, parents" } }, "body": { "name": { "type": "string", "description": "New file name" }, "description": { "type": "string", "description": "New file description" } } } }, { "id": "delete_file", "name": "Delete File", "description": "Permanently delete a file or folder from Google Drive", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://www.googleapis.com/drive/v3/files/{fileId}", "params": { "fileId": { "type": "string", "in": "path", "description": "Google Drive file ID to delete", "required": true } } } }], "prompts": [{ "id": "organize_files", "title": "Organize Drive files", "prompt": "Help me organize files in Google Drive by creating folders and moving files based on file types or names.", "category": "productivity", "icon": "folder" }, { "id": "find_document", "title": "Find a document", "prompt": "Search Google Drive for a specific file or document by name, type, or content.", "category": "productivity", "icon": "search" }, { "id": "backup_files", "title": "Create backup structure", "prompt": "Create a backup folder structure in Google Drive and organize important files.", "category": "productivity", "icon": "upload" }], "suggestedWith": ["gmail", "calendar", "sheets"] },
|
|
12
|
+
{ "name": "figma", "displayName": "Figma", "icon": "figma.svg", "description": "Access Figma designs, files, comments, and collaborate on design projects", "auth": { "type": "oauth2", "provider": "figma", "authorizationUrl": "https://www.figma.com/oauth", "tokenUrl": "https://api.figma.com/v1/oauth/token", "scopes": ["file_content:read", "file_comments:read", "file_comments:write"], "tokenAuthMethod": "client_secret_basic", "requiredApis": [{ "name": "Figma OAuth App", "enableUrl": "https://www.figma.com/developers/apps" }] }, "envVars": [{ "name": "FIGMA_CLIENT_ID", "description": "Figma OAuth Client ID (from your app settings)", "required": true, "sensitive": false, "docsUrl": "https://www.figma.com/developers/apps" }, { "name": "FIGMA_CLIENT_SECRET", "description": "Figma OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://www.figma.com/developers/apps" }], "tools": [{ "id": "get_me", "name": "Get Me", "description": "Get the authenticated user's Figma profile (id, email, handle). Use this to verify the connection and identify the user.", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/me" } }, { "id": "list_files", "name": "List Files", "description": "List recent Figma files accessible to the user", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/projects/{projectId}/files", "params": { "projectId": { "type": "string", "in": "path", "description": "Figma project ID whose files should be listed", "required": true }, "branch_data": { "type": "boolean", "in": "query", "description": "Include branch metadata", "default": false } } } }, { "id": "get_file", "name": "Get File", "description": "Get detailed information about a Figma file including components and styles", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/files/{fileKey}", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true }, "ids": { "type": "string", "in": "query", "description": "Comma-separated node IDs to include" }, "depth": { "type": "number", "in": "query", "description": "Traversal depth for document tree" }, "geometry": { "type": "string", "in": "query", "description": "Set to paths to export vector data" }, "plugin_data": { "type": "string", "in": "query", "description": "Plugin data namespace to include" } } } }, { "id": "get_comments", "name": "Get Comments", "description": "Get all comments on a Figma file", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/files/{fileKey}/comments", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true } }, "response": { "transform": "comments" } } }, { "id": "post_comment", "name": "Post Comment", "description": "Post a comment on a Figma file", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.figma.com/v1/files/{fileKey}/comments", "params": { "fileKey": { "type": "string", "in": "path", "description": "Figma file key", "required": true } }, "body": { "message": { "type": "string", "description": "Comment text", "required": true }, "client_meta": { "type": "object", "description": "Optional Figma comment position metadata" } } } }, { "id": "list_projects", "name": "List Projects", "description": "List all projects in a team. The teamId is the numeric ID found in the Figma URL: figma.com/files/team/{teamId}/...", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.figma.com/v1/teams/{teamId}/projects", "params": { "teamId": { "type": "string", "in": "path", "description": "Numeric Figma team ID from the URL: figma.com/files/team/{teamId}/...", "required": true } }, "response": { "transform": "projects" } } }], "prompts": [{ "id": "review_design", "title": "Review a design", "prompt": "Review a Figma design file and provide feedback on the components, layout, and design system usage.", "category": "design", "icon": "eye" }, { "id": "summarize_comments", "title": "Summarize comments", "prompt": "Read all comments on a Figma file and summarize the feedback, action items, and unresolved discussions.", "category": "design", "icon": "message" }, { "id": "extract_components", "title": "Extract components", "prompt": "List all components in a Figma file and describe their structure, variants, and properties.", "category": "design", "icon": "component" }, { "id": "design_feedback", "title": "Give design feedback", "prompt": "Review the design file and post constructive feedback as comments on specific elements.", "category": "design", "icon": "plus" }], "suggestedWith": ["linear", "slack", "notion"] },
|
|
13
|
+
{ "name": "github", "displayName": "GitHub", "icon": "github.svg", "description": "Manage repositories, issues, and pull requests", "auth": { "type": "oauth2", "provider": "github", "authorizationUrl": "https://github.com/login/oauth/authorize", "tokenUrl": "https://github.com/login/oauth/access_token", "scopes": ["repo", "read:user", "read:org"] }, "envVars": [{ "name": "GITHUB_CLIENT_ID", "description": "GitHub OAuth App Client ID", "required": true, "sensitive": false, "docsUrl": "https://github.com/settings/developers" }, { "name": "GITHUB_CLIENT_SECRET", "description": "GitHub OAuth App Client Secret", "required": true, "sensitive": true, "docsUrl": "https://github.com/settings/developers" }], "tools": [{ "id": "list_repos", "name": "List Repositories", "description": "Get list of user's repositories", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/user/repos", "params": { "type": { "type": "string", "in": "query", "description": "Type: all, owner, public, private, member" }, "sort": { "type": "string", "in": "query", "description": "Sort: created, updated, pushed, full_name", "default": "updated" }, "per_page": { "type": "number", "in": "query", "description": "Results per page (max 100)", "default": 30 } } } }, { "id": "get_repo", "name": "Get Repository", "description": "Get details of a specific repository", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true } } } }, { "id": "list_prs", "name": "List Pull Requests", "description": "Get pull requests for a repository", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/pulls", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "state": { "type": "string", "in": "query", "description": "State: open, closed, all", "default": "open" }, "per_page": { "type": "number", "in": "query", "description": "Results per page", "default": 30 } } } }, { "id": "create_issue", "name": "Create Issue", "description": "Create a new issue in a repository", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.github.com/repos/{owner}/{repo}/issues", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true } }, "body": { "title": { "type": "string", "description": "Issue title", "required": true }, "body": { "type": "string", "description": "Issue body (markdown)" }, "labels": { "type": "array", "description": "Label names" }, "assignees": { "type": "array", "description": "Usernames to assign" } } } }, { "id": "get_pr_diff", "name": "Get PR Diff", "description": "Get the diff for a pull request", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "pull_number": { "type": "number", "in": "path", "description": "Pull request number", "required": true }, "Accept": { "type": "string", "in": "header", "description": "Response format", "default": "application/vnd.github.v3.diff" } } } }, { "id": "list_issues", "name": "List Issues", "description": "List issues for a repository", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.github.com/graphql", "query": "query($owner: String!, $repo: String!, $first: Int, $states: [IssueState!]) { repository(owner: $owner, name: $repo) { issues(first: $first, states: $states, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { id number title body state url createdAt updatedAt author { login } labels(first: 10) { nodes { name } } assignees(first: 10) { nodes { login } } } } } }", "params": { "owner": { "type": "string", "in": "body", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "body", "description": "Repository name", "required": true }, "states": { "type": "string[]", "in": "body", "description": "Issue states to include (e.g. OPEN, CLOSED)", "default": ["OPEN"] }, "first": { "type": "number", "in": "body", "description": "Results per page", "default": 30 } }, "response": { "transform": "repository.issues.nodes" } } }, { "id": "get_issue", "name": "Get Issue", "description": "Get details of a GitHub issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue number", "required": true } } } }, { "id": "update_issue", "name": "Update Issue", "description": "Update, close, or reopen a GitHub issue", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue number", "required": true } }, "body": { "title": { "type": "string", "description": "Updated issue title" }, "body": { "type": "string", "description": "Updated issue body (markdown)" }, "state": { "type": "string", "description": "Issue state: open or closed" }, "labels": { "type": "array", "description": "Replacement label names" }, "assignees": { "type": "array", "description": "Replacement assignee usernames" } } } }, { "id": "add_issue_comment", "name": "Add Issue Comment", "description": "Add a comment to a GitHub issue or pull request", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/comments", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "issue_number": { "type": "number", "in": "path", "description": "Issue or pull request number", "required": true } }, "body": { "body": { "type": "string", "description": "Comment body (markdown)", "required": true } } } }, { "id": "get_pr", "name": "Get Pull Request", "description": "Get details of a specific pull request (title, body, status, author, reviewers, labels)", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "pull_number": { "type": "number", "in": "path", "description": "Pull request number", "required": true } } } }, { "id": "create_pr", "name": "Create Pull Request", "description": "Create a new pull request in a repository", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.github.com/repos/{owner}/{repo}/pulls", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true } }, "body": { "title": { "type": "string", "description": "PR title", "required": true }, "body": { "type": "string", "description": "PR description (markdown)" }, "head": { "type": "string", "description": "Branch to merge from (e.g. feature-branch or owner:feature-branch)", "required": true }, "base": { "type": "string", "description": "Branch to merge into (e.g. main)", "required": true }, "draft": { "type": "boolean", "description": "Create as draft PR", "default": false } } } }, { "id": "merge_pr", "name": "Merge Pull Request", "description": "Merge an open pull request", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/merge", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "pull_number": { "type": "number", "in": "path", "description": "Pull request number to merge", "required": true } }, "body": { "commit_title": { "type": "string", "description": "Merge commit title" }, "commit_message": { "type": "string", "description": "Merge commit message" }, "merge_method": { "type": "string", "description": "Merge method: merge, squash, or rebase", "default": "merge" } } } }, { "id": "list_commits", "name": "List Commits", "description": "List commits for a repository, branch, or file path", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.github.com/repos/{owner}/{repo}/commits", "params": { "owner": { "type": "string", "in": "path", "description": "Repository owner", "required": true }, "repo": { "type": "string", "in": "path", "description": "Repository name", "required": true }, "sha": { "type": "string", "in": "query", "description": "SHA or branch name to list commits from" }, "path": { "type": "string", "in": "query", "description": "Only include commits touching this file path" }, "per_page": { "type": "number", "in": "query", "description": "Results per page (max 100)", "default": 30 } } } }], "prompts": [{ "id": "review_prs", "title": "Review my open PRs", "prompt": "Show me my open pull requests and help me review them. Summarize the changes and any comments.", "category": "development", "icon": "git-pull-request" }, { "id": "create_issue", "title": "Create GitHub issue", "prompt": "Help me create a new GitHub issue with a clear description and appropriate labels.", "category": "development", "icon": "circle-dot" }, { "id": "summarize_commits", "title": "Summarize recent commits", "prompt": "Summarize the recent commits in my repository and highlight significant changes.", "category": "development", "icon": "git-commit" }], "suggestedWith": ["jira", "slack"] },
|
|
15
14
|
{ "name": "gitlab", "displayName": "GitLab", "icon": "gitlab.svg", "description": "Search and manage GitLab issues, merge requests, and projects", "auth": { "type": "oauth2", "provider": "gitlab", "authorizationUrl": "https://gitlab.com/oauth/authorize", "tokenUrl": "https://gitlab.com/oauth/token", "scopes": ["api", "read_user", "read_repository"], "tokenAuthMethod": "body", "requiredApis": [{ "name": "GitLab Application", "enableUrl": "https://gitlab.com/-/profile/applications" }] }, "envVars": [{ "name": "GITLAB_CLIENT_ID", "description": "GitLab OAuth Application ID", "required": true, "sensitive": false, "docsUrl": "https://docs.gitlab.com/ee/api/oauth2.html" }, { "name": "GITLAB_CLIENT_SECRET", "description": "GitLab OAuth Application Secret", "required": true, "sensitive": true, "docsUrl": "https://docs.gitlab.com/ee/api/oauth2.html" }], "tools": [{ "id": "list_projects", "name": "List Projects", "description": "List accessible GitLab projects", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/projects", "params": { "membership": { "type": "boolean", "in": "query", "description": "Only return projects the user is a member of", "default": true }, "search": { "type": "string", "in": "query", "description": "Search text for projects" }, "simple": { "type": "boolean", "in": "query", "description": "Return simplified project objects", "default": true }, "page": { "type": "number", "in": "query", "description": "Result page", "default": 1 }, "per_page": { "type": "number", "in": "query", "description": "Results per page", "default": 20 } } } }, { "id": "get_project", "name": "Get Project", "description": "Get detailed information about a GitLab project", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/projects/{projectId}", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true } } } }, { "id": "search_issues", "name": "Search Issues", "description": "Search for issues across projects", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/issues", "params": { "search": { "type": "string", "in": "query", "description": "Search text for issue title or description" }, "state": { "type": "string", "in": "query", "description": "Issue state", "default": "opened" }, "scope": { "type": "string", "in": "query", "description": "Issue scope such as created_by_me, assigned_to_me, or all", "default": "assigned_to_me" }, "labels": { "type": "string", "in": "query", "description": "Comma-separated label names" }, "page": { "type": "number", "in": "query", "description": "Result page", "default": 1 }, "per_page": { "type": "number", "in": "query", "description": "Results per page", "default": 20 } } } }, { "id": "get_issue", "name": "Get Issue", "description": "Get detailed information about a specific issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/projects/{projectId}/issues/{issueIid}", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true }, "issueIid": { "type": "number", "in": "path", "description": "Project-local issue IID", "required": true } } } }, { "id": "create_issue", "name": "Create Issue", "description": "Create a new issue in a project", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gitlab.com/api/v4/projects/{projectId}/issues", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true } }, "body": { "title": { "type": "string", "description": "Issue title", "required": true }, "description": { "type": "string", "description": "Issue description" }, "labels": { "type": "string", "description": "Comma-separated labels" }, "assignee_ids": { "type": "array", "description": "GitLab user IDs to assign" } } } }, { "id": "update_issue", "name": "Update Issue", "description": "Update, close, or reopen a GitLab issue", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://gitlab.com/api/v4/projects/{projectId}/issues/{issueIid}", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true }, "issueIid": { "type": "number", "in": "path", "description": "Project-local issue IID", "required": true } }, "body": { "title": { "type": "string", "description": "Updated issue title" }, "description": { "type": "string", "description": "Updated issue description" }, "state_event": { "type": "string", "description": "close or reopen" }, "labels": { "type": "string", "description": "Comma-separated replacement labels" }, "assignee_ids": { "type": "array", "description": "GitLab user IDs to assign" } } } }, { "id": "add_issue_comment", "name": "Add Issue Comment", "description": "Add a comment/note to a GitLab issue", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gitlab.com/api/v4/projects/{projectId}/issues/{issueIid}/notes", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true }, "issueIid": { "type": "number", "in": "path", "description": "Project-local issue IID", "required": true } }, "body": { "body": { "type": "string", "description": "Comment body in Markdown", "required": true }, "confidential": { "type": "boolean", "description": "Make the note visible only to project members" } } } }, { "id": "list_merge_requests", "name": "List Merge Requests", "description": "List merge requests for a project or across projects", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/merge_requests", "params": { "state": { "type": "string", "in": "query", "description": "Merge request state", "default": "opened" }, "scope": { "type": "string", "in": "query", "description": "Merge request scope such as created_by_me, assigned_to_me, or all", "default": "assigned_to_me" }, "search": { "type": "string", "in": "query", "description": "Search text for merge requests" }, "page": { "type": "number", "in": "query", "description": "Result page", "default": 1 }, "per_page": { "type": "number", "in": "query", "description": "Results per page", "default": 20 } } } }, { "id": "get_merge_request", "name": "Get Merge Request", "description": "Get detailed information about a specific GitLab merge request", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gitlab.com/api/v4/projects/{projectId}/merge_requests/{mergeRequestIid}", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true }, "mergeRequestIid": { "type": "number", "in": "path", "description": "Project-local merge request IID", "required": true } } } }, { "id": "add_merge_request_comment", "name": "Add Merge Request Comment", "description": "Add a comment/note to a GitLab merge request", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gitlab.com/api/v4/projects/{projectId}/merge_requests/{mergeRequestIid}/notes", "params": { "projectId": { "type": "string", "in": "path", "description": "GitLab numeric project ID or raw namespace/project path", "required": true }, "mergeRequestIid": { "type": "number", "in": "path", "description": "Project-local merge request IID", "required": true } }, "body": { "body": { "type": "string", "description": "Comment body in Markdown", "required": true }, "internal": { "type": "boolean", "description": "Make the note internal when supported" } } } }], "prompts": [{ "id": "find_issues", "title": "Find my issues", "prompt": "Search for issues assigned to me that are open. Show me the most important ones.", "category": "development", "icon": "bug" }, { "id": "review_mrs", "title": "Review merge requests", "prompt": "Show me all open merge requests that need my review. Summarize what each one does.", "category": "development", "icon": "git-merge" }, { "id": "create_bug_report", "title": "Create bug report", "prompt": "Help me create a detailed bug report issue with steps to reproduce, expected vs actual behavior.", "category": "development", "icon": "plus" }, { "id": "project_status", "title": "Project status", "prompt": "Give me a summary of my projects: open issues, merge requests, and recent activity.", "category": "development", "icon": "list" }], "suggestedWith": ["github", "jira", "slack"] },
|
|
16
15
|
{ "name": "gmail", "displayName": "Gmail", "icon": "gmail.svg", "description": "Read and send emails via Gmail API", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/gmail.labels", "https://www.googleapis.com/auth/gmail.compose", "https://mail.google.com/"], "requiredApis": [{ "name": "Gmail API", "enableUrl": "https://console.cloud.google.com/apis/library/gmail.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_emails", "name": "List Emails", "description": "List email message IDs from inbox. Use get-email to fetch full content for each message.", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages", "params": { "maxResults": { "type": "number", "in": "query", "description": "Maximum number of messages to return (1-500)", "default": 20 }, "q": { "type": "string", "in": "query", "description": "Gmail search query (e.g. is:unread, from:user@example.com)" }, "labelIds": { "type": "string[]", "in": "query", "description": "Only return messages with these label IDs (e.g. INBOX, UNREAD)" }, "pageToken": { "type": "string", "in": "query", "description": "Page token for pagination" } }, "response": { "transform": "messages" } } }, { "id": "send_email", "name": "Send Email", "description": "Send an email to recipients", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/send", "body": { "raw": { "type": "string", "description": "Base64url-encoded RFC 2822 email message", "required": true }, "threadId": { "type": "string", "description": "Thread ID for a reply" } } } }, { "id": "get_email", "name": "Get Email", "description": "Get a specific email by ID with full content", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true }, "format": { "type": "string", "in": "query", "description": "Format: full, metadata, minimal, raw", "default": "full" } } } }, { "id": "search_emails", "name": "Search Emails", "description": "Search emails by query", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages", "params": { "q": { "type": "string", "in": "query", "description": "Gmail search query", "required": true }, "maxResults": { "type": "number", "in": "query", "description": "Maximum results", "default": 10 }, "pageToken": { "type": "string", "in": "query", "description": "Page token for pagination" } }, "response": { "transform": "messages" } } }, { "id": "mark_email_read", "name": "Mark Email Read", "description": "Mark an email as read", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/modify", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } }, "body": { "removeLabelIds": { "type": "array", "description": "Label IDs to remove, use UNREAD", "default": ["UNREAD"] } } } }, { "id": "archive_email", "name": "Archive Email", "description": "Archive an email", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/modify", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } }, "body": { "removeLabelIds": { "type": "array", "description": "Label IDs to remove, use INBOX", "default": ["INBOX"] } } } }, { "id": "list_labels", "name": "List Labels", "description": "List Gmail labels", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/labels", "response": { "transform": "labels" } } }, { "id": "get_label", "name": "Get Label", "description": "Get a Gmail label", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/labels/{labelId}", "params": { "labelId": { "type": "string", "in": "path", "description": "Label ID", "required": true } } } }, { "id": "create_label", "name": "Create Label", "description": "Create a Gmail user label", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/labels", "body": { "name": { "type": "string", "description": "Label display name", "required": true }, "messageListVisibility": { "type": "string", "description": "Message list visibility: show or hide" }, "labelListVisibility": { "type": "string", "description": "Label list visibility" }, "color": { "type": "object", "description": "Label color object" } } } }, { "id": "update_label", "name": "Update Label", "description": "Update a Gmail user label", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://gmail.googleapis.com/gmail/v1/users/me/labels/{labelId}", "params": { "labelId": { "type": "string", "in": "path", "description": "Label ID", "required": true } }, "body": { "name": { "type": "string", "description": "Label display name", "required": true }, "messageListVisibility": { "type": "string", "description": "Message list visibility: show or hide" }, "labelListVisibility": { "type": "string", "description": "Label list visibility" }, "color": { "type": "object", "description": "Label color object" } } } }, { "id": "delete_label", "name": "Delete Label", "description": "Delete a Gmail user label", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://gmail.googleapis.com/gmail/v1/users/me/labels/{labelId}", "params": { "labelId": { "type": "string", "in": "path", "description": "Label ID", "required": true } } } }, { "id": "apply_labels", "name": "Apply Labels", "description": "Apply or remove labels on an email", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/modify", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } }, "body": { "addLabelIds": { "type": "array", "description": "Label IDs to add" }, "removeLabelIds": { "type": "array", "description": "Label IDs to remove" } } } }, { "id": "modify_email_labels", "name": "Modify Email Labels", "description": "Modify labels on an email", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/modify", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } }, "body": { "addLabelIds": { "type": "array", "description": "Label IDs to add" }, "removeLabelIds": { "type": "array", "description": "Label IDs to remove" } } } }, { "id": "trash_email", "name": "Trash Email", "description": "Move an email to trash", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/trash", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } } } }, { "id": "untrash_email", "name": "Untrash Email", "description": "Remove an email from trash", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/untrash", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } } } }, { "id": "delete_email", "name": "Delete Email", "description": "Permanently delete an email", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true } } } }, { "id": "batch_modify_emails", "name": "Batch Modify Emails", "description": "Modify labels on multiple emails", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/batchModify", "body": { "ids": { "type": "array", "description": "Email message IDs", "required": true }, "addLabelIds": { "type": "array", "description": "Label IDs to add" }, "removeLabelIds": { "type": "array", "description": "Label IDs to remove" } } } }, { "id": "batch_delete_emails", "name": "Batch Delete Emails", "description": "Permanently delete multiple emails", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/batchDelete", "body": { "ids": { "type": "array", "description": "Email message IDs", "required": true } } } }, { "id": "list_threads", "name": "List Threads", "description": "List Gmail threads", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads", "params": { "maxResults": { "type": "number", "in": "query", "description": "Maximum number of threads to return (1-500)", "default": 20 }, "q": { "type": "string", "in": "query", "description": "Gmail search query" }, "labelIds": { "type": "string[]", "in": "query", "description": "Only return threads with these label IDs" }, "pageToken": { "type": "string", "in": "query", "description": "Page token for pagination" } }, "response": { "transform": "threads" } } }, { "id": "get_thread", "name": "Get Thread", "description": "Get a Gmail thread", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads/{threadId}", "params": { "threadId": { "type": "string", "in": "path", "description": "Thread ID", "required": true }, "format": { "type": "string", "in": "query", "description": "Format: full, metadata, minimal", "default": "full" } } } }, { "id": "modify_thread_labels", "name": "Modify Thread Labels", "description": "Modify labels on a Gmail thread", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads/{threadId}/modify", "params": { "threadId": { "type": "string", "in": "path", "description": "Thread ID", "required": true } }, "body": { "addLabelIds": { "type": "array", "description": "Label IDs to add" }, "removeLabelIds": { "type": "array", "description": "Label IDs to remove" } } } }, { "id": "trash_thread", "name": "Trash Thread", "description": "Move a Gmail thread to trash", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads/{threadId}/trash", "params": { "threadId": { "type": "string", "in": "path", "description": "Thread ID", "required": true } } } }, { "id": "untrash_thread", "name": "Untrash Thread", "description": "Remove a Gmail thread from trash", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads/{threadId}/untrash", "params": { "threadId": { "type": "string", "in": "path", "description": "Thread ID", "required": true } } } }, { "id": "delete_thread", "name": "Delete Thread", "description": "Permanently delete a Gmail thread", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://gmail.googleapis.com/gmail/v1/users/me/threads/{threadId}", "params": { "threadId": { "type": "string", "in": "path", "description": "Thread ID", "required": true } } } }, { "id": "create_draft", "name": "Create Draft", "description": "Create a Gmail draft", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts", "body": { "message": { "type": "object", "description": "Draft message containing raw RFC 2822 content", "required": true } } } }, { "id": "list_drafts", "name": "List Drafts", "description": "List Gmail drafts", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts", "params": { "maxResults": { "type": "number", "in": "query", "description": "Maximum number of drafts to return (1-500)", "default": 20 }, "q": { "type": "string", "in": "query", "description": "Gmail search query" }, "pageToken": { "type": "string", "in": "query", "description": "Page token for pagination" } }, "response": { "transform": "drafts" } } }, { "id": "get_draft", "name": "Get Draft", "description": "Get a Gmail draft", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts/{draftId}", "params": { "draftId": { "type": "string", "in": "path", "description": "Draft ID", "required": true }, "format": { "type": "string", "in": "query", "description": "Format: full, metadata, minimal, raw", "default": "full" } } } }, { "id": "update_draft", "name": "Update Draft", "description": "Replace a Gmail draft", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts/{draftId}", "params": { "draftId": { "type": "string", "in": "path", "description": "Draft ID", "required": true } }, "body": { "message": { "type": "object", "description": "Draft message containing raw RFC 2822 content", "required": true } } } }, { "id": "send_draft", "name": "Send Draft", "description": "Send an existing Gmail draft", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts/send", "body": { "id": { "type": "string", "description": "Draft ID", "required": true } } } }, { "id": "delete_draft", "name": "Delete Draft", "description": "Permanently delete a Gmail draft", "requiresWrite": true, "endpoint": { "method": "DELETE", "url": "https://gmail.googleapis.com/gmail/v1/users/me/drafts/{draftId}", "params": { "draftId": { "type": "string", "in": "path", "description": "Draft ID", "required": true } } } }, { "id": "get_attachment", "name": "Get Attachment", "description": "Get a Gmail message attachment", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}/attachments/{attachmentId}", "params": { "messageId": { "type": "string", "in": "path", "description": "Email message ID", "required": true }, "attachmentId": { "type": "string", "in": "path", "description": "Attachment ID", "required": true } } } }, { "id": "get_profile", "name": "Get Profile", "description": "Get the Gmail mailbox profile", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/profile" } }, { "id": "list_history", "name": "List History", "description": "List Gmail mailbox history changes", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://gmail.googleapis.com/gmail/v1/users/me/history", "params": { "startHistoryId": { "type": "string", "in": "query", "description": "History ID to start after", "required": true }, "maxResults": { "type": "number", "in": "query", "description": "Maximum history records", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Page token for pagination" }, "labelId": { "type": "string", "in": "query", "description": "Only return history for this label" }, "historyTypes": { "type": "string[]", "in": "query", "description": "History event types" } } } }], "prompts": [{ "id": "summarize_emails", "title": "Summarize today's emails", "prompt": "Summarize my unread emails from today. Group them by priority and highlight any that need immediate attention.", "category": "productivity", "icon": "mail" }, { "id": "draft_reply", "title": "Draft a quick reply", "prompt": "Help me draft a reply to my most recent email. Keep it professional and concise.", "category": "productivity", "icon": "reply" }, { "id": "find_emails", "title": "Find important emails", "prompt": "Search my emails for important messages from the past week that I might have missed.", "category": "productivity", "icon": "search" }], "suggestedWith": ["calendar", "slack"] },
|
|
17
16
|
{ "name": "hubspot", "displayName": "HubSpot", "icon": "hubspot.svg", "description": "Manage contacts, companies, and deals in your HubSpot CRM", "auth": { "type": "oauth2", "provider": "hubspot", "authorizationUrl": "https://app.hubspot.com/oauth/authorize", "tokenUrl": "https://api.hubapi.com/oauth/v1/token", "scopes": ["crm.objects.contacts.read", "crm.objects.contacts.write", "crm.objects.companies.read", "crm.objects.deals.read", "crm.objects.deals.write"], "tokenAuthMethod": "request_body", "requiredApis": [{ "name": "HubSpot App", "enableUrl": "https://app.hubspot.com/developer" }] }, "envVars": [{ "name": "HUBSPOT_CLIENT_ID", "description": "HubSpot OAuth Client ID (from your app)", "required": true, "sensitive": false, "docsUrl": "https://app.hubspot.com/developer" }, { "name": "HUBSPOT_CLIENT_SECRET", "description": "HubSpot OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://app.hubspot.com/developer" }], "tools": [{ "id": "list_contacts", "name": "List Contacts", "description": "List contacts from your HubSpot CRM", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.hubapi.com/crm/v3/objects/contacts", "params": { "limit": { "type": "number", "in": "query", "description": "Maximum number of contacts to return", "default": 100 }, "after": { "type": "string", "in": "query", "description": "Paging cursor from HubSpot" }, "properties": { "type": "string", "in": "query", "description": "Comma-separated contact properties to include" }, "archived": { "type": "boolean", "in": "query", "description": "Whether to include archived contacts", "default": false } }, "response": { "transform": "results" } } }, { "id": "get_contact", "name": "Get Contact", "description": "Get detailed information about a specific contact", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.hubapi.com/crm/v3/objects/contacts/{contactId}", "params": { "contactId": { "type": "string", "in": "path", "description": "HubSpot contact ID", "required": true }, "properties": { "type": "string", "in": "query", "description": "Comma-separated contact properties to include" }, "archived": { "type": "boolean", "in": "query", "description": "Whether to include archived contacts", "default": false } } } }, { "id": "create_contact", "name": "Create Contact", "description": "Create a new contact in HubSpot CRM", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.hubapi.com/crm/v3/objects/contacts", "body": { "properties": { "type": "object", "description": "Contact property values keyed by HubSpot property name", "required": true } } } }, { "id": "list_deals", "name": "List Deals", "description": "List sales deals from your HubSpot CRM", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.hubapi.com/crm/v3/objects/deals", "params": { "limit": { "type": "number", "in": "query", "description": "Maximum number of deals to return", "default": 100 }, "after": { "type": "string", "in": "query", "description": "Paging cursor from HubSpot" }, "properties": { "type": "string", "in": "query", "description": "Comma-separated deal properties to include" }, "archived": { "type": "boolean", "in": "query", "description": "Whether to include archived deals", "default": false } }, "response": { "transform": "results" } } }, { "id": "create_deal", "name": "Create Deal", "description": "Create a new deal in HubSpot CRM", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.hubapi.com/crm/v3/objects/deals", "body": { "properties": { "type": "object", "description": "Deal property values keyed by HubSpot property name", "required": true } } } }], "prompts": [{ "id": "find_contacts", "title": "Find contacts", "prompt": "Search for contacts in my HubSpot CRM and show me their key information.", "category": "crm", "icon": "search" }, { "id": "create_contact", "title": "Create a contact", "prompt": "Create a new contact in HubSpot CRM with the information I provide.", "category": "crm", "icon": "plus" }, { "id": "pipeline_summary", "title": "Pipeline summary", "prompt": "Show me a summary of my current sales deals and pipeline status.", "category": "crm", "icon": "chart" }], "suggestedWith": ["gmail", "slack", "calendar"] },
|
|
18
|
-
{ "name": "jira", "displayName": "Jira", "icon": "jira.svg", "description": "Search, create, and manage Jira issues and projects", "auth": { "type": "oauth2", "provider": "atlassian", "authorizationUrl": "https://auth.atlassian.com/authorize", "tokenUrl": "https://auth.atlassian.com/oauth/token", "scopes": ["read:jira-work", "write:jira-work", "read:jira-user", "offline_access"], "tokenAuthMethod": "body", "requiredApis": [{ "name": "Atlassian OAuth 2.0", "enableUrl": "https://developer.atlassian.com/console/myapps/" }], "additionalAuthParams": { "audience": "api.atlassian.com", "prompt": "consent" } }, "envVars": [{ "name": "ATLASSIAN_CLIENT_ID", "description": "Atlassian OAuth 2.0 Client ID (from your app)", "required": true, "sensitive": false, "docsUrl": "https://developer.atlassian.com/console/myapps/" }, { "name": "ATLASSIAN_CLIENT_SECRET", "description": "Atlassian OAuth 2.0 Client Secret", "required": true, "sensitive": true, "docsUrl": "https://developer.atlassian.com/console/myapps/" }], "tools": [{ "id": "list_sites", "name": "List Atlassian Sites", "description": "List Atlassian cloud sites/resources the OAuth token can access; use the returned id as cloudId for Jira and Confluence tools", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/oauth/token/accessible-resources", "response": { "transform": "" } } }, { "id": "list_projects", "name": "List Projects", "description": "List all accessible Jira projects", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/project/search", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "query": { "type": "string", "in": "query", "description": "Search text for project name or key" }, "maxResults": { "type": "number", "in": "query", "description": "Maximum projects to return", "default": 50 }, "startAt": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 } }, "response": { "transform": "values" } } }, { "id": "get_project", "name": "Get Project", "description": "Get detailed information about a Jira project", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/project/{projectIdOrKey}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "projectIdOrKey": { "type": "string", "in": "path", "description": "Jira project ID or key", "required": true } } } }, { "id": "search_issues", "name": "Search Issues", "description": "Search Jira issues using JQL (Jira Query Language)", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/search
|
|
17
|
+
{ "name": "jira", "displayName": "Jira", "icon": "jira.svg", "description": "Search, create, and manage Jira issues and projects", "auth": { "type": "oauth2", "provider": "atlassian", "authorizationUrl": "https://auth.atlassian.com/authorize", "tokenUrl": "https://auth.atlassian.com/oauth/token", "scopes": ["read:jira-work", "write:jira-work", "read:jira-user", "offline_access"], "tokenAuthMethod": "body", "requiredApis": [{ "name": "Atlassian OAuth 2.0", "enableUrl": "https://developer.atlassian.com/console/myapps/" }], "additionalAuthParams": { "audience": "api.atlassian.com", "prompt": "consent" } }, "envVars": [{ "name": "ATLASSIAN_CLIENT_ID", "description": "Atlassian OAuth 2.0 Client ID (from your app)", "required": true, "sensitive": false, "docsUrl": "https://developer.atlassian.com/console/myapps/" }, { "name": "ATLASSIAN_CLIENT_SECRET", "description": "Atlassian OAuth 2.0 Client Secret", "required": true, "sensitive": true, "docsUrl": "https://developer.atlassian.com/console/myapps/" }], "tools": [{ "id": "list_sites", "name": "List Atlassian Sites", "description": "List Atlassian cloud sites/resources the OAuth token can access; use the returned id as cloudId for Jira and Confluence tools", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/oauth/token/accessible-resources", "response": { "transform": "" } } }, { "id": "list_projects", "name": "List Projects", "description": "List all accessible Jira projects", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/project/search", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "query": { "type": "string", "in": "query", "description": "Search text for project name or key" }, "maxResults": { "type": "number", "in": "query", "description": "Maximum projects to return", "default": 50 }, "startAt": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 } }, "response": { "transform": "values" } } }, { "id": "get_project", "name": "Get Project", "description": "Get detailed information about a Jira project", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/project/{projectIdOrKey}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "projectIdOrKey": { "type": "string", "in": "path", "description": "Jira project ID or key", "required": true } } } }, { "id": "search_issues", "name": "Search Issues", "description": "Search Jira issues using JQL (Jira Query Language)", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/search", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "jql": { "type": "string", "in": "query", "description": "Jira Query Language search expression", "required": true }, "maxResults": { "type": "number", "in": "query", "description": "Maximum issues to return", "default": 50 }, "startAt": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 }, "fields": { "type": "array", "in": "query", "description": "Issue fields to include" } }, "response": { "transform": "issues" } } }, { "id": "get_issue", "name": "Get Issue", "description": "Get detailed information about a specific Jira issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true }, "fields": { "type": "string", "in": "query", "description": "Comma-separated issue fields to include" } } } }, { "id": "create_issue", "name": "Create Issue", "description": "Create a new Jira issue in a project", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true } }, "body": { "fields": { "type": "object", "description": "Jira issue fields including project, issuetype, summary, and description", "required": true } } } }, { "id": "update_issue", "name": "Update Issue", "description": "Update an existing Jira issue (status, fields, etc.)", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from accessible-resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true } }, "body": { "fields": { "type": "object", "description": "Jira fields to set" }, "update": { "type": "object", "description": "Jira update operations" } } } }, { "id": "list_comments", "name": "List Comments", "description": "List comments on a Jira issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/comment", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true }, "startAt": { "type": "number", "in": "query", "description": "Pagination offset", "default": 0 }, "maxResults": { "type": "number", "in": "query", "description": "Maximum comments to return", "default": 50 } } } }, { "id": "add_comment", "name": "Add Comment", "description": "Add a comment to a Jira issue", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/comment", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true } }, "body": { "body": { "type": "object", "description": "Comment body in Atlassian Document Format", "required": true } } } }, { "id": "get_transitions", "name": "Get Transitions", "description": "List available workflow transitions for a Jira issue", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/transitions", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true } } } }, { "id": "transition_issue", "name": "Transition Issue", "description": "Move a Jira issue to a new workflow status. First call get_transitions to get valid transition IDs, then pass the ID here.", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/transitions", "params": { "cloudId": { "type": "string", "in": "path", "description": "Atlassian cloud ID from OAuth accessible resources", "required": true }, "issueIdOrKey": { "type": "string", "in": "path", "description": "Jira issue ID or key", "required": true } }, "body": { "transition": { "type": "object", "description": "Transition object with id field, e.g. {\"id\": \"21\"}", "required": true }, "fields": { "type": "object", "description": "Optional field updates to apply during the transition" }, "comment": { "type": "object", "description": "Optional comment in Atlassian Document Format to add with the transition" } } } }], "prompts": [{ "id": "find_bugs", "title": "Find open bugs", "prompt": "Search for all open bugs assigned to me or in my current sprint.", "category": "productivity", "icon": "bug" }, { "id": "create_task", "title": "Create a task", "prompt": "Create a new task in Jira with a title, description, and priority.", "category": "productivity", "icon": "plus" }, { "id": "sprint_summary", "title": "Sprint summary", "prompt": "Get a summary of all issues in the current sprint, organized by status.", "category": "productivity", "icon": "list" }, { "id": "update_status", "title": "Update issue status", "prompt": "Move an issue to a different status (To Do, In Progress, Done, etc.).", "category": "productivity", "icon": "check" }], "suggestedWith": ["github", "slack", "confluence"] },
|
|
19
18
|
{ "name": "linear", "displayName": "Linear", "icon": "linear.svg", "description": "Search, create, and manage Linear issues and projects", "auth": { "type": "oauth2", "provider": "linear", "authorizationUrl": "https://linear.app/oauth/authorize", "tokenUrl": "https://api.linear.app/oauth/token", "scopes": ["read", "write"], "tokenAuthMethod": "basic", "requiredApis": [{ "name": "Linear OAuth Application", "enableUrl": "https://linear.app/settings/api" }] }, "envVars": [{ "name": "LINEAR_CLIENT_ID", "description": "Linear OAuth Client ID (from your OAuth application)", "required": true, "sensitive": false, "docsUrl": "https://linear.app/settings/api" }, { "name": "LINEAR_CLIENT_SECRET", "description": "Linear OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://linear.app/settings/api" }], "tools": [{ "id": "search_issues", "name": "Search Issues", "description": "Search for Linear issues by title or description", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($query: String!, $first: Int) { issueSearch(query: $query, first: $first) { nodes { id identifier title description state { name } assignee { name } priority priorityLabel createdAt updatedAt } } }", "params": { "query": { "type": "string", "in": "body", "description": "Search query text", "required": true }, "first": { "type": "number", "in": "body", "description": "Max results", "default": 20 } }, "response": { "transform": "issueSearch" } } }, { "id": "get_issue", "name": "Get Issue", "description": "Get detailed information about a specific Linear issue", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($id: String!) { issue(id: $id) { id identifier title description state { name } assignee { name email } priority priorityLabel team { name } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } createdAt updatedAt } }", "params": { "id": { "type": "string", "in": "body", "description": "Issue ID or identifier (e.g. ENG-123)", "required": true } }, "response": { "transform": "issue" } } }, { "id": "create_issue", "name": "Create Issue", "description": "Create a new Linear issue in a team", "requiresWrite": true, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "mutation($teamId: String!, $title: String!, $description: String, $priority: Int) { issueCreate(input: { teamId: $teamId, title: $title, description: $description, priority: $priority }) { success issue { id identifier title url } } }", "params": { "teamId": { "type": "string", "in": "body", "description": "Team ID", "required": true }, "title": { "type": "string", "in": "body", "description": "Issue title", "required": true }, "description": { "type": "string", "in": "body", "description": "Issue description (markdown)" }, "priority": { "type": "number", "in": "body", "description": "Priority (0=none, 1=urgent, 2=high, 3=medium, 4=low)" } }, "response": { "transform": "issueCreate" } } }, { "id": "update_issue", "name": "Update Issue", "description": "Update the status, assignee, or other properties of an issue", "requiresWrite": true, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "mutation($id: String!, $stateId: String, $assigneeId: String, $priority: Int) { issueUpdate(id: $id, input: { stateId: $stateId, assigneeId: $assigneeId, priority: $priority }) { success issue { id identifier title state { name } assignee { name } } } }", "params": { "id": { "type": "string", "in": "body", "description": "Issue ID", "required": true }, "stateId": { "type": "string", "in": "body", "description": "New state ID" }, "assigneeId": { "type": "string", "in": "body", "description": "New assignee user ID" }, "priority": { "type": "number", "in": "body", "description": "New priority" } }, "response": { "transform": "issueUpdate" } } }, { "id": "list_projects", "name": "List Projects", "description": "List all projects in the workspace", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($first: Int) { projects(first: $first) { nodes { id name description state startDate targetDate lead { name } teams { nodes { name } } } } }", "params": { "first": { "type": "number", "in": "body", "description": "Max results", "default": 50 } }, "response": { "transform": "projects" } } }, { "id": "list_teams", "name": "List Teams", "description": "List Linear teams in the workspace so issues can be created in the right team", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($first: Int) { teams(first: $first) { nodes { id name key description private issueCount createdAt updatedAt } } }", "params": { "first": { "type": "number", "in": "body", "description": "Max results", "default": 50 } }, "response": { "transform": "teams" } } }, { "id": "list_workflow_states", "name": "List Workflow States", "description": "List workflow states for a Linear team so issues can be moved to the right status", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($teamId: String!) { team(id: $teamId) { id name states { nodes { id name type color position } } } }", "params": { "teamId": { "type": "string", "in": "body", "description": "Team ID", "required": true } }, "response": { "transform": "team.states" } } }, { "id": "list_users", "name": "List Users", "description": "List Linear users in the workspace so issues can be assigned to the right person", "requiresWrite": false, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "query($first: Int) { users(first: $first) { nodes { id name displayName email active avatarUrl } } }", "params": { "first": { "type": "number", "in": "body", "description": "Max results", "default": 50 } }, "response": { "transform": "users" } } }, { "id": "add_comment", "name": "Add Comment", "description": "Add a comment to a Linear issue", "requiresWrite": true, "endpoint": { "type": "graphql", "method": "POST", "url": "https://api.linear.app/graphql", "query": "mutation($issueId: String!, $body: String!) { commentCreate(input: { issueId: $issueId, body: $body }) { success comment { id body createdAt user { id name } issue { id identifier title } } } }", "params": { "issueId": { "type": "string", "in": "body", "description": "Issue ID", "required": true }, "body": { "type": "string", "in": "body", "description": "Comment body in markdown", "required": true } }, "response": { "transform": "commentCreate" } } }], "prompts": [{ "id": "find_issues", "title": "Find my issues", "prompt": "Search for Linear issues assigned to me or related to a specific topic.", "category": "productivity", "icon": "search" }, { "id": "create_bug_report", "title": "Create bug report", "prompt": "Create a new bug report in Linear with title, description, and relevant labels.", "category": "productivity", "icon": "plus" }, { "id": "update_issue_status", "title": "Update issue status", "prompt": "Update the status of a Linear issue (e.g., mark as done, in progress, blocked).", "category": "productivity", "icon": "check" }, { "id": "project_overview", "title": "Project overview", "prompt": "Get an overview of all projects in Linear, including their status and key issues.", "category": "productivity", "icon": "list" }], "suggestedWith": ["github", "slack", "figma"] },
|
|
20
19
|
{ "name": "mixpanel", "displayName": "Mixpanel", "icon": "mixpanel.svg", "description": "Track events, analyze funnels, and understand user behavior with Mixpanel analytics", "auth": { "type": "api-key", "requiredApis": [{ "name": "Mixpanel API", "enableUrl": "https://mixpanel.com/settings/project" }], "keyName": "MIXPANEL_PROJECT_TOKEN" }, "envVars": [{ "name": "MIXPANEL_PROJECT_TOKEN", "description": "Mixpanel Project Token for event tracking", "required": true, "sensitive": true, "docsUrl": "https://docs.mixpanel.com/docs/tracking-methods/id-management/authentication" }, { "name": "MIXPANEL_API_SECRET", "description": "Mixpanel API Secret for data export and query operations", "required": true, "sensitive": true, "docsUrl": "https://developer.mixpanel.com/reference/authentication" }, { "name": "MIXPANEL_PROJECT_ID", "description": "Mixpanel Project ID (found in project settings)", "required": true, "sensitive": false, "docsUrl": "https://docs.mixpanel.com/docs/admin/organizations-projects/manage-projects" }], "tools": [{ "id": "track_event", "name": "Track Event", "description": "Track a custom event in Mixpanel with properties", "requiresWrite": true }, { "id": "query_events", "name": "Query Events", "description": "Query and export event data from Mixpanel", "requiresWrite": false }, { "id": "get_funnel", "name": "Get Funnel", "description": "Retrieve funnel analysis data to understand conversion rates", "requiresWrite": false }, { "id": "get_retention", "name": "Get Retention", "description": "Analyze user retention cohorts over time", "requiresWrite": false }, { "id": "list_cohorts", "name": "List Cohorts", "description": "List all user cohorts defined in your Mixpanel project", "requiresWrite": false }], "prompts": [{ "id": "event_analysis", "title": "Event analysis", "prompt": "Show me the most important events tracked in my Mixpanel project over the last 7 days and their trends.", "category": "analytics", "icon": "chart" }, { "id": "funnel_performance", "title": "Funnel performance", "prompt": "Analyze my key conversion funnels and identify where users are dropping off.", "category": "analytics", "icon": "funnel" }, { "id": "retention_insights", "title": "Retention insights", "prompt": "Give me insights about user retention and cohort behavior over the past month.", "category": "analytics", "icon": "users" }], "suggestedWith": ["slack", "analytics", "monitoring"] },
|
|
21
20
|
{ "name": "neon", "displayName": "Neon", "icon": "neon.svg", "description": "Manage Neon Postgres projects, branches, and execute database queries", "auth": { "type": "api-key", "requiredApis": [{ "name": "Neon Management API", "enableUrl": "https://console.neon.tech/app/settings/api-keys" }], "tokenName": "API Key", "docsUrl": "https://neon.tech/docs/manage/api-keys" }, "envVars": [{ "name": "NEON_API_KEY", "description": "Neon API Key for Management API access", "required": true, "sensitive": true, "docsUrl": "https://neon.tech/docs/manage/api-keys" }, { "name": "DATABASE_URL", "description": "PostgreSQL connection string for database queries", "required": true, "sensitive": true, "docsUrl": "https://neon.tech/docs/connect/connect-from-any-app" }], "npmDependencies": { "pg": "^8.13.1" }, "tools": [{ "id": "list_projects", "name": "List Projects", "description": "List all Neon projects in your account", "requiresWrite": false }, { "id": "list_branches", "name": "List Branches", "description": "List all branches for a specific project", "requiresWrite": false }, { "id": "query_database", "name": "Query Database", "description": "Execute SQL queries against the connected database", "requiresWrite": false }, { "id": "list_tables", "name": "List Tables", "description": "List all tables in the connected database", "requiresWrite": false }, { "id": "describe_table", "name": "Describe Table", "description": "Get detailed schema information for a specific table", "requiresWrite": false }], "prompts": [{ "id": "check_db_status", "title": "Check database status", "prompt": "Show me the status of my Neon projects and their branches.", "category": "database", "icon": "database" }, { "id": "explore_schema", "title": "Explore database schema", "prompt": "List all tables in my database and show me the schema for the main tables.", "category": "database", "icon": "table" }, { "id": "query_data", "title": "Query database", "prompt": "Help me query my database to find specific data.", "category": "database", "icon": "search" }], "suggestedWith": ["stripe", "clerk", "vercel"] },
|
|
@@ -29,7 +28,7 @@ export const connectors = [
|
|
|
29
28
|
{ "name": "sharepoint", "displayName": "SharePoint", "icon": "sharepoint.svg", "description": "Access and manage SharePoint sites, document libraries, and files", "auth": { "type": "oauth2", "provider": "microsoft", "authorizationUrl": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", "tokenUrl": "https://login.microsoftonline.com/common/oauth2/v2.0/token", "scopes": ["Sites.Read.All", "Sites.ReadWrite.All", "Files.Read.All", "Files.ReadWrite.All", "offline_access"], "tokenAuthMethod": "body", "requiredApis": [{ "name": "Microsoft Graph API", "enableUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade" }] }, "envVars": [{ "name": "MICROSOFT_CLIENT_ID", "description": "Microsoft Azure App Client ID (shared with Outlook/Teams)", "required": true, "sensitive": false, "docsUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade" }, { "name": "MICROSOFT_CLIENT_SECRET", "description": "Microsoft Azure App Client Secret", "required": true, "sensitive": true, "docsUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade" }], "tools": [{ "id": "list_sites", "name": "List SharePoint Sites", "description": "List all SharePoint sites the user has access to", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://graph.microsoft.com/v1.0/sites", "params": { "search": { "type": "string", "in": "query", "description": "Search term for SharePoint sites", "default": "*" }, "$top": { "type": "number", "in": "query", "description": "Maximum number of sites to return", "default": 200 } }, "response": { "transform": "value" } } }, { "id": "get_site", "name": "Get Site Details", "description": "Get detailed information about a specific SharePoint site", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://graph.microsoft.com/v1.0/sites/{siteId}", "params": { "siteId": { "type": "string", "in": "path", "description": "SharePoint site ID", "required": true } } } }, { "id": "list_files", "name": "List Files", "description": "List files and folders in a SharePoint document library", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://graph.microsoft.com/v1.0/sites/{siteId}/drive/root/children", "params": { "siteId": { "type": "string", "in": "path", "description": "SharePoint site ID", "required": true }, "$top": { "type": "number", "in": "query", "description": "Maximum number of items to return", "default": 200 } } } }, { "id": "get_file", "name": "Get File", "description": "Get file metadata and content from SharePoint", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://graph.microsoft.com/v1.0/sites/{siteId}/drive/items/{itemId}", "params": { "siteId": { "type": "string", "in": "path", "description": "SharePoint site ID", "required": true }, "itemId": { "type": "string", "in": "path", "description": "Drive item ID", "required": true } } } }, { "id": "upload_file", "name": "Upload File", "description": "Upload a file to a SharePoint document library", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://graph.microsoft.com/v1.0/sites/{siteId}/drive/items/{parentFolderId}:/{fileName}:/content", "params": { "siteId": { "type": "string", "in": "path", "description": "SharePoint site ID", "required": true }, "parentFolderId": { "type": "string", "in": "path", "description": "Parent folder item ID, or root", "default": "root" }, "fileName": { "type": "string", "in": "path", "description": "Name of the file to upload", "required": true } }, "body": { "content": { "type": "string", "description": "File content to upload", "required": true } }, "contentType": "application/octet-stream" } }], "prompts": [{ "id": "search_documents", "title": "Search documents", "prompt": "Search for documents in SharePoint sites and summarize their content.", "category": "productivity", "icon": "search" }, { "id": "list_recent_files", "title": "List recent files", "prompt": "Show me the most recently modified files across all SharePoint sites I have access to.", "category": "productivity", "icon": "document" }, { "id": "organize_documents", "title": "Organize documents", "prompt": "Help me organize and categorize documents in a SharePoint library.", "category": "productivity", "icon": "folder" }], "suggestedWith": ["outlook", "teams", "onedrive"] },
|
|
30
29
|
{ "name": "sheets", "displayName": "Google Sheets", "icon": "sheets.svg", "description": "Read, write, and manage Google Sheets spreadsheets", "auth": { "type": "oauth2", "provider": "google", "authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "scopes": ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/drive.file"], "requiredApis": [{ "name": "Google Sheets API", "enableUrl": "https://console.cloud.google.com/apis/library/sheets.googleapis.com" }, { "name": "Google Drive API", "enableUrl": "https://console.cloud.google.com/apis/library/drive.googleapis.com" }] }, "envVars": [{ "name": "GOOGLE_CLIENT_ID", "description": "Google OAuth Client ID", "required": true, "sensitive": false, "docsUrl": "https://console.cloud.google.com/apis/credentials" }, { "name": "GOOGLE_CLIENT_SECRET", "description": "Google OAuth Client Secret", "required": true, "sensitive": true, "docsUrl": "https://console.cloud.google.com/apis/credentials" }], "tools": [{ "id": "list_spreadsheets", "name": "List Spreadsheets", "description": "List recent Google Sheets spreadsheets from Drive", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://www.googleapis.com/drive/v3/files", "params": { "q": { "type": "string", "in": "query", "description": "Drive query limited to Google Sheets spreadsheets", "default": "mimeType='application/vnd.google-apps.spreadsheet' and trashed=false" }, "pageSize": { "type": "number", "in": "query", "description": "Maximum number of spreadsheets to return", "default": 100 }, "pageToken": { "type": "string", "in": "query", "description": "Pagination token" }, "fields": { "type": "string", "in": "query", "description": "Partial response field selector", "default": "nextPageToken, files(id, name, webViewLink, modifiedTime)" } }, "response": { "transform": "files" } } }, { "id": "get_spreadsheet", "name": "Get Spreadsheet", "description": "Get spreadsheet metadata including sheet names and properties", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true }, "includeGridData": { "type": "boolean", "in": "query", "description": "Whether to include grid data", "default": false }, "ranges": { "type": "string[]", "in": "query", "description": "Ranges to include when includeGridData is true" } } } }, { "id": "read_range", "name": "Read Range", "description": "Read cell data from a spreadsheet range", "requiresWrite": false, "endpoint": { "method": "GET", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true }, "range": { "type": "string", "in": "path", "description": "A1 notation range to read", "required": true }, "majorDimension": { "type": "string", "in": "query", "description": "Major dimension for returned values" }, "valueRenderOption": { "type": "string", "in": "query", "description": "How values should be rendered" } } } }, { "id": "write_range", "name": "Write Range", "description": "Write data to a spreadsheet range", "requiresWrite": true, "endpoint": { "method": "PUT", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true }, "range": { "type": "string", "in": "path", "description": "A1 notation range to write", "required": true }, "valueInputOption": { "type": "string", "in": "query", "description": "How input values should be interpreted", "default": "USER_ENTERED" }, "includeValuesInResponse": { "type": "boolean", "in": "query", "description": "Whether the response should include written values", "default": false } }, "body": { "values": { "type": "array", "description": "2D array of row values to write", "required": true }, "majorDimension": { "type": "string", "description": "Major dimension of provided values", "default": "ROWS" } } } }, { "id": "create_spreadsheet", "name": "Create Spreadsheet", "description": "Create a new spreadsheet with optional initial data", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets", "body": { "properties": { "type": "object", "description": "Spreadsheet properties such as title", "required": true }, "sheets": { "type": "array", "description": "Optional initial sheet definitions" } } } }, { "id": "append_rows", "name": "Append Rows", "description": "Append rows to a spreadsheet range", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:append", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true }, "range": { "type": "string", "in": "path", "description": "A1 notation range/table to append to", "required": true }, "valueInputOption": { "type": "string", "in": "query", "description": "How input values should be interpreted", "default": "USER_ENTERED" }, "insertDataOption": { "type": "string", "in": "query", "description": "How inserted data should be handled", "default": "INSERT_ROWS" }, "includeValuesInResponse": { "type": "boolean", "in": "query", "description": "Whether the response should include appended values", "default": false } }, "body": { "values": { "type": "array", "description": "2D array of row values to append", "required": true }, "majorDimension": { "type": "string", "description": "Major dimension of provided values", "default": "ROWS" } } } }, { "id": "clear_range", "name": "Clear Range", "description": "Clear values from a spreadsheet range", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:clear", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true }, "range": { "type": "string", "in": "path", "description": "A1 notation range to clear", "required": true } }, "body": {} } }, { "id": "batch_update", "name": "Batch Update", "description": "Run raw Google Sheets batchUpdate requests for formatting and structural changes", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "Google Sheets API batchUpdate request objects", "required": true }, "includeSpreadsheetInResponse": { "type": "boolean", "description": "Whether to include the updated spreadsheet in the response" } } } }, { "id": "add_sheet", "name": "Add Sheet", "description": "Add a new sheet/tab to a spreadsheet", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing an addSheet request", "required": true } } } }, { "id": "delete_sheet", "name": "Delete Sheet", "description": "Delete a sheet/tab from a spreadsheet by sheet ID", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing a deleteSheet request", "required": true } } } }, { "id": "rename_sheet", "name": "Rename Sheet", "description": "Rename a sheet/tab by sheet ID", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing an updateSheetProperties request", "required": true } } } }, { "id": "delete_spreadsheet", "name": "Delete Spreadsheet", "description": "Move an app-accessible spreadsheet file to trash", "requiresWrite": true, "endpoint": { "method": "PATCH", "url": "https://www.googleapis.com/drive/v3/files/{spreadsheetId}", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID / Drive file ID", "required": true } }, "body": { "trashed": { "type": "boolean", "description": "Whether to move the spreadsheet file to trash", "default": true } } } }, { "id": "find_replace", "name": "Find and Replace", "description": "Find and replace text in a spreadsheet or sheet", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing a findReplace request", "required": true } } } }, { "id": "copy_sheet", "name": "Copy Sheet", "description": "Copy a sheet/tab to another spreadsheet", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/sheets/{sheetId}:copyTo", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Source spreadsheet ID", "required": true }, "sheetId": { "type": "number", "in": "path", "description": "Source sheet ID", "required": true } }, "body": { "destinationSpreadsheetId": { "type": "string", "description": "Destination spreadsheet ID", "required": true } } } }, { "id": "create_chart", "name": "Create Chart", "description": "Create an embedded chart using a Sheets API chart specification", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing an addChart request", "required": true } } } }, { "id": "set_data_validation", "name": "Set Data Validation", "description": "Set data validation rules on a sheet range", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate", "params": { "spreadsheetId": { "type": "string", "in": "path", "description": "Google Sheets spreadsheet ID", "required": true } }, "body": { "requests": { "type": "array", "description": "A batchUpdate requests array containing a setDataValidation request", "required": true } } } }], "prompts": [{ "id": "analyze_data", "title": "Analyze spreadsheet data", "prompt": "Read and analyze data from a Google Sheets spreadsheet. Provide insights, trends, and statistics.", "category": "productivity", "icon": "chart" }, { "id": "create_report", "title": "Create a report spreadsheet", "prompt": "Create a new Google Sheets spreadsheet with formatted data, headers, and calculations.", "category": "productivity", "icon": "plus" }, { "id": "update_tracker", "title": "Update a tracker", "prompt": "Update a tracking spreadsheet with new data. Add rows, update values, or calculate totals.", "category": "productivity", "icon": "edit" }], "suggestedWith": ["gmail", "calendar", "notion"] },
|
|
31
30
|
{ "name": "shopify", "displayName": "Shopify", "icon": "shopify.svg", "description": "Manage products, orders, and customers in your Shopify store", "auth": { "type": "oauth2", "provider": "shopify", "authorizationUrl": "https://shop.myshopify.com/admin/oauth/authorize", "tokenUrl": "https://shop.myshopify.com/admin/oauth/access_token", "scopes": ["read_products", "write_products", "read_orders"], "requiredApis": [{ "name": "Shopify Admin API", "enableUrl": "https://partners.shopify.com" }] }, "envVars": [{ "name": "SHOPIFY_CLIENT_ID", "description": "Shopify OAuth Client ID (API Key)", "required": true, "sensitive": false, "docsUrl": "https://shopify.dev/docs/apps/auth/oauth" }, { "name": "SHOPIFY_CLIENT_SECRET", "description": "Shopify OAuth Client Secret (API Secret Key)", "required": true, "sensitive": true, "docsUrl": "https://shopify.dev/docs/apps/auth/oauth" }, { "name": "SHOPIFY_SHOP_DOMAIN", "description": "Your Shopify store domain (e.g., mystore.myshopify.com)", "required": true, "sensitive": false, "docsUrl": "https://shopify.dev/docs/apps/auth/oauth" }], "tools": [{ "id": "list_products", "name": "List Products", "description": "List products in your Shopify store", "requiresWrite": false }, { "id": "get_product", "name": "Get Product", "description": "Get details of a specific product", "requiresWrite": false }, { "id": "list_orders", "name": "List Orders", "description": "List orders from your Shopify store", "requiresWrite": false }, { "id": "get_order", "name": "Get Order", "description": "Get details of a specific order", "requiresWrite": false }, { "id": "list_customers", "name": "List Customers", "description": "List customers in your Shopify store", "requiresWrite": false }], "prompts": [{ "id": "list_products", "title": "Show my products", "prompt": "List all products in my Shopify store with their prices and inventory levels.", "category": "ecommerce", "icon": "shopping-bag" }, { "id": "recent_orders", "title": "Show recent orders", "prompt": "Show me the most recent orders from my Shopify store with customer details and order totals.", "category": "ecommerce", "icon": "receipt" }, { "id": "customer_list", "title": "Show my customers", "prompt": "List all customers in my Shopify store with their contact information and order history.", "category": "ecommerce", "icon": "users" }], "suggestedWith": ["stripe", "analytics"] },
|
|
32
|
-
{ "name": "slack", "displayName": "Slack", "icon": "slack.svg", "description": "Send messages, read channels, and manage Slack workspace", "auth": { "type": "oauth2", "provider": "slack", "authorizationUrl": "https://slack.com/oauth/v2/authorize", "tokenUrl": "https://slack.com/api/oauth.v2.access", "scopes": ["channels:history", "channels:read", "chat:write", "groups:history", "groups:read", "im:history", "im:read", "mpim:history", "mpim:read", "users:read"] }, "envVars": [{ "name": "SLACK_CLIENT_ID", "description": "Slack App Client ID", "required": true, "sensitive": false, "docsUrl": "https://api.slack.com/apps" }, { "name": "SLACK_CLIENT_SECRET", "description": "Slack App Client Secret", "required": true, "sensitive": true, "docsUrl": "https://api.slack.com/apps" }], "tools": [{ "id": "list_channels", "name": "List Channels", "description": "Get list of Slack channels", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/conversations.list", "body": { "limit": { "type": "number", "description": "Max channels (1-1000)", "default": 100 }, "exclude_archived": { "type": "boolean", "description": "Exclude archived channels", "default": true }, "types": { "type": "string", "description": "Channel types: public_channel, private_channel, mpim, im", "default": "public_channel" } }, "response": { "transform": "channels" } } }, { "id": "send_message", "name": "Send Message", "description": "Send a message to a Slack channel", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://slack.com/api/chat.postMessage", "body": { "channel": { "type": "string", "description": "Channel ID to send to", "required": true }, "text": { "type": "string", "description": "Message text (supports mrkdwn)", "required": true }, "thread_ts": { "type": "string", "description": "Thread timestamp to reply to" }, "unfurl_links": { "type": "boolean", "description": "Unfurl URLs" } } } }, { "id": "get_messages", "name": "Get Messages", "description": "Get recent messages from a channel", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/conversations.history", "body": { "channel": { "type": "string", "description": "Channel ID", "required": true }, "limit": { "type": "number", "description": "Max messages (1-1000)", "default": 20 }, "oldest": { "type": "string", "description": "Only messages after this timestamp" } }, "response": { "transform": "messages" } } }], "prompts": [{ "id": "catch_up_slack", "title": "Catch up on Slack", "prompt": "Summarize the important messages from my Slack channels from today. Highlight any mentions or urgent items.", "category": "productivity", "icon": "slack" }, { "id": "post_update", "title": "Post team update", "prompt": "Help me write and post a team update to Slack about my current work progress.", "category": "productivity", "icon": "message" }], "suggestedWith": ["gmail", "calendar", "jira"] },
|
|
31
|
+
{ "name": "slack", "displayName": "Slack", "icon": "slack.svg", "description": "Send messages, read channels, and manage Slack workspace", "auth": { "type": "oauth2", "provider": "slack", "authorizationUrl": "https://slack.com/oauth/v2/authorize", "tokenUrl": "https://slack.com/api/oauth.v2.access", "scopes": ["channels:history", "channels:read", "chat:write", "groups:history", "groups:read", "im:history", "im:read", "mpim:history", "mpim:read", "users:read"] }, "envVars": [{ "name": "SLACK_CLIENT_ID", "description": "Slack App Client ID", "required": true, "sensitive": false, "docsUrl": "https://api.slack.com/apps" }, { "name": "SLACK_CLIENT_SECRET", "description": "Slack App Client Secret", "required": true, "sensitive": true, "docsUrl": "https://api.slack.com/apps" }], "tools": [{ "id": "list_channels", "name": "List Channels", "description": "Get list of Slack channels", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/conversations.list", "body": { "limit": { "type": "number", "description": "Max channels (1-1000)", "default": 100 }, "exclude_archived": { "type": "boolean", "description": "Exclude archived channels", "default": true }, "types": { "type": "string", "description": "Channel types: public_channel, private_channel, mpim, im", "default": "public_channel" } }, "response": { "transform": "channels" } } }, { "id": "send_message", "name": "Send Message", "description": "Send a message to a Slack channel", "requiresWrite": true, "endpoint": { "method": "POST", "url": "https://slack.com/api/chat.postMessage", "body": { "channel": { "type": "string", "description": "Channel ID to send to", "required": true }, "text": { "type": "string", "description": "Message text (supports mrkdwn)", "required": true }, "thread_ts": { "type": "string", "description": "Thread timestamp to reply to" }, "unfurl_links": { "type": "boolean", "description": "Unfurl URLs" } } } }, { "id": "get_messages", "name": "Get Messages", "description": "Get recent messages from a channel", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/conversations.history", "body": { "channel": { "type": "string", "description": "Channel ID", "required": true }, "limit": { "type": "number", "description": "Max messages (1-1000)", "default": 20 }, "oldest": { "type": "string", "description": "Only messages after this timestamp" } }, "response": { "transform": "messages" } } }, { "id": "get_thread", "name": "Get Thread", "description": "Get all replies in a Slack message thread", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/conversations.replies", "body": { "channel": { "type": "string", "description": "Channel ID containing the thread", "required": true }, "ts": { "type": "string", "description": "Timestamp (ts) of the parent message", "required": true }, "limit": { "type": "number", "description": "Max replies (1-1000)", "default": 20 } }, "response": { "transform": "messages" } } }, { "id": "list_users", "name": "List Users", "description": "List members of the Slack workspace", "requiresWrite": false, "endpoint": { "method": "POST", "url": "https://slack.com/api/users.list", "body": { "limit": { "type": "number", "description": "Max users (1-1000)", "default": 100 } }, "response": { "transform": "members" } } }], "prompts": [{ "id": "catch_up_slack", "title": "Catch up on Slack", "prompt": "Summarize the important messages from my Slack channels from today. Highlight any mentions or urgent items.", "category": "productivity", "icon": "slack" }, { "id": "post_update", "title": "Post team update", "prompt": "Help me write and post a team update to Slack about my current work progress.", "category": "productivity", "icon": "message" }], "suggestedWith": ["gmail", "calendar", "jira"] },
|
|
33
32
|
{ "name": "snowflake", "displayName": "Snowflake", "icon": "snowflake.svg", "description": "Query and manage your Snowflake data warehouse with SQL operations across databases, schemas, and tables", "auth": { "type": "api-key", "requiredApis": [{ "name": "Snowflake Account", "enableUrl": "https://app.snowflake.com/" }] }, "envVars": [{ "name": "SNOWFLAKE_ACCOUNT", "description": "Your Snowflake account identifier (e.g., xy12345.us-east-1)", "required": true, "sensitive": false, "docsUrl": "https://docs.snowflake.com/en/user-guide/admin-account-identifier" }, { "name": "SNOWFLAKE_USERNAME", "description": "Snowflake username for authentication", "required": true, "sensitive": false, "docsUrl": "https://docs.snowflake.com/en/user-guide/admin-user-management" }, { "name": "SNOWFLAKE_PASSWORD", "description": "Snowflake password for authentication", "required": true, "sensitive": true, "docsUrl": "https://docs.snowflake.com/en/user-guide/admin-user-management" }, { "name": "SNOWFLAKE_WAREHOUSE", "description": "Default warehouse to use for queries (e.g., COMPUTE_WH)", "required": true, "sensitive": false, "docsUrl": "https://docs.snowflake.com/en/user-guide/warehouses" }, { "name": "SNOWFLAKE_DATABASE", "description": "Default database to use for queries", "required": false, "sensitive": false, "docsUrl": "https://docs.snowflake.com/en/user-guide/databases" }, { "name": "SNOWFLAKE_SCHEMA", "description": "Default schema to use for queries (defaults to PUBLIC)", "required": false, "sensitive": false, "docsUrl": "https://docs.snowflake.com/en/user-guide/schemas" }], "tools": [{ "id": "run_query", "name": "Run Query", "description": "Execute a SQL query against your Snowflake data warehouse", "requiresWrite": false }, { "id": "list_databases", "name": "List Databases", "description": "List all databases in your Snowflake account", "requiresWrite": false }, { "id": "list_schemas", "name": "List Schemas", "description": "List all schemas in a Snowflake database", "requiresWrite": false }, { "id": "list_tables", "name": "List Tables", "description": "List all tables in a Snowflake database schema", "requiresWrite": false }, { "id": "describe_table", "name": "Describe Table", "description": "Get detailed column information for a specific table", "requiresWrite": false }], "prompts": [{ "id": "query_data", "title": "Query my data warehouse", "prompt": "Help me query data from my Snowflake data warehouse. Show me specific records or analyze patterns.", "category": "data", "icon": "search" }, { "id": "analyze_tables", "title": "Analyze table structure", "prompt": "Show me the structure of tables in my Snowflake database and help me understand the schema.", "category": "data", "icon": "database" }, { "id": "data_insights", "title": "Generate insights", "prompt": "Analyze my Snowflake data and generate insights about trends, patterns, and anomalies.", "category": "analytics", "icon": "chart" }, { "id": "optimize_queries", "title": "Optimize queries", "prompt": "Help me optimize my SQL queries for better performance in Snowflake.", "category": "analytics", "icon": "lightning" }], "suggestedWith": ["github", "slack", "notion"] },
|
|
34
33
|
{ "name": "stripe", "displayName": "Stripe", "icon": "stripe.svg", "description": "Access Stripe payment data, customers, subscriptions, and balance information", "auth": { "type": "api-key", "requiredApis": [{ "name": "Stripe API", "enableUrl": "https://dashboard.stripe.com/apikeys" }], "keyName": "STRIPE_SECRET_KEY", "headerName": "Authorization", "headerPrefix": "Bearer" }, "envVars": [{ "name": "STRIPE_SECRET_KEY", "description": "Stripe Secret Key (starts with sk_)", "required": true, "sensitive": true, "docsUrl": "https://dashboard.stripe.com/apikeys" }, { "name": "STRIPE_WEBHOOK_SECRET", "description": "Stripe Webhook Secret (optional, for webhook verification)", "required": false, "sensitive": true, "docsUrl": "https://dashboard.stripe.com/webhooks" }], "tools": [{ "id": "list_customers", "name": "List Customers", "description": "List Stripe customers with optional filtering", "requiresWrite": false }, { "id": "get_customer", "name": "Get Customer", "description": "Retrieve detailed information about a specific customer", "requiresWrite": false }, { "id": "list_payments", "name": "List Payments", "description": "List payment intents with optional status filtering", "requiresWrite": false }, { "id": "get_balance", "name": "Get Balance", "description": "Retrieve the current account balance", "requiresWrite": false }, { "id": "list_subscriptions", "name": "List Subscriptions", "description": "List subscriptions with optional status filtering", "requiresWrite": false }], "prompts": [{ "id": "check_balance", "title": "Check account balance", "prompt": "Check my Stripe account balance and provide a summary of available and pending funds.", "category": "finance", "icon": "currency" }, { "id": "recent_payments", "title": "Recent payments", "prompt": "Show me the most recent successful payments in my Stripe account.", "category": "finance", "icon": "payment" }, { "id": "customer_overview", "title": "Customer overview", "prompt": "Give me an overview of my Stripe customers including total count and recent additions.", "category": "analytics", "icon": "users" }, { "id": "subscription_status", "title": "Subscription status", "prompt": "Show me the status of all active subscriptions and any that are expiring soon.", "category": "analytics", "icon": "repeat" }], "suggestedWith": ["slack", "email", "analytics"] },
|
|
35
34
|
{ "name": "supabase", "displayName": "Supabase", "icon": "supabase.svg", "description": "Query and manage your Supabase database with full CRUD operations", "auth": { "type": "api-key", "requiredApis": [{ "name": "Supabase Project", "enableUrl": "https://supabase.com/dashboard/projects" }] }, "envVars": [{ "name": "SUPABASE_URL", "description": "Your Supabase project URL (e.g., https://xxxxx.supabase.co)", "required": true, "sensitive": false, "docsUrl": "https://supabase.com/docs/guides/api#api-url-and-keys" }, { "name": "SUPABASE_ANON_KEY", "description": "Supabase anonymous/public API key for client-side operations", "required": true, "sensitive": true, "docsUrl": "https://supabase.com/docs/guides/api#api-url-and-keys" }, { "name": "SUPABASE_SERVICE_KEY", "description": "Supabase service role key for server-side operations (bypasses RLS)", "required": true, "sensitive": true, "docsUrl": "https://supabase.com/docs/guides/api#api-url-and-keys" }], "tools": [{ "id": "list_tables", "name": "List Tables", "description": "List all tables in your Supabase database", "requiresWrite": false }, { "id": "query_table", "name": "Query Table", "description": "Select rows from a table with optional filters and sorting", "requiresWrite": false }, { "id": "insert_row", "name": "Insert Row", "description": "Insert a new row into a table", "requiresWrite": true }, { "id": "update_row", "name": "Update Row", "description": "Update an existing row in a table", "requiresWrite": true }, { "id": "delete_row", "name": "Delete Row", "description": "Delete a row from a table", "requiresWrite": true }], "prompts": [{ "id": "query_data", "title": "Query my database", "prompt": "Help me query data from my Supabase database. Show me specific records or analyze patterns.", "category": "data", "icon": "search" }, { "id": "create_record", "title": "Create a record", "prompt": "Create a new record in my Supabase database with the information I provide.", "category": "data", "icon": "plus" }, { "id": "update_records", "title": "Update records", "prompt": "Find and update records in my Supabase database based on specific criteria.", "category": "data", "icon": "edit" }, { "id": "database_stats", "title": "Database statistics", "prompt": "Show me statistics and insights about my Supabase database tables and data.", "category": "analytics", "icon": "chart" }], "suggestedWith": ["github", "slack", "linear"] },
|
|
@@ -48,7 +47,6 @@ export const icons = {
|
|
|
48
47
|
"discord": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_0_445)\">\n<mask id=\"mask0_0_445\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"14\" width=\"128\" height=\"100\">\n<path d=\"M128 14.4225H0V113.577H128V14.4225Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask0_0_445)\">\n<path d=\"M108.357 23.2524C100.199 19.509 91.4506 16.7511 82.3035 15.1715C82.1369 15.141 81.9705 15.2172 81.8847 15.3695C80.7595 17.3707 79.5132 19.9813 78.6405 22.0333C68.8022 20.5604 59.0143 20.5604 49.3777 22.0333C48.5048 19.9357 47.2133 17.3707 46.0831 15.3695C45.9972 15.2223 45.8308 15.1461 45.6643 15.1715C36.5222 16.746 27.7737 19.504 19.6103 23.2524C19.5396 23.2828 19.4791 23.3337 19.4389 23.3997C2.84476 48.1909 -1.70107 72.3728 0.528961 96.2549C0.539051 96.3717 0.604639 96.4835 0.695456 96.5546C11.6438 104.595 22.2491 109.476 32.6575 112.711C32.8241 112.762 33.0006 112.701 33.1066 112.564C35.5687 109.202 37.7634 105.656 39.6452 101.928C39.7563 101.71 39.6503 101.451 39.4233 101.364C35.942 100.044 32.6272 98.4338 29.4386 96.6054C29.1863 96.4581 29.1662 96.0974 29.3982 95.9246C30.0692 95.4218 30.7404 94.8987 31.3811 94.3704C31.497 94.274 31.6585 94.2536 31.7948 94.3146C52.7429 103.879 75.4216 103.879 96.1224 94.3146C96.2587 94.2486 96.4202 94.2689 96.5412 94.3654C97.1821 94.8936 97.8531 95.4218 98.5292 95.9246C98.7612 96.0974 98.746 96.4581 98.4938 96.6054C95.3052 98.4693 91.9903 100.044 88.5041 101.359C88.2771 101.446 88.1761 101.71 88.2872 101.928C90.2094 105.651 92.4041 109.196 94.8208 112.559C94.9217 112.701 95.1033 112.762 95.2699 112.711C105.729 109.476 116.334 104.595 127.282 96.5546C127.378 96.4835 127.439 96.3768 127.449 96.26C130.118 68.6497 122.979 44.6661 108.524 23.4047C108.488 23.3337 108.428 23.2828 108.357 23.2524ZM42.7735 81.7132C36.4667 81.7132 31.27 75.9231 31.27 68.8123C31.27 61.7014 36.3659 55.9113 42.7735 55.9113C49.2313 55.9113 54.3776 61.7523 54.2767 68.8123C54.2767 75.9231 49.1808 81.7132 42.7735 81.7132ZM85.3053 81.7132C78.9987 81.7132 73.8021 75.9231 73.8021 68.8123C73.8021 61.7014 78.8978 55.9113 85.3053 55.9113C91.7634 55.9113 96.9095 61.7523 96.8087 68.8123C96.8087 75.9231 91.7634 81.7132 85.3053 81.7132Z\" fill=\"#5865F2\"/>\n</g>\n</g>\n<defs>\n<clipPath id=\"clip0_0_445\">\n<rect width=\"128\" height=\"99.1549\" fill=\"white\" transform=\"translate(0 14.4225)\"/>\n</clipPath>\n</defs>\n</svg>\n",
|
|
49
48
|
"docs-google": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_0_239)\">\n<mask id=\"mask0_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask0_0_239)\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L90.3077 20.3636L75.8462 0Z\" fill=\"#4285F4\"/>\n</g>\n<mask id=\"mask1_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask1_0_239)\">\n<path d=\"M78.3848 32.3564L110.554 64.7055V34.9091L78.3848 32.3564Z\" fill=\"url(#paint0_linear_0_239)\"/>\n</g>\n<mask id=\"mask2_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask2_0_239)\">\n<path d=\"M41.1382 93.0909H87.4151V87.2727H41.1382V93.0909ZM41.1382 104.727H75.8459V98.9091H41.1382V104.727ZM41.1382 64V69.8182H87.4151V64H41.1382ZM41.1382 81.4545H87.4151V75.6364H41.1382V81.4545Z\" fill=\"#F1F1F1\"/>\n</g>\n<mask id=\"mask3_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask3_0_239)\">\n<path d=\"M75.8462 0V26.1818C75.8462 31.0036 79.7291 34.9091 84.5231 34.9091H110.554L75.8462 0Z\" fill=\"#A1C2FA\"/>\n</g>\n<mask id=\"mask4_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask4_0_239)\">\n<path d=\"M26.6769 0C21.9046 0 18 3.92727 18 8.72727V9.45455C18 4.65455 21.9046 0.727273 26.6769 0.727273H75.8462V0H26.6769Z\" fill=\"white\" fill-opacity=\"0.2\"/>\n</g>\n<mask id=\"mask5_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask5_0_239)\">\n<path d=\"M101.877 127.273H26.6769C21.9046 127.273 18 123.345 18 118.545V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V118.545C110.554 123.345 106.649 127.273 101.877 127.273Z\" fill=\"#1A237E\" fill-opacity=\"0.2\"/>\n</g>\n<mask id=\"mask6_0_239\" style=\"mask-type:luminance\" maskUnits=\"userSpaceOnUse\" x=\"18\" y=\"0\" width=\"93\" height=\"128\">\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"white\"/>\n</mask>\n<g mask=\"url(#mask6_0_239)\">\n<path d=\"M84.5231 34.9091C79.7291 34.9091 75.8462 31.0036 75.8462 26.1818V26.9091C75.8462 31.7309 79.7291 35.6364 84.5231 35.6364H110.554V34.9091H84.5231Z\" fill=\"#1A237E\" fill-opacity=\"0.1\"/>\n</g>\n<path d=\"M75.8462 0H26.6769C21.9046 0 18 3.92727 18 8.72727V119.273C18 124.073 21.9046 128 26.6769 128H101.877C106.649 128 110.554 124.073 110.554 119.273V34.9091L75.8462 0Z\" fill=\"url(#paint1_radial_0_239)\"/>\n</g>\n<defs>\n<linearGradient id=\"paint0_linear_0_239\" x1=\"1687.04\" y1=\"310.109\" x2=\"1687.04\" y2=\"3267.72\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#1A237E\" stop-opacity=\"0.2\"/>\n<stop offset=\"1\" stop-color=\"#1A237E\" stop-opacity=\"0.02\"/>\n</linearGradient>\n<radialGradient id=\"paint1_radial_0_239\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"translate(311.215 251.525) scale(14924.2 14924.2)\">\n<stop stop-color=\"white\" stop-opacity=\"0.1\"/>\n<stop offset=\"1\" stop-color=\"white\" stop-opacity=\"0\"/>\n</radialGradient>\n<clipPath id=\"clip0_0_239\">\n<rect width=\"92.5538\" height=\"128\" fill=\"white\" transform=\"translate(18)\"/>\n</clipPath>\n</defs>\n</svg>\n",
|
|
50
49
|
"drive": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_0_185)\">\n<g clip-path=\"url(#clip1_0_185)\">\n<path d=\"M9.32688 104.834L14.9718 114.584C16.1447 116.637 17.8309 118.25 19.8103 119.423L39.9706 84.5269H-0.350098C-0.350098 86.7995 0.236386 89.0722 1.40935 91.1249L9.32688 104.834Z\" fill=\"#0066DA\"/>\n<path d=\"M63.6499 43.4731L43.4895 8.57732C41.5102 9.75029 39.824 11.3631 38.651 13.4158L1.40935 77.929C0.257958 79.9374 -0.348565 82.2119 -0.350098 84.5269H39.9706L63.6499 43.4731Z\" fill=\"#00AC47\"/>\n<path d=\"M107.489 119.423C109.469 118.25 111.155 116.637 112.328 114.584L114.674 110.552L125.89 91.1249C127.063 89.0722 127.65 86.7995 127.65 84.5269H87.3262L95.9064 101.388L107.489 119.423Z\" fill=\"#EA4335\"/>\n<path d=\"M63.6496 43.4731L83.81 8.57732C81.8306 7.40435 79.558 6.81787 77.2121 6.81787H50.0872C47.7413 6.81787 45.4686 7.47767 43.4893 8.57732L63.6496 43.4731Z\" fill=\"#00832D\"/>\n<path d=\"M87.3294 84.5269H39.9709L19.8105 119.423C21.7899 120.596 24.0626 121.182 26.4085 121.182H100.892C103.238 121.182 105.51 120.522 107.49 119.423L87.3294 84.5269Z\" fill=\"#2684FC\"/>\n<path d=\"M107.27 45.6724L88.6488 13.4158C87.4758 11.3631 85.7896 9.75029 83.8103 8.57732L63.6499 43.4731L87.3292 84.5269H127.577C127.577 82.2543 126.99 79.9817 125.817 77.929L107.27 45.6724Z\" fill=\"#FFBA00\"/>\n</g>\n</g>\n<defs>\n<clipPath id=\"clip0_0_185\">\n<rect width=\"128\" height=\"128\" fill=\"white\"/>\n</clipPath>\n<clipPath id=\"clip1_0_185\">\n<rect width=\"128\" height=\"114.364\" fill=\"white\" transform=\"translate(-0.350098 6.81787)\"/>\n</clipPath>\n</defs>\n</svg>\n",
|
|
51
|
-
"dropbox": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M31.9986 50.409L64.0026 30.0226L31.9986 9.63611L0 30.0226L31.9986 50.409Z\" fill=\"#0061FF\"/>\n<path d=\"M96.0015 50.409L128 30.0226L96.0015 9.63611L64.0029 30.0226L96.0015 50.409Z\" fill=\"#0061FF\"/>\n<path d=\"M64.0026 70.7954L31.9986 50.409L0 70.7954L31.9986 91.1819L64.0026 70.7954Z\" fill=\"#0061FF\"/>\n<path d=\"M96.0015 91.1819L128 70.7954L96.0015 50.409L64.0029 70.7954L96.0015 91.1819Z\" fill=\"#0061FF\"/>\n<path d=\"M96.0011 97.9774L64.0025 77.5909L31.9985 97.9774L64.0025 118.364L96.0011 97.9774Z\" fill=\"#0061FF\"/>\n</svg>\n",
|
|
52
50
|
"figma": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_0_460)\">\n<path d=\"M64 64C64 52.3381 73.4539 42.8839 85.1161 42.8839C96.7781 42.8839 106.232 52.3381 106.232 64C106.232 75.6622 96.7781 85.1161 85.1161 85.1161C73.4539 85.1161 64 75.6622 64 64Z\" fill=\"#1ABCFE\"/>\n<path d=\"M21.7681 106.232C21.7681 94.5704 31.2221 85.1161 42.8842 85.1161H64.0004V106.232C64.0004 117.895 54.5464 127.348 42.8842 127.348C31.2221 127.348 21.7681 117.895 21.7681 106.232Z\" fill=\"#0ACF83\"/>\n<path d=\"M64 0.651688V42.8838H85.1161C96.7784 42.8838 106.232 33.4299 106.232 21.7678C106.232 10.1057 96.7784 0.651688 85.1161 0.651688H64Z\" fill=\"#FF7262\"/>\n<path d=\"M21.7681 21.7678C21.7681 33.4299 31.2221 42.8838 42.8842 42.8838H64.0004V0.651672H42.8842C31.2221 0.651672 21.7681 10.1057 21.7681 21.7678Z\" fill=\"#F24E1E\"/>\n<path d=\"M21.7681 64C21.7681 75.6622 31.2221 85.1161 42.8842 85.1161H64.0004V42.8839H42.8842C31.2221 42.8839 21.7681 52.3381 21.7681 64Z\" fill=\"#A259FF\"/>\n</g>\n<defs>\n<clipPath id=\"clip0_0_460\">\n<rect width=\"85.3333\" height=\"128\" fill=\"white\" transform=\"translate(21.3335)\"/>\n</clipPath>\n</defs>\n</svg>\n",
|
|
53
51
|
"github": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_0_48)\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M63.8093 1.30612C28.5244 1.30612 0 30.0408 0 65.5895C0 94.0055 18.2766 118.059 43.631 126.572C46.801 127.212 47.9621 125.189 47.9621 123.487C47.9621 121.997 47.8576 116.889 47.8576 111.566C30.1074 115.399 26.4111 103.903 26.4111 103.903C23.5585 96.4532 19.3319 94.5384 19.3319 94.5384C13.5223 90.6005 19.7551 90.6005 19.7551 90.6005C26.1995 91.0263 29.5811 97.199 29.5811 97.199C35.2849 106.99 44.4761 104.223 48.1737 102.52C48.7014 98.3693 50.3928 95.4958 52.1887 93.8997C38.0317 92.4095 23.1367 86.8754 23.1367 62.1832C23.1367 55.1589 25.6705 49.4119 29.6856 44.9424C29.0521 43.3463 26.833 36.7464 30.3203 27.9131C30.3203 27.9131 35.7081 26.21 47.8563 34.5117C53.0574 33.1045 58.4212 32.3887 63.8093 32.3827C69.1971 32.3827 74.6893 33.1285 79.761 34.5117C91.9105 26.21 97.2983 27.9131 97.2983 27.9131C100.786 36.7464 98.5652 43.3463 97.9318 44.9424C102.053 49.4119 104.482 55.1589 104.482 62.1832C104.482 86.8754 89.5869 92.3024 75.3241 93.8997C77.649 95.9216 79.6552 99.7525 79.6552 105.819C79.6552 114.44 79.5507 121.358 79.5507 123.486C79.5507 125.189 80.7132 127.212 83.8818 126.574C109.236 118.058 127.513 94.0055 127.513 65.5895C127.617 30.0408 98.9884 1.30612 63.8093 1.30612Z\" fill=\"#24292F\"/>\n</g>\n<defs>\n<clipPath id=\"clip0_0_48\">\n<rect width=\"128\" height=\"125.388\" fill=\"white\" transform=\"translate(0 1.30612)\"/>\n</clipPath>\n</defs>\n</svg>\n",
|
|
54
52
|
"gitlab": "<svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g clip-path=\"url(#clip0_240_6238)\">\n<g clip-path=\"url(#clip1_240_6238)\">\n<path d=\"M125.848 51.1162L125.668 50.6562L108.268 5.25622C107.915 4.3644 107.289 3.60698 106.48 3.09222C105.665 2.57734 104.711 2.32811 103.749 2.37899C102.786 2.42986 101.864 2.77832 101.108 3.37622C100.36 3.97622 99.82 4.80022 99.564 5.72422L87.804 41.7282H40.204L28.44 5.72822C28.1887 4.79778 27.6485 3.97111 26.8973 3.36729C26.1462 2.76346 25.2227 2.41365 24.26 2.36822C23.3004 2.3176 22.3491 2.56794 21.5387 3.08427C20.7283 3.6006 20.0995 4.35714 19.74 5.24822L2.31598 50.7202L2.13598 51.1722C-0.364414 57.7204 -0.671054 64.9035 1.26218 71.6409C3.19542 78.3784 7.264 84.306 12.856 88.5322L12.92 88.5802L13.072 88.7002L39.612 108.568L52.732 118.504L60.708 124.544C61.6452 125.252 62.7876 125.635 63.962 125.635C65.1364 125.635 66.2788 125.252 67.216 124.544L75.192 118.504L88.32 108.568L115.012 88.5802L115.084 88.5282C120.694 84.3053 124.778 78.3718 126.719 71.6235C128.66 64.8752 128.353 57.6786 125.844 51.1202L125.848 51.1162Z\" fill=\"#E24329\"/>\n<path d=\"M125.848 51.1158L125.668 50.6558C117.181 52.4047 109.183 56.002 102.244 61.1918L64.032 90.1518C72.1526 96.2905 80.2752 102.427 88.4 108.56L115.092 88.5718L115.168 88.5198C120.763 84.2854 124.831 78.3471 126.757 71.5998C128.683 64.8525 128.364 57.662 125.848 51.1118V51.1158Z\" fill=\"#FC6D26\"/>\n<path d=\"M39.632 108.56L52.732 118.5L60.708 124.54C61.6452 125.248 62.7876 125.63 63.962 125.63C65.1364 125.63 66.2788 125.248 67.216 124.54L75.192 118.5L88.32 108.564C88.32 108.564 76.98 100.004 63.952 90.1519L39.632 108.564V108.56Z\" fill=\"#FCA326\"/>\n<path d=\"M25.74 61.22C18.8038 56.0281 10.8068 52.4318 2.32001 50.688L2.14001 51.14C-0.367146 57.6918 -0.677348 64.8809 1.25614 71.6242C3.18962 78.3676 7.26208 84.3001 12.86 88.528L12.924 88.576L13.076 88.696L39.616 108.564L64.036 90.152L25.74 61.22Z\" fill=\"#FC6D26\"/>\n</g>\n</g>\n<defs>\n<clipPath id=\"clip0_240_6238\">\n<rect width=\"128\" height=\"128\" fill=\"white\"/>\n</clipPath>\n<clipPath id=\"clip1_240_6238\">\n<rect width=\"128\" height=\"128\" fill=\"white\"/>\n</clipPath>\n</defs>\n</svg>\n",
|