feat(cursor): add cursor block and tools (#2245)

* fix(autolayout): reduce horizontal spacing in autolayout

* feat(cursor): add cursor cloud agents tools

* address greptile prompt
This commit is contained in:
Vikhyath Mondreti
2025-12-08 09:49:28 -08:00
committed by GitHub
parent d200f664e8
commit 01b2f809d1
18 changed files with 1393 additions and 103 deletions
+8
View File
@@ -4121,3 +4121,11 @@ export function GoogleGroupsIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function CursorIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 546 546' fill='currentColor'>
<path d='m466.383 137.073-206.469-119.2034c-6.63-3.8287-14.811-3.8287-21.441 0l-206.4586 119.2034c-5.5734 3.218-9.0144 9.169-9.0144 15.615v240.375c0 6.436 3.441 12.397 9.0144 15.615l206.4686 119.203c6.63 3.829 14.811 3.829 21.441 0l206.468-119.203c5.574-3.218 9.015-9.17 9.015-15.615v-240.375c0-6.436-3.441-12.397-9.015-15.615zm-12.969 25.25-199.316 345.223c-1.347 2.326-4.904 1.376-4.904-1.319v-226.048c0-4.517-2.414-8.695-6.33-10.963l-195.7577-113.019c-2.3263-1.347-1.3764-4.905 1.3182-4.905h398.6305c5.661 0 9.199 6.136 6.368 11.041h-.009z' />
</svg>
)
}
+105 -103
View File
@@ -15,6 +15,7 @@ import {
CalendlyIcon,
ClayIcon,
ConfluenceIcon,
CursorIcon,
DatadogIcon,
DiscordIcon,
DocumentIcon,
@@ -115,113 +116,114 @@ import {
type IconComponent = ComponentType<SVGProps<SVGSVGElement>>
export const blockTypeToIconMap: Record<string, IconComponent> = {
zoom: ZoomIcon,
zep: ZepIcon,
zendesk: ZendeskIcon,
youtube: YouTubeIcon,
x: xIcon,
wordpress: WordpressIcon,
wikipedia: WikipediaIcon,
whatsapp: WhatsAppIcon,
webflow: WebflowIcon,
wealthbox: WealthboxIcon,
vision: EyeIcon,
video_generator: VideoIcon,
typeform: TypeformIcon,
twilio_voice: TwilioIcon,
twilio_sms: TwilioIcon,
tts: TTSIcon,
trello: TrelloIcon,
translate: TranslateIcon,
thinking: BrainIcon,
telegram: TelegramIcon,
tavily: TavilyIcon,
supabase: SupabaseIcon,
stt: STTIcon,
stripe: StripeIcon,
stagehand_agent: StagehandIcon,
stagehand: StagehandIcon,
ssh: SshIcon,
smtp: SmtpIcon,
slack: SlackIcon,
shopify: ShopifyIcon,
sharepoint: MicrosoftSharepointIcon,
serper: SerperIcon,
sentry: SentryIcon,
sendgrid: SendgridIcon,
search: SearchIcon,
salesforce: SalesforceIcon,
s3: S3Icon,
resend: ResendIcon,
reddit: RedditIcon,
rds: RDSIcon,
qdrant: QdrantIcon,
pylon: PylonIcon,
posthog: PosthogIcon,
postgresql: PostgresIcon,
polymarket: PolymarketIcon,
pipedrive: PipedriveIcon,
pinecone: PineconeIcon,
perplexity: PerplexityIcon,
parallel_ai: ParallelIcon,
outlook: OutlookIcon,
openai: OpenAIIcon,
onedrive: MicrosoftOneDriveIcon,
notion: NotionIcon,
neo4j: Neo4jIcon,
mysql: MySQLIcon,
mongodb: MongoDBIcon,
mistral_parse: MistralIcon,
microsoft_teams: MicrosoftTeamsIcon,
microsoft_planner: MicrosoftPlannerIcon,
microsoft_excel: MicrosoftExcelIcon,
memory: BrainIcon,
mem0: Mem0Icon,
mailgun: MailgunIcon,
mailchimp: MailchimpIcon,
linkup: LinkupIcon,
linkedin: LinkedInIcon,
linear: LinearIcon,
knowledge: PackageSearchIcon,
kalshi: KalshiIcon,
jira: JiraIcon,
jina: JinaAIIcon,
intercom: IntercomIcon,
incidentio: IncidentioIcon,
image_generator: ImageIcon,
hunter: HunterIOIcon,
huggingface: HuggingFaceIcon,
hubspot: HubspotIcon,
grafana: GrafanaIcon,
google_vault: GoogleVaultIcon,
google_slides: GoogleSlidesIcon,
google_sheets: GoogleSheetsIcon,
google_groups: GoogleGroupsIcon,
google_forms: GoogleFormsIcon,
google_drive: GoogleDriveIcon,
google_docs: GoogleDocsIcon,
google_calendar: GoogleCalendarIcon,
google_search: GoogleIcon,
gmail: GmailIcon,
gitlab: GitLabIcon,
github: GithubIcon,
firecrawl: FirecrawlIcon,
file: DocumentIcon,
exa: ExaAIIcon,
elevenlabs: ElevenLabsIcon,
elasticsearch: ElasticsearchIcon,
dynamodb: DynamoDBIcon,
dropbox: DropboxIcon,
discord: DiscordIcon,
datadog: DatadogIcon,
confluence: ConfluenceIcon,
clay: ClayIcon,
calendly: CalendlyIcon,
browser_use: BrowserUseIcon,
asana: AsanaIcon,
mailchimp: MailchimpIcon,
postgresql: PostgresIcon,
twilio_voice: TwilioIcon,
elasticsearch: ElasticsearchIcon,
rds: RDSIcon,
translate: TranslateIcon,
dynamodb: DynamoDBIcon,
wordpress: WordpressIcon,
tavily: TavilyIcon,
zendesk: ZendeskIcon,
stagehand_agent: StagehandIcon,
youtube: YouTubeIcon,
supabase: SupabaseIcon,
vision: EyeIcon,
zoom: ZoomIcon,
confluence: ConfluenceIcon,
arxiv: ArxivIcon,
webflow: WebflowIcon,
pinecone: PineconeIcon,
apollo: ApolloIcon,
whatsapp: WhatsAppIcon,
typeform: TypeformIcon,
qdrant: QdrantIcon,
shopify: ShopifyIcon,
asana: AsanaIcon,
apify: ApifyIcon,
memory: BrainIcon,
gitlab: GitLabIcon,
polymarket: PolymarketIcon,
serper: SerperIcon,
linear: LinearIcon,
exa: ExaAIIcon,
telegram: TelegramIcon,
salesforce: SalesforceIcon,
hubspot: HubspotIcon,
hunter: HunterIOIcon,
linkup: LinkupIcon,
mongodb: MongoDBIcon,
pylon: PylonIcon,
airtable: AirtableIcon,
discord: DiscordIcon,
ahrefs: AhrefsIcon,
neo4j: Neo4jIcon,
tts: TTSIcon,
jina: JinaAIIcon,
google_docs: GoogleDocsIcon,
perplexity: PerplexityIcon,
google_search: GoogleIcon,
x: xIcon,
kalshi: KalshiIcon,
google_calendar: GoogleCalendarIcon,
zep: ZepIcon,
posthog: PosthogIcon,
grafana: GrafanaIcon,
google_slides: GoogleSlidesIcon,
microsoft_planner: MicrosoftPlannerIcon,
thinking: BrainIcon,
pipedrive: PipedriveIcon,
dropbox: DropboxIcon,
stagehand: StagehandIcon,
google_forms: GoogleFormsIcon,
file: DocumentIcon,
mistral_parse: MistralIcon,
gmail: GmailIcon,
openai: OpenAIIcon,
outlook: OutlookIcon,
incidentio: IncidentioIcon,
onedrive: MicrosoftOneDriveIcon,
resend: ResendIcon,
google_vault: GoogleVaultIcon,
sharepoint: MicrosoftSharepointIcon,
huggingface: HuggingFaceIcon,
sendgrid: SendgridIcon,
video_generator: VideoIcon,
smtp: SmtpIcon,
google_groups: GoogleGroupsIcon,
mailgun: MailgunIcon,
clay: ClayIcon,
jira: JiraIcon,
search: SearchIcon,
linkedin: LinkedInIcon,
wealthbox: WealthboxIcon,
notion: NotionIcon,
elevenlabs: ElevenLabsIcon,
microsoft_teams: MicrosoftTeamsIcon,
github: GithubIcon,
ssh: SshIcon,
google_drive: GoogleDriveIcon,
sentry: SentryIcon,
reddit: RedditIcon,
parallel_ai: ParallelIcon,
stripe: StripeIcon,
s3: S3Icon,
trello: TrelloIcon,
mem0: Mem0Icon,
knowledge: PackageSearchIcon,
intercom: IntercomIcon,
twilio_sms: TwilioIcon,
slack: SlackIcon,
datadog: DatadogIcon,
microsoft_excel: MicrosoftExcelIcon,
image_generator: ImageIcon,
google_sheets: GoogleSheetsIcon,
wikipedia: WikipediaIcon,
cursor: CursorIcon,
firecrawl: FirecrawlIcon,
mysql: MySQLIcon,
browser_use: BrowserUseIcon,
stt: STTIcon,
}
+163
View File
@@ -0,0 +1,163 @@
---
title: Cursor
description: Launch and manage Cursor cloud agents to work on GitHub repositories
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="cursor"
color="#1E1E1E"
/>
## Usage Instructions
Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.
## Tools
### `cursor_list_agents`
List all cloud agents for the authenticated user with optional pagination.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `limit` | number | No | Number of agents to return \(default: 20, max: 100\) |
| `cursor` | string | No | Pagination cursor from previous response |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Human-readable list of agents |
| `metadata` | object | Agent list metadata |
### `cursor_get_agent`
Retrieve the current status and results of a cloud agent.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `agentId` | string | Yes | Unique identifier for the cloud agent \(e.g., bc_abc123\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Human-readable agent details |
| `metadata` | object | Agent metadata |
### `cursor_get_conversation`
Retrieve the conversation history of a cloud agent, including all user prompts and assistant responses.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `agentId` | string | Yes | Unique identifier for the cloud agent \(e.g., bc_abc123\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Human-readable conversation history |
| `metadata` | object | Conversation metadata |
### `cursor_launch_agent`
Start a new cloud agent to work on a GitHub repository with the given instructions.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `repository` | string | Yes | GitHub repository URL \(e.g., https://github.com/your-org/your-repo\) |
| `ref` | string | No | Branch, tag, or commit to work from \(defaults to default branch\) |
| `promptText` | string | Yes | The instruction text for the agent |
| `promptImages` | string | No | JSON array of image objects with base64 data and dimensions |
| `model` | string | No | Model to use \(leave empty for auto-selection\) |
| `branchName` | string | No | Custom branch name for the agent to use |
| `autoCreatePr` | boolean | No | Automatically create a PR when the agent finishes |
| `openAsCursorGithubApp` | boolean | No | Open the PR as the Cursor GitHub App |
| `skipReviewerRequest` | boolean | No | Skip requesting reviewers on the PR |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Success message with agent details |
| `metadata` | object | Launch result metadata |
### `cursor_add_followup`
Add a follow-up instruction to an existing cloud agent.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `agentId` | string | Yes | Unique identifier for the cloud agent \(e.g., bc_abc123\) |
| `promptText` | string | Yes | The follow-up instruction text for the agent |
| `promptImages` | string | No | JSON array of image objects with base64 data and dimensions \(max 5\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Success message |
| `metadata` | object | Result metadata |
### `cursor_stop_agent`
Stop a running cloud agent. This pauses the agent without deleting it.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `agentId` | string | Yes | Unique identifier for the cloud agent \(e.g., bc_abc123\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Success message |
| `metadata` | object | Result metadata |
### `cursor_delete_agent`
Permanently delete a cloud agent. This action cannot be undone.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Cursor API key |
| `agentId` | string | Yes | Unique identifier for the cloud agent \(e.g., bc_abc123\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `content` | string | Success message |
| `metadata` | object | Result metadata |
## Notes
- Category: `tools`
- Type: `cursor`
@@ -11,6 +11,7 @@
"calendly",
"clay",
"confluence",
"cursor",
"datadog",
"discord",
"dropbox",
@@ -416,6 +416,165 @@ Delete an account from Salesforce CRM
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_list_reports`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_get_report`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_run_report`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_list_report_types`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_list_dashboards`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_get_dashboard`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_refresh_dashboard`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_query`
Execute a custom SOQL query to retrieve data from Salesforce
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `idToken` | string | No | No description |
| `instanceUrl` | string | No | No description |
| `query` | string | Yes | SOQL query to execute \(e.g., SELECT Id, Name FROM Account LIMIT 10\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Success status |
| `output` | object | Query results |
### `salesforce_query_more`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_describe_object`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
### `salesforce_list_objects`
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Operation result data |
## Notes
+171
View File
@@ -0,0 +1,171 @@
import { CursorIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode } from '@/blocks/types'
import type { CursorResponse } from '@/tools/cursor/types'
export const CursorBlock: BlockConfig<CursorResponse> = {
type: 'cursor',
name: 'Cursor',
description: 'Launch and manage Cursor cloud agents to work on GitHub repositories',
longDescription:
'Interact with Cursor Cloud Agents API to launch AI agents that can work on your GitHub repositories. Supports launching agents, adding follow-up instructions, checking status, viewing conversations, and managing agent lifecycle.',
docsLink: 'https://cursor.com/docs/cloud-agent/api/endpoints',
category: 'tools',
bgColor: '#1E1E1E',
icon: CursorIcon,
authMode: AuthMode.ApiKey,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'Launch Agent', id: 'cursor_launch_agent' },
{ label: 'Add Follow-up', id: 'cursor_add_followup' },
{ label: 'Get Agent Status', id: 'cursor_get_agent' },
{ label: 'Get Conversation', id: 'cursor_get_conversation' },
{ label: 'List Agents', id: 'cursor_list_agents' },
{ label: 'Stop Agent', id: 'cursor_stop_agent' },
{ label: 'Delete Agent', id: 'cursor_delete_agent' },
],
value: () => 'cursor_launch_agent',
},
{
id: 'repository',
title: 'Repository URL',
type: 'short-input',
placeholder: 'https://github.com/your-org/your-repo',
condition: { field: 'operation', value: 'cursor_launch_agent' },
required: true,
},
{
id: 'ref',
title: 'Branch/Ref',
type: 'short-input',
placeholder: 'main (optional)',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'promptText',
title: 'Prompt',
type: 'long-input',
placeholder: 'Describe the task for the agent...',
condition: { field: 'operation', value: 'cursor_launch_agent' },
required: true,
},
{
id: 'model',
title: 'Model',
type: 'short-input',
placeholder: 'Auto-selection by default',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'branchName',
title: 'Branch Name',
type: 'short-input',
placeholder: 'Custom branch name (optional)',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'autoCreatePr',
title: 'Auto Create PR',
type: 'switch',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'openAsCursorGithubApp',
title: 'Open as Cursor GitHub App',
type: 'switch',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'skipReviewerRequest',
title: 'Skip Reviewer Request',
type: 'switch',
condition: { field: 'operation', value: 'cursor_launch_agent' },
},
{
id: 'agentId',
title: 'Agent ID',
type: 'short-input',
placeholder: 'e.g., bc_abc123',
condition: {
field: 'operation',
value: [
'cursor_get_agent',
'cursor_get_conversation',
'cursor_add_followup',
'cursor_stop_agent',
'cursor_delete_agent',
],
},
required: true,
},
{
id: 'followupPromptText',
title: 'Follow-up Prompt',
type: 'long-input',
placeholder: 'Additional instructions for the agent...',
condition: { field: 'operation', value: 'cursor_add_followup' },
required: true,
},
{
id: 'limit',
title: 'Limit',
type: 'short-input',
placeholder: '20 (default, max 100)',
condition: { field: 'operation', value: 'cursor_list_agents' },
},
{
id: 'cursor',
title: 'Pagination Cursor',
type: 'short-input',
placeholder: 'Cursor from previous response',
condition: { field: 'operation', value: 'cursor_list_agents' },
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
placeholder: 'Enter Cursor API Key',
password: true,
required: true,
},
],
tools: {
access: [
'cursor_list_agents',
'cursor_get_agent',
'cursor_get_conversation',
'cursor_launch_agent',
'cursor_add_followup',
'cursor_stop_agent',
'cursor_delete_agent',
],
config: {
tool: (params) => params.operation || 'cursor_launch_agent',
},
},
inputs: {
operation: { type: 'string', description: 'Operation to perform' },
repository: { type: 'string', description: 'GitHub repository URL' },
ref: { type: 'string', description: 'Branch, tag, or commit reference' },
promptText: { type: 'string', description: 'Instruction text for the agent' },
followupPromptText: { type: 'string', description: 'Follow-up instruction text for the agent' },
promptImages: { type: 'string', description: 'JSON array of image objects' },
model: { type: 'string', description: 'Model to use (empty for auto-selection)' },
branchName: { type: 'string', description: 'Custom branch name' },
autoCreatePr: { type: 'boolean', description: 'Auto-create PR when done' },
openAsCursorGithubApp: { type: 'boolean', description: 'Open PR as Cursor GitHub App' },
skipReviewerRequest: { type: 'boolean', description: 'Skip reviewer request' },
agentId: { type: 'string', description: 'Agent identifier' },
limit: { type: 'number', description: 'Number of results to return' },
cursor: { type: 'string', description: 'Pagination cursor' },
apiKey: { type: 'string', description: 'Cursor API key' },
},
outputs: {
content: { type: 'string', description: 'Human-readable response content' },
metadata: { type: 'json', description: 'Response metadata' },
},
}
+2
View File
@@ -14,6 +14,7 @@ import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger'
import { ClayBlock } from '@/blocks/blocks/clay'
import { ConditionBlock } from '@/blocks/blocks/condition'
import { ConfluenceBlock } from '@/blocks/blocks/confluence'
import { CursorBlock } from '@/blocks/blocks/cursor'
import { DatadogBlock } from '@/blocks/blocks/datadog'
import { DiscordBlock } from '@/blocks/blocks/discord'
import { DropboxBlock } from '@/blocks/blocks/dropbox'
@@ -152,6 +153,7 @@ export const registry: Record<string, BlockConfig> = {
clay: ClayBlock,
condition: ConditionBlock,
confluence: ConfluenceBlock,
cursor: CursorBlock,
datadog: DatadogBlock,
discord: DiscordBlock,
dropbox: DropboxBlock,
+8
View File
@@ -4121,3 +4121,11 @@ export function GoogleGroupsIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function CursorIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 546 546' fill='currentColor'>
<path d='m466.383 137.073-206.469-119.2034c-6.63-3.8287-14.811-3.8287-21.441 0l-206.4586 119.2034c-5.5734 3.218-9.0144 9.169-9.0144 15.615v240.375c0 6.436 3.441 12.397 9.0144 15.615l206.4686 119.203c6.63 3.829 14.811 3.829 21.441 0l206.468-119.203c5.574-3.218 9.015-9.17 9.015-15.615v-240.375c0-6.436-3.441-12.397-9.015-15.615zm-12.969 25.25-199.316 345.223c-1.347 2.326-4.904 1.376-4.904-1.319v-226.048c0-4.517-2.414-8.695-6.33-10.963l-195.7577-113.019c-2.3263-1.347-1.3764-4.905 1.3182-4.905h398.6305c5.661 0 9.199 6.136 6.368 11.041h-.009z' />
</svg>
)
}
+89
View File
@@ -0,0 +1,89 @@
import type { AddFollowupParams, AddFollowupResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const addFollowupTool: ToolConfig<AddFollowupParams, AddFollowupResponse> = {
id: 'cursor_add_followup',
name: 'Cursor Add Follow-up',
description: 'Add a follow-up instruction to an existing cloud agent.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
agentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier for the cloud agent (e.g., bc_abc123)',
},
followupPromptText: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The follow-up instruction text for the agent',
},
promptImages: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'JSON array of image objects with base64 data and dimensions (max 5)',
},
},
request: {
url: (params) => `https://api.cursor.com/v0/agents/${params.agentId}/followup`,
method: 'POST',
headers: (params) => ({
'Content-Type': 'application/json',
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
body: (params) => {
const body: Record<string, any> = {
prompt: {
text: params.followupPromptText,
},
}
if (params.promptImages) {
try {
body.prompt.images = JSON.parse(params.promptImages)
} catch {
body.prompt.images = []
}
}
return body
},
},
transformResponse: async (response) => {
const data = await response.json()
const content = `Follow-up added to agent ${data.id}`
return {
success: true,
output: {
content,
metadata: {
id: data.id,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Success message' },
metadata: {
type: 'object',
description: 'Result metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
},
},
},
}
+59
View File
@@ -0,0 +1,59 @@
import type { DeleteAgentParams, DeleteAgentResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const deleteAgentTool: ToolConfig<DeleteAgentParams, DeleteAgentResponse> = {
id: 'cursor_delete_agent',
name: 'Cursor Delete Agent',
description: 'Permanently delete a cloud agent. This action cannot be undone.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
agentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier for the cloud agent (e.g., bc_abc123)',
},
},
request: {
url: (params) => `https://api.cursor.com/v0/agents/${params.agentId}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
const content = `Agent ${data.id} has been deleted`
return {
success: true,
output: {
content,
metadata: {
id: data.id,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Success message' },
metadata: {
type: 'object',
description: 'Result metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
},
},
},
}
+61
View File
@@ -0,0 +1,61 @@
import type { GetAgentParams, GetAgentResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const getAgentTool: ToolConfig<GetAgentParams, GetAgentResponse> = {
id: 'cursor_get_agent',
name: 'Cursor Get Agent',
description: 'Retrieve the current status and results of a cloud agent.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
agentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier for the cloud agent (e.g., bc_abc123)',
},
},
request: {
url: (params) => `https://api.cursor.com/v0/agents/${params.agentId}`,
method: 'GET',
headers: (params) => ({
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
return {
success: true,
output: {
content: `Agent "${data.name}" is ${data.status}`,
metadata: data,
},
}
},
outputs: {
content: { type: 'string', description: 'Human-readable agent details' },
metadata: {
type: 'object',
description: 'Agent metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
name: { type: 'string', description: 'Agent name' },
status: { type: 'string', description: 'Agent status' },
source: { type: 'object', description: 'Source repository info' },
target: { type: 'object', description: 'Target branch info' },
summary: { type: 'string', description: 'Agent summary', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
},
},
},
}
+63
View File
@@ -0,0 +1,63 @@
import type { GetConversationParams, GetConversationResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const getConversationTool: ToolConfig<GetConversationParams, GetConversationResponse> = {
id: 'cursor_get_conversation',
name: 'Cursor Get Conversation',
description:
'Retrieve the conversation history of a cloud agent, including all user prompts and assistant responses.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
agentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier for the cloud agent (e.g., bc_abc123)',
},
},
request: {
url: (params) => `https://api.cursor.com/v0/agents/${params.agentId}/conversation`,
method: 'GET',
headers: (params) => ({
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
return {
success: true,
output: {
content: `Retrieved ${data.messages.length} messages`,
metadata: {
id: data.id,
messages: data.messages,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Human-readable conversation history' },
metadata: {
type: 'object',
description: 'Conversation metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
messages: {
type: 'array',
description: 'Array of conversation messages',
},
},
},
},
}
+15
View File
@@ -0,0 +1,15 @@
import { addFollowupTool } from '@/tools/cursor/add_followup'
import { deleteAgentTool } from '@/tools/cursor/delete_agent'
import { getAgentTool } from '@/tools/cursor/get_agent'
import { getConversationTool } from '@/tools/cursor/get_conversation'
import { launchAgentTool } from '@/tools/cursor/launch_agent'
import { listAgentsTool } from '@/tools/cursor/list_agents'
import { stopAgentTool } from '@/tools/cursor/stop_agent'
export const cursorListAgentsTool = listAgentsTool
export const cursorGetAgentTool = getAgentTool
export const cursorGetConversationTool = getConversationTool
export const cursorLaunchAgentTool = launchAgentTool
export const cursorAddFollowupTool = addFollowupTool
export const cursorStopAgentTool = stopAgentTool
export const cursorDeleteAgentTool = deleteAgentTool
+150
View File
@@ -0,0 +1,150 @@
import type { LaunchAgentParams, LaunchAgentResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const launchAgentTool: ToolConfig<LaunchAgentParams, LaunchAgentResponse> = {
id: 'cursor_launch_agent',
name: 'Cursor Launch Agent',
description:
'Start a new cloud agent to work on a GitHub repository with the given instructions.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
repository: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'GitHub repository URL (e.g., https://github.com/your-org/your-repo)',
},
ref: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Branch, tag, or commit to work from (defaults to default branch)',
},
promptText: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The instruction text for the agent',
},
promptImages: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'JSON array of image objects with base64 data and dimensions',
},
model: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Model to use (leave empty for auto-selection)',
},
branchName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom branch name for the agent to use',
},
autoCreatePr: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Automatically create a PR when the agent finishes',
},
openAsCursorGithubApp: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Open the PR as the Cursor GitHub App',
},
skipReviewerRequest: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Skip requesting reviewers on the PR',
},
},
request: {
url: () => 'https://api.cursor.com/v0/agents',
method: 'POST',
headers: (params) => ({
'Content-Type': 'application/json',
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
body: (params) => {
const body: Record<string, any> = {
source: {
repository: params.repository,
},
prompt: {
text: params.promptText,
},
}
if (params.ref) {
body.source.ref = params.ref
}
if (params.promptImages) {
try {
body.prompt.images = JSON.parse(params.promptImages)
} catch {
body.prompt.images = []
}
}
if (params.model) {
body.model = params.model
}
const target: Record<string, any> = {}
if (params.branchName) target.branchName = params.branchName
if (typeof params.autoCreatePr === 'boolean') target.autoCreatePr = params.autoCreatePr
if (typeof params.openAsCursorGithubApp === 'boolean')
target.openAsCursorGithubApp = params.openAsCursorGithubApp
if (typeof params.skipReviewerRequest === 'boolean')
target.skipReviewerRequest = params.skipReviewerRequest
if (Object.keys(target).length > 0) {
body.target = target
}
return body
},
},
transformResponse: async (response) => {
const data = await response.json()
const agentUrl = `https://cursor.com/agents?selectedBcId=${data.id}`
return {
success: true,
output: {
content: 'Agent launched successfully!',
metadata: {
id: data.id,
url: agentUrl,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Success message with agent details' },
metadata: {
type: 'object',
description: 'Launch result metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
url: { type: 'string', description: 'Agent URL' },
},
},
},
}
+77
View File
@@ -0,0 +1,77 @@
import type { ListAgentsParams, ListAgentsResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const listAgentsTool: ToolConfig<ListAgentsParams, ListAgentsResponse> = {
id: 'cursor_list_agents',
name: 'Cursor List Agents',
description: 'List all cloud agents for the authenticated user with optional pagination.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of agents to return (default: 20, max: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor from previous response',
},
},
request: {
url: (params) => {
const url = new URL('https://api.cursor.com/v0/agents')
if (params.limit) url.searchParams.set('limit', String(params.limit))
if (params.cursor) url.searchParams.set('cursor', params.cursor)
return url.toString()
},
method: 'GET',
headers: (params) => ({
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
return {
success: true,
output: {
content: `Found ${data.agents.length} agents`,
metadata: {
agents: data.agents,
nextCursor: data.nextCursor,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Human-readable list of agents' },
metadata: {
type: 'object',
description: 'Agent list metadata',
properties: {
agents: {
type: 'array',
description: 'Array of agent objects',
},
nextCursor: {
type: 'string',
description: 'Pagination cursor for next page',
optional: true,
},
},
},
},
}
+59
View File
@@ -0,0 +1,59 @@
import type { StopAgentParams, StopAgentResponse } from '@/tools/cursor/types'
import type { ToolConfig } from '@/tools/types'
export const stopAgentTool: ToolConfig<StopAgentParams, StopAgentResponse> = {
id: 'cursor_stop_agent',
name: 'Cursor Stop Agent',
description: 'Stop a running cloud agent. This pauses the agent without deleting it.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Cursor API key',
},
agentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier for the cloud agent (e.g., bc_abc123)',
},
},
request: {
url: (params) => `https://api.cursor.com/v0/agents/${params.agentId}/stop`,
method: 'POST',
headers: (params) => ({
Authorization: `Basic ${Buffer.from(`${params.apiKey}:`).toString('base64')}`,
}),
},
transformResponse: async (response) => {
const data = await response.json()
const content = `Agent ${data.id} has been stopped`
return {
success: true,
output: {
content,
metadata: {
id: data.id,
},
},
}
},
outputs: {
content: { type: 'string', description: 'Success message' },
metadata: {
type: 'object',
description: 'Result metadata',
properties: {
id: { type: 'string', description: 'Agent ID' },
},
},
},
}
+187
View File
@@ -0,0 +1,187 @@
import type { ToolResponse } from '@/tools/types'
export interface BaseCursorParams {
apiKey: string
}
export interface ListAgentsParams extends BaseCursorParams {
limit?: number
cursor?: string
}
export interface GetAgentParams extends BaseCursorParams {
agentId: string
}
export interface GetConversationParams extends BaseCursorParams {
agentId: string
}
export interface LaunchAgentParams extends BaseCursorParams {
repository: string
ref?: string
promptText: string
promptImages?: string
model?: string
branchName?: string
autoCreatePr?: boolean
openAsCursorGithubApp?: boolean
skipReviewerRequest?: boolean
}
export interface AddFollowupParams extends BaseCursorParams {
agentId: string
followupPromptText: string
promptImages?: string
}
export interface StopAgentParams extends BaseCursorParams {
agentId: string
}
export interface DeleteAgentParams extends BaseCursorParams {
agentId: string
}
interface AgentSource {
repository: string
ref: string
}
interface AgentTarget {
branchName: string
url: string
prUrl?: string
autoCreatePr: boolean
openAsCursorGithubApp: boolean
skipReviewerRequest: boolean
}
interface AgentMetadata {
id: string
name: string
status: 'RUNNING' | 'FINISHED' | 'STOPPED' | 'FAILED'
source: AgentSource
target: AgentTarget
summary?: string
createdAt: string
}
interface ConversationMessage {
id: string
type: 'user_message' | 'assistant_message'
text: string
}
interface RepositoryMetadata {
owner: string
name: string
repository: string
}
interface ApiKeyInfoMetadata {
apiKeyName: string
createdAt: string
userEmail: string
}
export interface ListAgentsResponse extends ToolResponse {
output: {
content: string
metadata: {
agents: AgentMetadata[]
nextCursor?: string
}
}
}
export interface GetAgentResponse extends ToolResponse {
output: {
content: string
metadata: AgentMetadata
}
}
export interface GetConversationResponse extends ToolResponse {
output: {
content: string
metadata: {
id: string
messages: ConversationMessage[]
}
}
}
export interface LaunchAgentResponse extends ToolResponse {
output: {
content: string
metadata: {
id: string
url: string
}
}
}
export interface AddFollowupResponse extends ToolResponse {
output: {
content: string
metadata: {
id: string
}
}
}
export interface StopAgentResponse extends ToolResponse {
output: {
content: string
metadata: {
id: string
}
}
}
export interface DeleteAgentResponse extends ToolResponse {
output: {
content: string
metadata: {
id: string
}
}
}
export interface GetApiKeyInfoResponse extends ToolResponse {
output: {
content: string
metadata: ApiKeyInfoMetadata
}
}
export interface ListModelsResponse extends ToolResponse {
output: {
content: string
metadata: {
models: string[]
}
}
}
export interface ListRepositoriesResponse extends ToolResponse {
output: {
content: string
metadata: {
repositories: RepositoryMetadata[]
}
}
}
export type CursorResponse =
| ListAgentsResponse
| GetAgentResponse
| GetConversationResponse
| LaunchAgentResponse
| AddFollowupResponse
| StopAgentResponse
| DeleteAgentResponse
| GetApiKeyInfoResponse
| ListModelsResponse
| ListRepositoriesResponse
+16
View File
@@ -81,6 +81,15 @@ import {
confluenceUpdateCommentTool,
confluenceUpdateTool,
} from '@/tools/confluence'
import {
cursorAddFollowupTool,
cursorDeleteAgentTool,
cursorGetAgentTool,
cursorGetConversationTool,
cursorLaunchAgentTool,
cursorListAgentsTool,
cursorStopAgentTool,
} from '@/tools/cursor'
import {
datadogCancelDowntimeTool,
datadogCreateDowntimeTool,
@@ -1787,6 +1796,13 @@ export const tools: Record<string, ToolConfig> = {
confluence_list_labels: confluenceListLabelsTool,
confluence_get_space: confluenceGetSpaceTool,
confluence_list_spaces: confluenceListSpacesTool,
cursor_list_agents: cursorListAgentsTool,
cursor_get_agent: cursorGetAgentTool,
cursor_get_conversation: cursorGetConversationTool,
cursor_launch_agent: cursorLaunchAgentTool,
cursor_add_followup: cursorAddFollowupTool,
cursor_stop_agent: cursorStopAgentTool,
cursor_delete_agent: cursorDeleteAgentTool,
trello_list_lists: trelloListListsTool,
trello_list_cards: trelloListCardsTool,
trello_create_card: trelloCreateCardTool,