@mindstudio-ai/agent 0.0.15 → 0.0.16

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/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # @mindstudio-ai/agent
2
2
 
3
- TypeScript SDK for executing MindStudio workflow steps. Each method calls a specific AI/automation action and returns typed results.
3
+ TypeScript SDK, CLI, and MCP server for executing MindStudio workflow steps. Each method calls a specific AI/automation action and returns typed results.
4
4
 
5
5
  This file is the complete API reference. No other documentation is needed to use the SDK.
6
6
 
@@ -12,6 +12,55 @@ npm install @mindstudio-ai/agent
12
12
 
13
13
  Requires Node.js >= 18.
14
14
 
15
+ ## CLI
16
+
17
+ The package includes a CLI for executing steps from the command line or scripts:
18
+
19
+ ```bash
20
+ # Execute with named flags (kebab-case)
21
+ mindstudio generate-image --prompt "A mountain landscape"
22
+
23
+ # Execute with JSON input (JSON5-tolerant)
24
+ mindstudio generate-image '{prompt: "A mountain landscape"}'
25
+
26
+ # Extract a single output field
27
+ mindstudio generate-image --prompt "A sunset" --output-key imageUrl
28
+
29
+ # List all available methods
30
+ mindstudio list
31
+
32
+ # Show method details (params, types, output)
33
+ mindstudio info generate-image
34
+
35
+ # Run via npx without installing
36
+ npx @mindstudio-ai/agent generate-text --message "Hello"
37
+ ```
38
+
39
+ Auth: set `MINDSTUDIO_API_KEY` env var or pass `--api-key <key>`.
40
+ Method names are kebab-case on the CLI (camelCase also accepted). Flags are kebab-case (`--video-url` for `videoUrl`).
41
+ Use `--output-key <key>` to extract a single field, `--no-meta` to strip $-prefixed metadata.
42
+
43
+ ## MCP server
44
+
45
+ The package includes an MCP server exposing all methods as tools:
46
+
47
+ ```bash
48
+ mindstudio mcp
49
+ ```
50
+
51
+ MCP client config:
52
+ ```json
53
+ {
54
+ "mcpServers": {
55
+ "mindstudio": {
56
+ "command": "npx",
57
+ "args": ["-y", "@mindstudio-ai/agent", "mcp"],
58
+ "env": { "MINDSTUDIO_API_KEY": "your-api-key" }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
15
64
  ## Setup
16
65
 
17
66
  ```typescript
@@ -53,6 +102,8 @@ result.content; // step-specific output field
53
102
  result.$appId; // string — app ID for this execution
54
103
  result.$threadId; // string — thread ID for this execution
55
104
  result.$rateLimitRemaining; // number | undefined — API calls remaining in rate limit window
105
+ result.$billingCost; // number | undefined — cost in credits for this call
106
+ result.$billingEvents; // object[] | undefined — itemized billing events
56
107
  ```
57
108
 
58
109
  ## Thread persistence
@@ -215,7 +266,7 @@ Fetch the full extracted text contents of a document in a data source.
215
266
  #### fetchSlackChannelHistory
216
267
  Fetch recent message history from a Slack channel.
217
268
  - The user is responsible for connecting their Slack workspace and selecting the channel
218
- - Input: `{ connectionId: string, channelId: string, limit?: number, startDate?: string, endDate?: string, includeImages?: boolean, includeRawMessage?: boolean }`
269
+ - Input: `{ connectionId?: string, channelId: string, limit?: number, startDate?: string, endDate?: string, includeImages?: boolean, includeRawMessage?: boolean }`
219
270
  - Output: `{ messages: { from: string, content: string, timestamp?: string, images?: string[], rawMessage?: { app_id?: string, assistant_app_thread?: { first_user_thread_reply?: string, title?: string, title_blocks?: unknown[] }, attachments?: { actions?: unknown[], app_id?: string, app_unfurl_url?: string, author_icon?: string, author_id?: string, author_link?: string, author_name?: string, author_subname?: string, blocks?: unknown[], bot_id?: string, bot_team_id?: string, callback_id?: string, channel_id?: string, channel_name?: string, channel_team?: string, color?: string, fallback?: string, fields?: unknown[], file_id?: string, filename?: string, files?: unknown[], footer?: string, footer_icon?: string, from_url?: string, hide_border?: boolean, hide_color?: boolean, id?: number, image_bytes?: number, image_height?: number, image_url?: string, image_width?: number, indent?: boolean, is_app_unfurl?: boolean, is_file_attachment?: boolean, is_msg_unfurl?: boolean, is_reply_unfurl?: boolean, is_thread_root_unfurl?: boolean, list?: unknown, list_record?: unknown, list_record_id?: string, list_records?: unknown[], list_schema?: unknown[], list_view?: unknown, list_view_id?: string, message_blocks?: unknown[], metadata?: unknown, mimetype?: string, mrkdwn_in?: string[], msg_subtype?: string, original_url?: string, pretext?: string, preview?: unknown, service_icon?: string, service_name?: string, service_url?: string, size?: number, text?: string, thumb_height?: number, thumb_url?: string, thumb_width?: number, title?: string, title_link?: string, ts?: string, url?: string, video_html?: string, video_html_height?: number, video_html_width?: number, video_url?: string }[], blocks?: { accessory?: unknown, alt_text?: string, api_decoration_available?: boolean, app_collaborators?: string[], app_id?: string, author_name?: string, block_id?: string, bot_user_id?: string, button_label?: string, call?: unknown, call_id?: string, description?: unknown, developer_trace_id?: string, dispatch_action?: boolean, element?: unknown, elements?: unknown[], expand?: boolean, external_id?: string, fallback?: string, fields?: unknown[], file?: unknown, file_id?: string, function_trigger_id?: string, hint?: unknown, image_bytes?: number, image_height?: number, image_url?: string, image_width?: number, is_animated?: boolean, is_workflow_app?: boolean, label?: unknown, optional?: boolean, owning_team_id?: string, provider_icon_url?: string, provider_name?: string, sales_home_workflow_app_type?: number, share_url?: string, slack_file?: unknown, source?: string, text?: unknown, thumbnail_url?: string, title?: unknown, title_url?: string, trigger_subtype?: string, trigger_type?: string, type?: unknown, url?: string, video_url?: string, workflow_id?: string }[], bot_id?: string, bot_profile?: { app_id?: string, deleted?: boolean, icons?: unknown, id?: string, name?: string, team_id?: string, updated?: number }, client_msg_id?: string, display_as_bot?: boolean, edited?: { ts?: string, user?: string }, files?: { access?: string, alt_txt?: string, app_id?: string, app_name?: string, attachments?: unknown[], blocks?: unknown[], bot_id?: string, can_toggle_canvas_lock?: boolean, canvas_printing_enabled?: boolean, canvas_template_mode?: string, cc?: unknown[], channel_actions_count?: number, channel_actions_ts?: string, channels?: string[], comments_count?: number, converted_pdf?: string, created?: number, deanimate?: string, deanimate_gif?: string, display_as_bot?: boolean, dm_mpdm_users_with_file_access?: unknown[], duration_ms?: number, edit_link?: string, edit_timestamp?: number, editable?: boolean, editor?: string, editors?: string[], external_id?: string, external_type?: string, external_url?: string, favorites?: unknown[], file_access?: string, filetype?: string, from?: unknown[], groups?: string[], has_more?: boolean, has_more_shares?: boolean, has_rich_preview?: boolean, headers?: unknown, hls?: string, hls_embed?: string, id?: string, image_exif_rotation?: number, ims?: string[], initial_comment?: unknown, is_channel_space?: boolean, is_external?: boolean, is_public?: boolean, is_restricted_sharing_enabled?: boolean, is_starred?: boolean, last_editor?: string, last_read?: number, lines?: number, lines_more?: number, linked_channel_id?: string, list_csv_download_url?: string, list_limits?: unknown, list_metadata?: unknown, media_display_type?: string, media_progress?: unknown, mimetype?: string, mode?: string, mp4?: string, mp4_low?: string, name?: string, non_owner_editable?: boolean, num_stars?: number, org_or_workspace_access?: string, original_attachment_count?: number, original_h?: string, original_w?: string, permalink?: string, permalink_public?: string, pinned_to?: string[], pjpeg?: string, plain_text?: string, pretty_type?: string, preview?: string, preview_highlight?: string, preview_is_truncated?: boolean, preview_plain_text?: string, private_channels_with_file_access_count?: number, private_file_with_access_count?: number, public_url_shared?: boolean, quip_thread_id?: string, reactions?: unknown[], saved?: unknown, sent_to_self?: boolean, shares?: unknown, show_badge?: boolean, simplified_html?: string, size?: number, source_team?: string, subject?: string, subtype?: string, team_pref_version_history_enabled?: boolean, teams_shared_with?: unknown[], template_conversion_ts?: number, template_description?: string, template_icon?: string, template_name?: string, template_title?: string, thumb_1024?: string, thumb_1024_gif?: string, thumb_1024_h?: string, thumb_1024_w?: string, thumb_160?: string, thumb_160_gif?: string, thumb_160_h?: string, thumb_160_w?: string, thumb_360?: string, thumb_360_gif?: string, thumb_360_h?: string, thumb_360_w?: string, thumb_480?: string, thumb_480_gif?: string, thumb_480_h?: string, thumb_480_w?: string, thumb_64?: string, thumb_64_gif?: string, thumb_64_h?: string, thumb_64_w?: string, thumb_720?: string, thumb_720_gif?: string, thumb_720_h?: string, thumb_720_w?: string, thumb_80?: string, thumb_800?: string, thumb_800_gif?: string, thumb_800_h?: string, thumb_800_w?: string, thumb_80_gif?: string, thumb_80_h?: string, thumb_80_w?: string, thumb_960?: string, thumb_960_gif?: string, thumb_960_h?: string, thumb_960_w?: string, thumb_gif?: string, thumb_pdf?: string, thumb_pdf_h?: string, thumb_pdf_w?: string, thumb_tiny?: string, thumb_video?: string, thumb_video_h?: number, thumb_video_w?: number, timestamp?: number, title?: string, title_blocks?: unknown[], to?: unknown[], transcription?: unknown, update_notification?: number, updated?: number, url_private?: string, url_private_download?: string, url_static_preview?: string, user?: string, user_team?: string, username?: string, vtt?: string }[], icons?: { emoji?: string, image_36?: string, image_48?: string, image_64?: string, image_72?: string }, inviter?: string, is_locked?: boolean, latest_reply?: string, metadata?: { event_payload?: unknown, event_type?: string }, parent_user_id?: string, purpose?: string, reactions?: { count?: number, name?: string, url?: string, users?: string[] }[], reply_count?: number, reply_users?: string[], reply_users_count?: number, root?: { bot_id?: string, icons?: unknown, latest_reply?: string, parent_user_id?: string, reply_count?: number, reply_users?: string[], reply_users_count?: number, subscribed?: boolean, subtype?: string, text?: string, thread_ts?: string, ts?: string, type?: string, username?: string }, subscribed?: boolean, subtype?: string, team?: string, text?: string, thread_ts?: string, topic?: string, ts?: string, type?: string, upload?: boolean, user?: string, username?: string, x_files?: string[] } }[] }`
220
271
 
221
272
  #### generateAsset
@@ -225,7 +276,7 @@ Generate an HTML asset and export it as a webpage, PDF, or image
225
276
  - If PDF or composited image generation are part of the workflow, assistant adds the block and leaves the "source" empty. In a separate step, assistant generates a detailed request for the developer who will write the HTML.
226
277
  - Can also auto-generate HTML from a prompt (like a generate text block to generate HTML). In these cases, create a prompt with variables in the dynamicPrompt variable describing, in detail, the document to generate
227
278
  - Can either display output directly to user (foreground mode) or save the URL of the asset to a variable (background mode)
228
- - Input: `{ source: string, sourceType: "html" | "markdown" | "spa" | "raw" | "dynamic" | "customInterface", outputFormat: "pdf" | "png" | "html" | "mp4" | "openGraph", pageSize: "full" | "letter" | "A4" | "custom", testData: object, options?: { pageWidthPx?: number, pageHeightPx?: number, pageOrientation?: "portrait" | "landscape", rehostMedia?: boolean, videoDurationSeconds?: number }, spaSource?: { paths: string[], root: string, zipUrl: string }, rawSource?: string, dynamicPrompt?: string, dynamicSourceModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, transitionControl?: "default" | "native", shareControl?: "default" | "hidden", shareImageUrl?: string, skipAssetCreation?: boolean }`
279
+ - Input: `{ source: string, sourceType: "html" | "markdown" | "spa" | "raw" | "dynamic" | "customInterface", outputFormat: "pdf" | "png" | "html" | "mp4" | "openGraph", pageSize: "full" | "letter" | "A4" | "custom", testData: object, options?: { pageWidthPx?: number, pageHeightPx?: number, pageOrientation?: "portrait" | "landscape", rehostMedia?: boolean, videoDurationSeconds?: number }, spaSource?: { source?: string, lastCompiledSource?: string, files?: object, paths: string[], root: string, zipUrl: string }, rawSource?: string, dynamicPrompt?: string, dynamicSourceModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, transitionControl?: "default" | "native", shareControl?: "default" | "hidden", shareImageUrl?: string, skipAssetCreation?: boolean }`
229
280
  - Output: `{ url: string }`
230
281
 
231
282
  #### generateChart
@@ -370,7 +421,7 @@ Send a message to a Slack channel via a connected bot.
370
421
  - The user is responsible for connecting their Slack workspace and selecting the channel
371
422
  - Supports both simple text messages and slack blocks messages
372
423
  - Text messages can use limited markdown (slack-only fomatting—e.g., headers are just rendered as bold)
373
- - Input: `{ channelId: string, messageType: "string" | "blocks", message: string, connectionId: string }`
424
+ - Input: `{ channelId: string, messageType: "string" | "blocks", message: string, connectionId?: string }`
374
425
  - Output: `unknown`
375
426
 
376
427
  #### postToZapier
@@ -393,7 +444,7 @@ Execute a SQL query against an external database connected to the workspace.
393
444
  - Requires a database connection configured in the workspace.
394
445
  - Supports PostgreSQL (including Supabase), MySQL, and MSSQL.
395
446
  - Results can be returned as JSON or CSV.
396
- - Input: `{ connectionId: string, query: string, outputFormat: "json" | "csv" }`
447
+ - Input: `{ connectionId?: string, query: string, outputFormat: "json" | "csv" }`
397
448
  - Output: `{ data: unknown }`
398
449
 
399
450
  #### redactPII
@@ -503,13 +554,13 @@ Send an email to one or more configured recipient addresses.
503
554
  - When generateHtml is enabled, the body text is converted to a styled HTML email using an AI model.
504
555
  - connectionId can be a comma-separated list to send to multiple recipients.
505
556
  - The special connectionId "trigger_email" uses the email address that triggered the workflow.
506
- - Input: `{ subject: string, body: string, connectionId: string, generateHtml?: boolean, generateHtmlInstructions?: string, generateHtmlModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, attachments?: string[] }`
557
+ - Input: `{ subject: string, body: string, connectionId?: string, generateHtml?: boolean, generateHtmlInstructions?: string, generateHtmlModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, attachments?: string[] }`
507
558
  - Output: `{ recipients: string[] }`
508
559
 
509
560
  #### sendSMS
510
561
  Send an SMS text message to a phone number configured via OAuth connection.
511
562
  - User is responsible for configuring the connection to the number (MindStudio requires double opt-in to prevent spam)
512
- - Input: `{ body: string, connectionId: string }`
563
+ - Input: `{ body: string, connectionId?: string }`
513
564
  - Output: `unknown`
514
565
 
515
566
  #### setRunTitle
@@ -522,8 +573,8 @@ Explicitly set a variable to a given value.
522
573
  - Useful for bootstrapping global variables or setting constants.
523
574
  - The variable name and value both support variable interpolation.
524
575
  - The type field is a UI hint only (controls input widget in the editor).
525
- - Input: `{ value: string | string[], type: "imageUrl" | "videoUrl" | "fileUrl" | "plaintext" | "textArray" | "imageUrlArray" | "videoUrlArray" }`
526
- - Output: `{ variableName: string, value: string | string[] }`
576
+ - Input: `{ value: string | string[] }`
577
+ - Output: `object`
527
578
 
528
579
  #### telegramSendAudio
529
580
  Send an audio file to a Telegram chat as music or a voice note via a bot.
@@ -630,7 +681,7 @@ Add an image watermark to a video
630
681
  Add a note to an existing contact in ActiveCampaign.
631
682
  - Requires an ActiveCampaign OAuth connection (connectionId).
632
683
  - The contact must already exist — use the contact ID from a previous create or search step.
633
- - Input: `{ contactId: string, note: string, connectionId: string }`
684
+ - Input: `{ contactId: string, note: string, connectionId?: string }`
634
685
  - Output: `unknown`
635
686
 
636
687
  #### activeCampaignCreateContact
@@ -638,7 +689,7 @@ Create or sync a contact in ActiveCampaign.
638
689
  - Requires an ActiveCampaign OAuth connection (connectionId).
639
690
  - If a contact with the email already exists, it may be updated depending on ActiveCampaign settings.
640
691
  - Custom fields are passed as a key-value map where keys are field IDs.
641
- - Input: `{ email: string, firstName: string, lastName: string, phone: string, accountId: string, customFields: object, connectionId: string }`
692
+ - Input: `{ email: string, firstName: string, lastName: string, phone: string, accountId: string, customFields: object, connectionId?: string }`
642
693
  - Output: `{ contactId: string }`
643
694
 
644
695
  ### Airtable
@@ -648,21 +699,21 @@ Create a new record or update an existing record in an Airtable table.
648
699
  - If recordId is provided, updates that record. Otherwise, creates a new one.
649
700
  - When updating with updateMode "onlySpecified", unspecified fields are left as-is. With "all", unspecified fields are cleared.
650
701
  - Array fields (e.g. multipleAttachments) accept arrays of values.
651
- - Input: `{ connectionId: string, baseId: string, tableId: string, recordId?: string, updateMode?: "onlySpecified" | "all", fields: unknown, recordData: object }`
702
+ - Input: `{ connectionId?: string, baseId: string, tableId: string, recordId?: string, updateMode?: "onlySpecified" | "all", fields: unknown, recordData: object }`
652
703
  - Output: `{ recordId: string }`
653
704
 
654
705
  #### airtableDeleteRecord
655
706
  Delete a record from an Airtable table by its record ID.
656
707
  - Requires an active Airtable OAuth connection (connectionId).
657
708
  - Silently succeeds if the record does not exist.
658
- - Input: `{ connectionId: string, baseId: string, tableId: string, recordId: string }`
709
+ - Input: `{ connectionId?: string, baseId: string, tableId: string, recordId: string }`
659
710
  - Output: `{ deleted: boolean }`
660
711
 
661
712
  #### airtableGetRecord
662
713
  Fetch a single record from an Airtable table by its record ID.
663
714
  - Requires an active Airtable OAuth connection (connectionId).
664
715
  - If the record is not found, returns a string message instead of a record object.
665
- - Input: `{ connectionId: string, baseId: string, tableId: string, recordId: string }`
716
+ - Input: `{ connectionId?: string, baseId: string, tableId: string, recordId: string }`
666
717
  - Output: `{ record: { id: string, createdTime: string, fields: object } | null }`
667
718
 
668
719
  #### airtableGetTableRecords
@@ -670,7 +721,7 @@ Fetch multiple records from an Airtable table with optional pagination.
670
721
  - Requires an active Airtable OAuth connection (connectionId).
671
722
  - Default limit is 100 records. Maximum is 1000.
672
723
  - When outputFormat is 'csv', the variable receives CSV text. The direct execution output always returns parsed records.
673
- - Input: `{ connectionId: string, baseId: string, tableId: string, outputFormat?: "json" | "csv", limit?: number }`
724
+ - Input: `{ connectionId?: string, baseId: string, tableId: string, outputFormat?: "json" | "csv", limit?: number }`
674
725
  - Output: `{ records: { id: string, createdTime: string, fields: object }[] }`
675
726
 
676
727
  ### Apollo
@@ -699,7 +750,7 @@ Create a new page or update an existing page in a Coda document.
699
750
  - If pageData.pageId is provided, updates that page. Otherwise, creates a new one.
700
751
  - Page content is provided as markdown and converted to Coda's canvas format.
701
752
  - When updating, insertionMode controls how content is applied (default: 'append').
702
- - Input: `{ connectionId: string, pageData: { docId: string, pageId?: string, name: string, subtitle: string, iconName: string, imageUrl: string, parentPageId?: string, pageContent: string | unknown, contentUpdate?: unknown, insertionMode?: string } }`
753
+ - Input: `{ connectionId?: string, pageData: { docId: string, pageId?: string, name: string, subtitle: string, iconName: string, imageUrl: string, parentPageId?: string, pageContent: string | unknown, contentUpdate?: unknown, insertionMode?: string } }`
703
754
  - Output: `{ pageId: string }`
704
755
 
705
756
  #### codaCreateUpdateRow
@@ -707,7 +758,7 @@ Create a new row or update an existing row in a Coda table.
707
758
  - Requires a Coda OAuth connection (connectionId).
708
759
  - If rowId is provided, updates that row. Otherwise, creates a new one.
709
760
  - Row data keys are column IDs. Empty values are excluded.
710
- - Input: `{ connectionId: string, docId: string, tableId: string, rowId?: string, rowData: object }`
761
+ - Input: `{ connectionId?: string, docId: string, tableId: string, rowId?: string, rowData: object }`
711
762
  - Output: `{ rowId: string }`
712
763
 
713
764
  #### codaFindRow
@@ -715,7 +766,7 @@ Search for a row in a Coda table by matching column values.
715
766
  - Requires a Coda OAuth connection (connectionId).
716
767
  - Returns the first row matching all specified column values, or null if no match.
717
768
  - Search criteria in rowData are ANDed together.
718
- - Input: `{ connectionId: string, docId: string, tableId: string, rowData: object }`
769
+ - Input: `{ connectionId?: string, docId: string, tableId: string, rowData: object }`
719
770
  - Output: `{ row: { id: string, values: object } | null }`
720
771
 
721
772
  #### codaGetPage
@@ -723,7 +774,7 @@ Export and read the contents of a page from a Coda document.
723
774
  - Requires a Coda OAuth connection (connectionId).
724
775
  - Page export is asynchronous on Coda's side — there may be a brief delay while it processes.
725
776
  - If a page was just created in a prior step, there is an automatic 20-second retry if the first export attempt fails.
726
- - Input: `{ connectionId: string, docId: string, pageId: string, outputFormat?: "html" | "markdown" }`
777
+ - Input: `{ connectionId?: string, docId: string, pageId: string, outputFormat?: "html" | "markdown" }`
727
778
  - Output: `{ content: string }`
728
779
 
729
780
  #### codaGetTableRows
@@ -731,7 +782,7 @@ Fetch rows from a Coda table with optional pagination.
731
782
  - Requires a Coda OAuth connection (connectionId).
732
783
  - Default limit is 10000 rows. Rows are fetched in pages of 500.
733
784
  - When outputFormat is 'csv', the variable receives CSV text. The direct execution output always returns parsed rows.
734
- - Input: `{ connectionId: string, docId: string, tableId: string, limit?: number | string, outputFormat?: "json" | "csv" }`
785
+ - Input: `{ connectionId?: string, docId: string, tableId: string, limit?: number | string, outputFormat?: "json" | "csv" }`
735
786
  - Output: `{ rows: { id: string, values: object }[] }`
736
787
 
737
788
  ### Facebook
@@ -746,44 +797,98 @@ Get all the posts for a Facebook page
746
797
  - Input: `{ pageUrl: string }`
747
798
  - Output: `{ data: unknown }`
748
799
 
800
+ ### Gmail
801
+
802
+ #### deleteGmailEmail
803
+ Move an email to trash in the connected Gmail account (recoverable delete).
804
+ - Requires a Google OAuth connection with Gmail modify scope.
805
+ - Uses trash (recoverable) rather than permanent delete.
806
+ - Input: `{ messageId: string, connectionId?: string }`
807
+ - Output: `unknown`
808
+
809
+ #### getGmailDraft
810
+ Retrieve a specific draft from Gmail by draft ID.
811
+ - Requires a Google OAuth connection with Gmail readonly scope.
812
+ - Returns the draft content including subject, recipients, sender, and body.
813
+ - Input: `{ draftId: string, connectionId?: string }`
814
+ - Output: `{ draftId: string, messageId: string, subject: string, to: string, from: string, body: string }`
815
+
816
+ #### getGmailEmail
817
+ Retrieve a specific email from Gmail by message ID.
818
+ - Requires a Google OAuth connection with Gmail readonly scope.
819
+ - Returns the email subject, sender, recipient, date, body (plain text preferred, falls back to HTML), and labels.
820
+ - Input: `{ messageId: string, connectionId?: string }`
821
+ - Output: `{ messageId: string, subject: string, from: string, to: string, date: string, body: string, labels: string }`
822
+
823
+ #### listGmailDrafts
824
+ List drafts in the connected Gmail account.
825
+ - Requires a Google OAuth connection with Gmail readonly scope.
826
+ - Returns up to 50 drafts (default 10).
827
+ - The variable receives text or JSON depending on exportType.
828
+ - Input: `{ connectionId?: string, limit?: string, exportType: "json" | "text" }`
829
+ - Output: `{ drafts: { draftId: string, messageId: string, subject: string, to: string, snippet: string }[] }`
830
+
831
+ #### replyToGmailEmail
832
+ Reply to an existing email in Gmail. The reply is threaded under the original message.
833
+ - Requires a Google OAuth connection with Gmail compose and readonly scopes.
834
+ - The reply is sent to the original sender and threaded under the original message.
835
+ - messageType controls the body format: "plain", "html", or "markdown".
836
+ - Input: `{ messageId: string, message: string, messageType: "plain" | "html" | "markdown", connectionId?: string }`
837
+ - Output: `{ messageId: string }`
838
+
749
839
  ### Google
750
840
 
751
841
  #### createGoogleDoc
752
842
  Create a new Google Document and optionally populate it with content.
753
843
  - textType determines how the text field is interpreted: "plain" for plain text, "html" for HTML markup, "markdown" for Markdown.
754
- - Input: `{ title: string, text: string, connectionId: string, textType: "plain" | "html" | "markdown" }`
844
+ - Input: `{ title: string, text: string, connectionId?: string, textType: "plain" | "html" | "markdown" }`
755
845
  - Output: `{ documentUrl: string }`
756
846
 
757
847
  #### createGoogleSheet
758
848
  Create a new Google Spreadsheet and populate it with CSV data.
759
- - Input: `{ title: string, text: string, connectionId: string }`
849
+ - Input: `{ title: string, text: string, connectionId?: string }`
760
850
  - Output: `{ spreadsheetUrl: string }`
761
851
 
852
+ #### deleteGoogleSheetRows
853
+ Delete a range of rows from a Google Spreadsheet.
854
+ - Requires a Google OAuth connection with Drive scope.
855
+ - startRow and endRow are 1-based row numbers (inclusive).
856
+ - If sheetName is omitted, operates on the first sheet.
857
+ - Input: `{ documentId: string, sheetName?: string, startRow: string, endRow: string, connectionId?: string }`
858
+ - Output: `unknown`
859
+
762
860
  #### fetchGoogleDoc
763
861
  Fetch the contents of an existing Google Document.
764
862
  - exportType controls the output format: "html" for HTML markup, "markdown" for Markdown, "json" for structured JSON, "plain" for plain text.
765
- - Input: `{ documentId: string, connectionId: string, exportType: "html" | "markdown" | "json" | "plain" }`
863
+ - Input: `{ documentId: string, connectionId?: string, exportType: "html" | "markdown" | "json" | "plain" }`
766
864
  - Output: `{ content: string }`
767
865
 
768
866
  #### fetchGoogleSheet
769
867
  Fetch contents of a Google Spreadsheet range.
770
868
  - range uses A1 notation (e.g. "Sheet1!A1:C10"). Omit to fetch the entire first sheet.
771
869
  - exportType controls the output format: "csv" for comma-separated values, "json" for structured JSON.
772
- - Input: `{ spreadsheetId: string, range: string, connectionId: string, exportType: "csv" | "json" }`
870
+ - Input: `{ spreadsheetId: string, range: string, connectionId?: string, exportType: "csv" | "json" }`
773
871
  - Output: `{ content: string }`
774
872
 
873
+ #### getGoogleSheetInfo
874
+ Get metadata about a Google Spreadsheet including sheet names, row counts, and column counts.
875
+ - Requires a Google OAuth connection with Drive scope.
876
+ - Returns the spreadsheet title and a list of all sheets with their dimensions.
877
+ - Input: `{ documentId: string, connectionId?: string }`
878
+ - Output: `{ title: string, sheets: { sheetId: number, title: string, rowCount: number, columnCount: number }[] }`
879
+
775
880
  #### updateGoogleDoc
776
881
  Update the contents of an existing Google Document.
777
882
  - operationType controls how content is applied: "addToTop" prepends, "addToBottom" appends, "overwrite" replaces all content.
778
883
  - textType determines how the text field is interpreted: "plain" for plain text, "html" for HTML markup, "markdown" for Markdown.
779
- - Input: `{ documentId: string, connectionId: string, text: string, textType: "plain" | "html" | "markdown", operationType: "addToTop" | "addToBottom" | "overwrite" }`
884
+ - Input: `{ documentId: string, connectionId?: string, text: string, textType: "plain" | "html" | "markdown", operationType: "addToTop" | "addToBottom" | "overwrite" }`
780
885
  - Output: `{ documentUrl: string }`
781
886
 
782
887
  #### updateGoogleSheet
783
888
  Update a Google Spreadsheet with new data.
784
889
  - operationType controls how data is written: "addToBottom" appends rows, "overwrite" replaces all data, "range" writes to a specific cell range.
785
890
  - Data should be provided as CSV in the text field.
786
- - Input: `{ text: string, connectionId: string, spreadsheetId: string, range: string, operationType: "addToBottom" | "overwrite" | "range" }`
891
+ - Input: `{ text: string, connectionId?: string, spreadsheetId: string, range: string, operationType: "addToBottom" | "overwrite" | "range" }`
787
892
  - Output: `{ spreadsheetUrl: string }`
788
893
 
789
894
  ### Google Calendar
@@ -794,21 +899,21 @@ Create a new event on a Google Calendar.
794
899
  - Date/time values must be ISO 8601 format (e.g. "2025-07-02T10:00:00-07:00").
795
900
  - Attendees are specified as one email address per line in a single string.
796
901
  - Set addMeetLink to true to automatically attach a Google Meet video call.
797
- - Input: `{ connectionId: string, summary: string, description?: string, location?: string, startDateTime: string, endDateTime: string, attendees?: string, addMeetLink?: boolean, calendarId?: string }`
902
+ - Input: `{ connectionId?: string, summary: string, description?: string, location?: string, startDateTime: string, endDateTime: string, attendees?: string, addMeetLink?: boolean, calendarId?: string }`
798
903
  - Output: `{ eventId: string, htmlLink: string }`
799
904
 
800
905
  #### deleteGoogleCalendarEvent
801
906
  Retrieve a specific event from a Google Calendar by event ID.
802
907
  - Requires a Google OAuth connection with Calendar events scope.
803
908
  - The variable receives JSON or XML-like text depending on exportType. The direct execution output always returns the structured event.
804
- - Input: `{ connectionId: string, eventId: string, calendarId?: string }`
909
+ - Input: `{ connectionId?: string, eventId: string, calendarId?: string }`
805
910
  - Output: `unknown`
806
911
 
807
912
  #### getGoogleCalendarEvent
808
913
  Retrieve a specific event from a Google Calendar by event ID.
809
914
  - Requires a Google OAuth connection with Calendar events scope.
810
915
  - The variable receives JSON or XML-like text depending on exportType. The direct execution output always returns the structured event.
811
- - Input: `{ connectionId: string, eventId: string, exportType: "json" | "text", calendarId?: string }`
916
+ - Input: `{ connectionId?: string, eventId: string, exportType: "json" | "text", calendarId?: string }`
812
917
  - Output: `{ event: { id?: string | null, status?: string | null, htmlLink?: string | null, created?: string | null, updated?: string | null, summary?: string | null, description?: string | null, location?: string | null, organizer?: { displayName?: string | null, email?: string | null } | null, start?: { dateTime?: string | null, timeZone?: string | null } | null, end?: { dateTime?: string | null, timeZone?: string | null } | null, attendees?: ({ displayName?: string | null, email?: string | null, responseStatus?: string | null })[] | null } }`
813
918
 
814
919
  #### listGoogleCalendarEvents
@@ -816,7 +921,15 @@ List upcoming events from a Google Calendar, ordered by start time.
816
921
  - Requires a Google OAuth connection with Calendar events scope.
817
922
  - Only returns future events (timeMin = now).
818
923
  - The variable receives JSON or XML-like text depending on exportType. The direct execution output always returns structured events.
819
- - Input: `{ connectionId: string, limit: number, exportType: "json" | "text", calendarId?: string }`
924
+ - Input: `{ connectionId?: string, limit: number, exportType: "json" | "text", calendarId?: string }`
925
+ - Output: `{ events: ({ id?: string | null, status?: string | null, htmlLink?: string | null, created?: string | null, updated?: string | null, summary?: string | null, description?: string | null, location?: string | null, organizer?: { displayName?: string | null, email?: string | null } | null, start?: { dateTime?: string | null, timeZone?: string | null } | null, end?: { dateTime?: string | null, timeZone?: string | null } | null, attendees?: ({ displayName?: string | null, email?: string | null, responseStatus?: string | null })[] | null })[] }`
926
+
927
+ #### searchGoogleCalendarEvents
928
+ Search for events in a Google Calendar by keyword, date range, or both.
929
+ - Requires a Google OAuth connection with Calendar events scope.
930
+ - Supports keyword search via "query" and date filtering via "timeMin"/"timeMax" (ISO 8601 format).
931
+ - Unlike "List Events" which only shows future events, this allows searching past events too.
932
+ - Input: `{ query?: string, timeMin?: string, timeMax?: string, calendarId?: string, limit?: number, exportType: "json" | "text", connectionId?: string }`
820
933
  - Output: `{ events: ({ id?: string | null, status?: string | null, htmlLink?: string | null, created?: string | null, updated?: string | null, summary?: string | null, description?: string | null, location?: string | null, organizer?: { displayName?: string | null, email?: string | null } | null, start?: { dateTime?: string | null, timeZone?: string | null } | null, end?: { dateTime?: string | null, timeZone?: string | null } | null, attendees?: ({ displayName?: string | null, email?: string | null, responseStatus?: string | null })[] | null })[] }`
821
934
 
822
935
  #### updateGoogleCalendarEvent
@@ -824,9 +937,35 @@ Update an existing event on a Google Calendar. Only specified fields are changed
824
937
  - Requires a Google OAuth connection with Calendar events scope.
825
938
  - Fetches the existing event first, then applies only the provided updates. Omitted fields are left unchanged.
826
939
  - Attendees are specified as one email address per line, and replace the entire attendee list.
827
- - Input: `{ connectionId: string, eventId: string, summary?: string, description?: string, location?: string, startDateTime?: string, endDateTime?: string, attendees?: string, calendarId?: string }`
940
+ - Input: `{ connectionId?: string, eventId: string, summary?: string, description?: string, location?: string, startDateTime?: string, endDateTime?: string, attendees?: string, calendarId?: string }`
828
941
  - Output: `{ eventId: string, htmlLink: string }`
829
942
 
943
+ ### Google Drive
944
+
945
+ #### getGoogleDriveFile
946
+ Download a file from Google Drive and rehost it on the CDN. Returns a public CDN URL.
947
+ - Requires a Google OAuth connection with Drive scope.
948
+ - Google-native files (Docs, Sheets, Slides) cannot be downloaded — use dedicated steps instead.
949
+ - Maximum file size: 200MB.
950
+ - The file is downloaded and re-uploaded to the CDN; the returned URL is publicly accessible.
951
+ - Input: `{ fileId: string, connectionId?: string }`
952
+ - Output: `{ url: string, name: string, mimeType: string, size: number }`
953
+
954
+ #### listGoogleDriveFiles
955
+ List files in a Google Drive folder.
956
+ - Requires a Google OAuth connection with Drive scope.
957
+ - If folderId is omitted, lists files in the root folder.
958
+ - Returns file metadata including name, type, size, and links.
959
+ - Input: `{ folderId?: string, limit?: number, connectionId?: string, exportType: "json" | "text" }`
960
+ - Output: `{ files: { id: string, name: string, mimeType: string, size: string, webViewLink: string, createdTime: string, modifiedTime: string }[] }`
961
+
962
+ #### searchGoogleDrive
963
+ Search for files in Google Drive by keyword.
964
+ - Requires a Google OAuth connection with Drive scope.
965
+ - Searches file content and names using Google Drive's fullText search.
966
+ - Input: `{ query: string, limit?: number, connectionId?: string, exportType: "json" | "text" }`
967
+ - Output: `{ files: { id: string, name: string, mimeType: string, size: string, webViewLink: string, createdTime: string, modifiedTime: string }[] }`
968
+
830
969
  ### HubSpot
831
970
 
832
971
  #### hubspotCreateCompany
@@ -834,7 +973,7 @@ Create a new company or update an existing one in HubSpot. Matches by domain.
834
973
  - Requires a HubSpot OAuth connection (connectionId).
835
974
  - If a company with the given domain already exists, it is updated. Otherwise, a new one is created.
836
975
  - Property values are type-checked against enabledProperties before being sent to HubSpot.
837
- - Input: `{ connectionId: string, company: { domain: string, name: string }, enabledProperties: ({ label: string, value: string, type: "string" | "number" | "bool" })[] }`
976
+ - Input: `{ connectionId?: string, company: { domain: string, name: string }, enabledProperties: ({ label: string, value: string, type: "string" | "number" | "bool" })[] }`
838
977
  - Output: `{ companyId: string }`
839
978
 
840
979
  #### hubspotCreateContact
@@ -843,7 +982,7 @@ Create a new contact or update an existing one in HubSpot. Matches by email addr
843
982
  - If a contact with the given email already exists, it is updated. Otherwise, a new one is created.
844
983
  - If companyDomain is provided, the contact is associated with that company (creating the company if needed).
845
984
  - Property values are type-checked against enabledProperties before being sent to HubSpot.
846
- - Input: `{ connectionId: string, contact: { email: string, firstname: string, lastname: string }, enabledProperties: ({ label: string, value: string, type: "string" | "number" | "bool" })[], companyDomain: string }`
985
+ - Input: `{ connectionId?: string, contact: { email: string, firstname: string, lastname: string }, enabledProperties: ({ label: string, value: string, type: "string" | "number" | "bool" })[], companyDomain: string }`
847
986
  - Output: `{ contactId: string }`
848
987
 
849
988
  #### hubspotGetCompany
@@ -852,7 +991,7 @@ Look up a HubSpot company by domain name or company ID.
852
991
  - Returns null if the company is not found.
853
992
  - When searching by domain, performs a search query then fetches the full company record.
854
993
  - Use additionalProperties to request specific HubSpot properties beyond the defaults.
855
- - Input: `{ connectionId: string, searchBy: "domain" | "id", companyDomain: string, companyId: string, additionalProperties: string[] }`
994
+ - Input: `{ connectionId?: string, searchBy: "domain" | "id", companyDomain: string, companyId: string, additionalProperties: string[] }`
856
995
  - Output: `{ company: { id: string, properties: object, createdAt: string, updatedAt: string, archived: boolean } | null }`
857
996
 
858
997
  #### hubspotGetContact
@@ -860,7 +999,7 @@ Look up a HubSpot contact by email address or contact ID.
860
999
  - Requires a HubSpot OAuth connection (connectionId).
861
1000
  - Returns null if the contact is not found.
862
1001
  - Use additionalProperties to request specific HubSpot properties beyond the defaults.
863
- - Input: `{ connectionId: string, searchBy: "email" | "id", contactEmail: string, contactId: string, additionalProperties: string[] }`
1002
+ - Input: `{ connectionId?: string, searchBy: "email" | "id", contactEmail: string, contactId: string, additionalProperties: string[] }`
864
1003
  - Output: `{ contact: { id: string, properties: object, createdAt: string, updatedAt: string, archived: boolean } | null }`
865
1004
 
866
1005
  ### Hunter.io
@@ -936,7 +1075,7 @@ Create a post on LinkedIn from the connected account.
936
1075
  - Requires a LinkedIn OAuth connection (connectionId).
937
1076
  - Supports text posts, image posts, and video posts.
938
1077
  - Visibility controls who can see the post.
939
- - Input: `{ message: string, visibility: "PUBLIC" | "CONNECTIONS", videoUrl?: string, descriptionText?: string, titleText?: string, imageUrl?: string, connectionId: string }`
1078
+ - Input: `{ message: string, visibility: "PUBLIC" | "CONNECTIONS", videoUrl?: string, descriptionText?: string, titleText?: string, imageUrl?: string, connectionId?: string }`
940
1079
  - Output: `unknown`
941
1080
 
942
1081
  ### Meta Threads
@@ -953,7 +1092,7 @@ Create a new page in Notion as a child of an existing page.
953
1092
  - Requires a Notion OAuth connection (connectionId).
954
1093
  - Content is provided as markdown and converted to Notion blocks (headings, paragraphs, lists, code, quotes).
955
1094
  - The page is created as a child of the specified parent page (pageId).
956
- - Input: `{ pageId: string, content: string, title: string, connectionId: string }`
1095
+ - Input: `{ pageId: string, content: string, title: string, connectionId?: string }`
957
1096
  - Output: `{ pageId: string, pageUrl: string }`
958
1097
 
959
1098
  #### notionUpdatePage
@@ -961,7 +1100,7 @@ Update the content of an existing Notion page.
961
1100
  - Requires a Notion OAuth connection (connectionId).
962
1101
  - Content is provided as markdown and converted to Notion blocks.
963
1102
  - "append" mode adds content to the end of the page. "overwrite" mode deletes all existing blocks first.
964
- - Input: `{ pageId: string, content: string, mode: "append" | "overwrite", connectionId: string }`
1103
+ - Input: `{ pageId: string, content: string, mode: "append" | "overwrite", connectionId?: string }`
965
1104
  - Output: `{ pageId: string, pageUrl: string }`
966
1105
 
967
1106
  ### X
@@ -970,7 +1109,7 @@ Update the content of an existing Notion page.
970
1109
  Create a post on X (Twitter) from the connected account.
971
1110
  - Requires an X OAuth connection (connectionId).
972
1111
  - Posts are plain text. Maximum 280 characters.
973
- - Input: `{ text: string, connectionId: string }`
1112
+ - Input: `{ text: string, connectionId?: string }`
974
1113
  - Output: `unknown`
975
1114
 
976
1115
  #### searchXPosts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/agent",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "TypeScript SDK for MindStudio direct step execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,6 +12,9 @@
12
12
  "default": "./dist/index.js"
13
13
  }
14
14
  },
15
+ "bin": {
16
+ "mindstudio": "./dist/cli.js"
17
+ },
15
18
  "files": [
16
19
  "dist",
17
20
  "llms.txt"