terse-types 0.0.73 → 0.0.75

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/dist/Tools.js CHANGED
@@ -957,6 +957,7 @@ export const searchPosthogEventsInputSchema = z.object({
957
957
  });
958
958
  export const linearCreateTicketTool = defineTool({
959
959
  name: "linear_create_ticket",
960
+ description: "Create a new Linear issue/ticket.",
960
961
  inputSchema: linearCreateTicketInputSchema,
961
962
  outputSchema: toolOutputBaseSchema.extend({
962
963
  issue: linearIssueHandleSchema
@@ -964,6 +965,7 @@ export const linearCreateTicketTool = defineTool({
964
965
  });
965
966
  export const linearUpdateTicketTool = defineTool({
966
967
  name: "linear_update_ticket",
968
+ description: `Update an existing Linear issue/ticket. Use linear_search_ticket to find the issue ID, and linear_get_states, linear_get_users, linear_get_projects, linear_get_teams to find valid IDs for each field.`,
967
969
  inputSchema: linearUpdateTicketInputSchema,
968
970
  outputSchema: toolOutputBaseSchema.extend({
969
971
  issue: linearIssueHandleSchema
@@ -971,6 +973,7 @@ export const linearUpdateTicketTool = defineTool({
971
973
  });
972
974
  export const linearAddCommentTool = defineTool({
973
975
  name: "linear_add_comment",
976
+ description: `Add a comment to an existing Linear issue. Use linear_search_ticket to find the issue ID.`,
974
977
  inputSchema: linearAddCommentInputSchema,
975
978
  outputSchema: toolOutputBaseSchema.extend({
976
979
  comment: linearCommentHandleSchema
@@ -978,6 +981,7 @@ export const linearAddCommentTool = defineTool({
978
981
  });
979
982
  export const linearSearchTicketTool = defineTool({
980
983
  name: "linear_search_ticket",
984
+ description: `Searches Linear issues by keyword, state filter, and/or date range filters. Use this before reading individual tickets. Results are ordered by most recently updated first. Use 'after' cursor to paginate.`,
981
985
  inputSchema: linearSearchTicketInputSchema,
982
986
  outputSchema: toolOutputBaseSchema.extend({
983
987
  issues: z.array(linearIssueSummarySchema),
@@ -988,6 +992,8 @@ export const linearSearchTicketTool = defineTool({
988
992
  });
989
993
  export const linearReadTicketTool = defineTool({
990
994
  name: "linear_read_ticket",
995
+ description: `Read detailed information about a Linear issue/ticket including title, description, state, assignee, and optionally all comments.
996
+ Use the issue ID (UUID) or the issue identifier (e.g. "TEAM-123"). Use this after searching for tickets to get full details.`,
991
997
  inputSchema: linearReadTicketInputSchema,
992
998
  outputSchema: toolOutputBaseSchema.extend({
993
999
  issue: linearIssueDetailSchema,
@@ -996,6 +1002,7 @@ export const linearReadTicketTool = defineTool({
996
1002
  });
997
1003
  export const linearGetStatesTool = defineTool({
998
1004
  name: "linear_get_states",
1005
+ description: `List workflow states for the Linear workspace or a specific team. Use when creating or updating issues to pick a valid stateId (e.g. "Todo", "In Progress", "Done").`,
999
1006
  inputSchema: linearGetStatesInputSchema,
1000
1007
  outputSchema: toolOutputBaseSchema.extend({
1001
1008
  states: z.array(linearStateSummarySchema)
@@ -1003,6 +1010,7 @@ export const linearGetStatesTool = defineTool({
1003
1010
  });
1004
1011
  export const linearGetLabelsTool = defineTool({
1005
1012
  name: "linear_get_labels",
1013
+ description: `List issue labels for the Linear workspace or a specific team. Use to pick labelIds for linear_create_ticket or linear_update_ticket.`,
1006
1014
  inputSchema: linearGetLabelsInputSchema,
1007
1015
  outputSchema: toolOutputBaseSchema.extend({
1008
1016
  labels: z.array(linearLabelSummarySchema)
@@ -1010,6 +1018,7 @@ export const linearGetLabelsTool = defineTool({
1010
1018
  });
1011
1019
  export const linearGetProjectsTool = defineTool({
1012
1020
  name: "linear_get_projects",
1021
+ description: `List projects for the Linear workspace or a specific team. Use to pick projectId when creating or updating issues.`,
1013
1022
  inputSchema: linearGetProjectsInputSchema,
1014
1023
  outputSchema: toolOutputBaseSchema.extend({
1015
1024
  projects: z.array(linearProjectSummarySchema)
@@ -1017,6 +1026,7 @@ export const linearGetProjectsTool = defineTool({
1017
1026
  });
1018
1027
  export const linearGetTeamsTool = defineTool({
1019
1028
  name: "linear_get_teams",
1029
+ description: `List teams in the Linear workspace. Use to pick teamId when creating tickets or when calling linear_get_states, linear_get_labels, or linear_get_projects for a specific team.`,
1020
1030
  inputSchema: linearGetTeamsInputSchema,
1021
1031
  outputSchema: toolOutputBaseSchema.extend({
1022
1032
  teams: z.array(linearTeamSchema)
@@ -1024,6 +1034,7 @@ export const linearGetTeamsTool = defineTool({
1024
1034
  });
1025
1035
  export const linearGetUsersTool = defineTool({
1026
1036
  name: "linear_get_users",
1037
+ description: `List users in the Linear workspace. Use to pick assigneeId or subscriberIds when creating or updating issues.`,
1027
1038
  inputSchema: linearGetUsersInputSchema,
1028
1039
  outputSchema: toolOutputBaseSchema.extend({
1029
1040
  users: z.array(linearUserSummarySchema)
@@ -1031,6 +1042,7 @@ export const linearGetUsersTool = defineTool({
1031
1042
  });
1032
1043
  export const slackSendMessageTool = defineTool({
1033
1044
  name: "slack_send_message",
1045
+ description: `Send message to a Slack channel or DM. Provide channelId (C…/G…/D…) or slackUserId (U…) to open or reuse a 1:1 DM. Supports plain text (mrkdwn) or Block Kit (JSON blocks). If both are set, channelId is used.`,
1034
1046
  inputSchema: slackSendMessageInputSchema,
1035
1047
  outputSchema: toolOutputBaseSchema.extend({
1036
1048
  message_ts: z.string().optional(),
@@ -1042,6 +1054,9 @@ export const slackSendMessageTool = defineTool({
1042
1054
  });
1043
1055
  export const slackListChannelsTool = defineTool({
1044
1056
  name: "slack_list_channels",
1057
+ description: `List available Slack channels and conversations (public, private, DMs, multi-person DMs) that the integration can access.
1058
+ Use this to discover channel IDs before reading conversation history.
1059
+ Supports pagination: if the response includes nextCursor and hasMore, pass nextCursor as the cursor parameter on the next call to fetch more.`,
1045
1060
  inputSchema: slackListChannelsInputSchema,
1046
1061
  outputSchema: toolOutputBaseSchema.extend({
1047
1062
  channels: z.array(slackChannelListItemSchema),
@@ -1052,6 +1067,8 @@ export const slackListChannelsTool = defineTool({
1052
1067
  });
1053
1068
  export const slackListUsersTool = defineTool({
1054
1069
  name: "slack_list_users",
1070
+ description: `List Slack workspace users (id, name, email). Use this to resolve user IDs to names when needed.
1071
+ Returns non-bot members. Optionally filter by name or email with the query parameter.`,
1055
1072
  inputSchema: slackListUsersInputSchema,
1056
1073
  outputSchema: toolOutputBaseSchema.extend({
1057
1074
  users: z.array(slackUserResponseSchema),
@@ -1060,6 +1077,9 @@ export const slackListUsersTool = defineTool({
1060
1077
  });
1061
1078
  export const slackReadConversationTool = defineTool({
1062
1079
  name: "slack_read_conversation",
1080
+ description: `Read message history from a Slack channel or DM.
1081
+ Use the channel ID from slack_list_channels. Supports public channels, private channels, and DMs.
1082
+ Supports pagination: if the response includes nextCursor and hasMore, pass nextCursor as the cursor parameter on the next call to fetch more messages.`,
1063
1083
  inputSchema: slackReadConversationInputSchema,
1064
1084
  outputSchema: toolOutputBaseSchema.extend({
1065
1085
  channelId: z.string(),
@@ -1072,6 +1092,26 @@ export const slackReadConversationTool = defineTool({
1072
1092
  });
1073
1093
  export const searchGitHubCodeTool = defineTool({
1074
1094
  name: "searchGitHubCode",
1095
+ description: `Search GitHub repositories for code by SEMANTIC MEANING (conceptual search). Use this when you DON'T know the exact code text.
1096
+
1097
+ Use searchGitHubCode for:
1098
+ - Concepts and patterns: "authentication", "error handling", "database connections"
1099
+ - Unknown implementations: "how is validation done?", "where are API routes?"
1100
+ - Exploring codebases: "logging implementations", "payment processing"
1101
+ - Finding code by what it DOES, not what it's CALLED
1102
+
1103
+ Use grepGitHubCode instead when you KNOW the exact text string (function name, import, etc.)
1104
+
1105
+ Examples:
1106
+ - ✅ "authentication middleware" (finds login, auth, verifyToken, etc.)
1107
+ - ✅ "error handling patterns" (finds try/catch, error handlers, etc.)
1108
+ - ✅ "database queries" (finds prisma, mysql, query builders)
1109
+ - ❌ "getUserById(" → Use grepGitHubCode for exact matches
1110
+
1111
+ Tips:
1112
+ - Start with broad searches, then narrow down
1113
+ - Use natural language or domain terms
1114
+ - Combine multiple terms for more specific results`,
1075
1115
  inputSchema: searchGitHubCodeInputSchema,
1076
1116
  outputSchema: toolOutputBaseSchema.extend({
1077
1117
  totalCount: z.number().int(),
@@ -1086,6 +1126,24 @@ export const searchGitHubCodeTool = defineTool({
1086
1126
  });
1087
1127
  export const grepGitHubCodeTool = defineTool({
1088
1128
  name: "grepGitHubCode",
1129
+ description: `Search GitHub repositories for EXACT TEXT MATCHES (like grep). Use this when you KNOW the exact string you're looking for.
1130
+
1131
+ Use grepGitHubCode for:
1132
+ - Exact function calls: "getUserById(", "processPayment()"
1133
+ - Exact imports: "from '@prisma/client'", "import React from"
1134
+ - Exact strings: "API_KEY", "TODO:", "FIXME:"
1135
+ - Known identifiers: class names, constants, variable names you know exist
1136
+
1137
+ Use searchGitHubCode instead when you DON'T know the exact text (looking for concepts/patterns).
1138
+
1139
+ Examples:
1140
+ - ✅ "getUserById(" (exact function call)
1141
+ - ✅ "from '@prisma/client'" (exact import statement)
1142
+ - ✅ "TODO: refactor" (exact comment)
1143
+ - ✅ "useState" (exact React hook name)
1144
+ - ❌ "state management" → Use searchGitHubCode for concepts
1145
+
1146
+ This is more precise than semantic search - use it when you know exactly what text to find.`,
1089
1147
  inputSchema: grepGitHubCodeInputSchema,
1090
1148
  outputSchema: toolOutputBaseSchema.extend({
1091
1149
  totalCount: z.number().int(),
@@ -1101,6 +1159,13 @@ export const grepGitHubCodeTool = defineTool({
1101
1159
  });
1102
1160
  export const readGitHubFileTool = defineTool({
1103
1161
  name: "readGitHubFile",
1162
+ description: `Read the full contents of a file from a GitHub repository. Use this after finding relevant files via search to:
1163
+ - Understand the complete implementation of a function or class
1164
+ - See imports and dependencies
1165
+ - Review the full context around a code snippet
1166
+ - Understand file structure and organization
1167
+
1168
+ Note: This reads from the default branch (main/master). Large files may be truncated.`,
1104
1169
  inputSchema: readGitHubFileInputSchema,
1105
1170
  outputSchema: toolOutputBaseSchema.extend({
1106
1171
  repository: z.string(),
@@ -1115,6 +1180,13 @@ export const readGitHubFileTool = defineTool({
1115
1180
  });
1116
1181
  export const listGitHubDirectoryTool = defineTool({
1117
1182
  name: "listGitHubDirectory",
1183
+ description: `List files and directories in a GitHub repository. Use this to:
1184
+ - Explore the repository structure
1185
+ - Find where specific types of files are located
1186
+ - Understand the project organization
1187
+ - Navigate to specific directories before reading files
1188
+
1189
+ Start with the root directory (empty path) to see the top-level structure, then drill down into interesting directories.`,
1118
1190
  inputSchema: listGitHubDirectoryInputSchema,
1119
1191
  outputSchema: toolOutputBaseSchema.extend({
1120
1192
  repository: z.string(),
@@ -1131,6 +1203,14 @@ export const listGitHubDirectoryTool = defineTool({
1131
1203
  });
1132
1204
  export const listGitHubPullRequestsTool = defineTool({
1133
1205
  name: "listGitHubPullRequests",
1206
+ description: `List pull requests in GitHub repositories within a time window. Use this to:
1207
+ - Find recently merged PRs to understand recent changes
1208
+ - Review what work has been completed in a given period
1209
+ - Track PR activity for specific repositories
1210
+ - Understand the development history and velocity
1211
+
1212
+ The tool returns PR details including title, description, author, merge status, and dates.
1213
+ Dates are specified in YYYY-MM-DD format (e.g., "2024-01-15"). The since date is interpreted as the start of that day (00:00:00), and the until date is interpreted as the end of that day (23:59:59).`,
1134
1214
  inputSchema: listGitHubPullRequestsInputSchema,
1135
1215
  outputSchema: toolOutputBaseSchema.extend({
1136
1216
  repository: z.string(),
@@ -1143,6 +1223,14 @@ export const listGitHubPullRequestsTool = defineTool({
1143
1223
  });
1144
1224
  export const listGitHubCommitsTool = defineTool({
1145
1225
  name: "listGitHubCommits",
1226
+ description: `List commits in GitHub repositories within a time window. Use this to:
1227
+ - Review recent changes and development activity
1228
+ - Track what code was modified in a specific period
1229
+ - Find commits by a specific author
1230
+ - See commit history for a specific file or directory
1231
+ - Understand the pace and nature of development
1232
+
1233
+ The tool returns commit details including message, author, date, and SHA.`,
1146
1234
  inputSchema: listGitHubCommitsInputSchema,
1147
1235
  outputSchema: toolOutputBaseSchema.extend({
1148
1236
  repository: z.string(),
@@ -1156,6 +1244,22 @@ export const listGitHubCommitsTool = defineTool({
1156
1244
  });
1157
1245
  export const summarizeGitHubPullRequestDiffTool = defineTool({
1158
1246
  name: "summarizeGitHubPullRequestDiff",
1247
+ description: `Summarize the diff of a pull request from a GitHub repository using an intelligent sub-agent. Use this to:
1248
+ - Understand what changes were made in a specific PR without loading the full diff into context
1249
+ - Get a concise summary of code changes before merging
1250
+ - Analyze the impact of a PR on the codebase efficiently
1251
+ - See file-by-file changes with key insights
1252
+
1253
+ The tool launches a sub-agent that:
1254
+ - Reads the full PR diff from GitHub
1255
+ - Analyzes the changes using a compact model
1256
+ - Provides a structured summary including:
1257
+ - Overview of changes
1258
+ - Key files modified
1259
+ - Notable additions/removals
1260
+ - Impact assessment
1261
+
1262
+ You can optionally provide high-level context about what you're looking for in the PR, which will help the sub-agent focus its analysis.`,
1159
1263
  inputSchema: summarizeGitHubPullRequestDiffInputSchema,
1160
1264
  outputSchema: toolOutputBaseSchema.extend({
1161
1265
  repository: z.string(),
@@ -1168,21 +1272,57 @@ export const summarizeGitHubPullRequestDiffTool = defineTool({
1168
1272
  });
1169
1273
  export const notionCreateOrUpdatePageTool = defineTool({
1170
1274
  name: "notion_create_or_update_page",
1275
+ description: `Create or update a **standalone page**. Not for database entries — use notion_create_or_update_database_row for those.
1276
+
1277
+ **Create**: Omit page_id (or pass null). Supply parentPageId (allowed page ID from config), title. Creates a new empty subpage under the parent. Use notion_modify_blocks on the returned page_id to add content.
1278
+ **Update**: Pass page_id of an existing page to update its title. parentPageId is ignored when updating. Use notion_modify_blocks to change page content.`,
1171
1279
  inputSchema: notionCreateOrUpdatePageInputSchema,
1172
1280
  outputSchema: notionDatabaseRowMutationResultSchema
1173
1281
  });
1174
1282
  export const notionCreateOrUpdateDatabaseRowTool = defineTool({
1175
1283
  name: "notion_create_or_update_database_row",
1284
+ description: `Create or update a **row** (entry) in a Notion database. Use with databaseId and properties_json. Not for standalone pages — use notion_create_or_update_page for those.
1285
+
1286
+ Use notion_get_schema first to understand property names and types. Use notion_query_database to find page_id for updates. Provide page_id null to create a new row, or a valid page_id to update. Property format: Title, Rich Text, Select, Status, etc. per notion_get_schema.`,
1176
1287
  inputSchema: notionCreateOrUpdateDatabaseRowInputSchema,
1177
1288
  outputSchema: notionDatabaseRowMutationResultSchema
1178
1289
  });
1179
1290
  export const notionModifyBlocksTool = defineTool({
1180
1291
  name: "notion_modify_blocks",
1292
+ description: `Add, update, or delete blocks in page content. Use this to modify page content (paragraphs, headings, lists, etc.).
1293
+
1294
+ Accepts a single operation object (backwards compatible) OR an array of operation objects executed sequentially. One approval covers the whole batch.
1295
+
1296
+ Operations:
1297
+ - append: Add new blocks to the page (or to a parent block if parent_block_id is provided). Use optional after_block_id to insert after a specific block instead of at the end. Get block IDs from notion_query_page.
1298
+ - update: Update an existing block by block_id
1299
+ - delete: Delete (archive) a block by block_id
1300
+
1301
+ Positional insertion: Use after_block_id with append to insert blocks after a specific block instead of at the end.
1302
+
1303
+ Moving blocks within a page:
1304
+ 1. Retrieve the block content with notion_query_page.
1305
+ 2. Append the block at the desired position (use after_block_id for position, or parent_block_id for container).
1306
+ 3. Delete the original block with the "delete" operation.
1307
+
1308
+ Examples — single operation:
1309
+ - Append: {"operation": "append", "blocks": [{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"type": "text", "text": {"content": "Hello world"}}]}}]}
1310
+ - Append after a block: {"operation": "append", "after_block_id": "xyz789", "blocks": [{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"type": "text", "text": {"content": "Inserted here"}}]}}]}
1311
+ - Update: {"operation": "update", "block_id": "abc123", "block": {"paragraph": {"rich_text": [{"type": "text", "text": {"content": "Updated text"}}]}}}
1312
+ - Delete: {"operation": "delete", "block_id": "abc123"}
1313
+
1314
+ Examples — batch (array):
1315
+ [{"operation": "append", "blocks": [...]}, {"operation": "update", "block_id": "abc", "block": {...}}, {"operation": "delete", "block_id": "def"}]
1316
+
1317
+ Error recovery: If Notion returns an error that suggests JSON/body/validation incompatibility, retry. First fix the specific issue mentioned in the error; if that is unclear or still failing, retry with a simpler payload (fewer blocks, simpler block types like plain paragraphs).`,
1181
1318
  inputSchema: notionModifyBlocksInputSchema,
1182
1319
  outputSchema: z.union([notionModifyBlocksSuccessSchema, notionModifyBlocksFailureSchema])
1183
1320
  });
1184
1321
  export const notionQueryPageTool = defineTool({
1185
1322
  name: "notion_query_page",
1323
+ description: `Call this tool ONCE at the beginning of your run to get the page state. After calling it once, remember and reuse the results - DO NOT call it multiple times in the same run.
1324
+
1325
+ This tool returns the current state of the page including all properties, metadata, and content blocks.`,
1186
1326
  inputSchema: notionQueryPageInputSchema,
1187
1327
  outputSchema: notionPageQueryMetadataSchema.extend({
1188
1328
  success: z.literal(true),
@@ -1195,11 +1335,63 @@ export const notionQueryPageTool = defineTool({
1195
1335
  });
1196
1336
  export const notionQueryDatabaseTool = defineTool({
1197
1337
  name: "notion_query_database",
1338
+ description: `Query a Notion data source (database) to retrieve pages that match specific criteria.
1339
+
1340
+ WHEN TO USE THIS TOOL:
1341
+ - Verify if the database contains any existing records and avoid creating duplicates.
1342
+ - When you need to find specific pages matching certain criteria (e.g., status, date ranges, property values)
1343
+ - When you need to retrieve a subset of pages rather than all pages in the database
1344
+ - When working with large databases and need pagination to retrieve results in batches
1345
+ - When you only need specific properties from pages (use filter_properties for efficiency)
1346
+
1347
+ WHAT THIS TOOL DOES:
1348
+ 1. Filters pages at the Notion API level (not client-side) for maximum efficiency
1349
+ 2. Supports complex filtering with AND/OR logic, property filters, and timestamp filters
1350
+ 3. Supports pagination - use start_cursor from previous responses to get next page
1351
+ 4. Supports filter_properties to only fetch needed fields, reducing response size and improving speed
1352
+
1353
+ FILTERING:
1354
+ - Property filters: Filter by any database property (title, number, date, select, status, checkbox, etc.)
1355
+ - Timestamp filters: Filter by created_time or last_edited_time (these are SYSTEM FIELDS, not database properties)
1356
+ - Compound filters: Combine filters with AND/OR logic
1357
+ - All filtering happens server-side at Notion for efficiency
1358
+
1359
+ SYSTEM FIELDS (available on ALL pages, not shown in schema):
1360
+ - created_time: When the page was created. Use timestamp filter format (NO "property" field).
1361
+ - last_edited_time: When the page was last edited. Use timestamp filter format (NO "property" field).
1362
+ - created_by: User who created the page. Use people filter WITH "property" field.
1363
+ - last_edited_by: User who last edited the page. Use people filter WITH "property" field.
1364
+
1365
+ IMPORTANT: Timestamp filters (created_time, last_edited_time) use a DIFFERENT format than property filters:
1366
+ - CORRECT: {"timestamp": "created_time", "created_time": {"on_or_after": "2024-01-01"}}
1367
+ - WRONG: {"property": "created_time", "date": {"on_or_after": "2024-01-01"}}
1368
+
1369
+ PAGINATION:
1370
+ - Use page_size to control how many results per page (default: all results)
1371
+ - Use start_cursor from the response to fetch the next page
1372
+ - The response includes has_more and next_cursor when more pages are available
1373
+
1374
+ FILTER_PROPERTIES:
1375
+ - Specify only the properties you need to reduce response size and improve performance
1376
+ - Especially important for databases with many properties or complex formulas/rollups
1377
+ - You can fetch additional properties later using Retrieve page property item API
1378
+
1379
+ NOTE: This tool does NOT return the database schema. Use notion_get_schema if you need schema information.`,
1198
1380
  inputSchema: notionQueryDatabaseInputSchema,
1199
1381
  outputSchema: z.discriminatedUnion("success", [notionQueryDatabaseSuccessSchema, notionQueryDatabaseFailureSchema])
1200
1382
  });
1201
1383
  export const notionGetSchemaTool = defineTool({
1202
1384
  name: "notion_get_schema",
1385
+ description: `Gets the schema/structure of the Notion data source. This tool retrieves all property definitions including property names, types, valid options for select/status fields, and exact format examples for how to construct each property when writing to the database.
1386
+
1387
+ Use this tool:
1388
+ - Before writing any data to determine available properties and their correct formats
1389
+ - To understand what property names exist and their data types
1390
+ - To get valid option values for select, multi_select, and status properties
1391
+ - To see exact format examples for constructing properties in the Notion API format
1392
+ - To determine how to write to the Notion database by understanding its structure
1393
+
1394
+ The schema information returned by this tool should be used to properly format properties when calling notion_create_or_update_database_row to create or update rows in the database.`,
1203
1395
  inputSchema: notionGetSchemaInputSchema,
1204
1396
  outputSchema: toolOutputSuccessSchema.extend({
1205
1397
  data_source_id: z.string(),
@@ -1210,6 +1402,13 @@ export const notionGetSchemaTool = defineTool({
1210
1402
  });
1211
1403
  export const notionListUsersTool = defineTool({
1212
1404
  name: "notion_list_users",
1405
+ description: `List users in the Notion workspace. Use this to resolve user names to Notion user IDs
1406
+ for populating People properties (e.g., Assignee, Owner) when creating or updating database pages.
1407
+
1408
+ Returns workspace members (not bots). Optionally filter by name with the query parameter.
1409
+
1410
+ Use the returned user IDs in people property format:
1411
+ {"Assignee": {"people": [{"object": "user", "id": "<user_id>"}]}}`,
1213
1412
  inputSchema: notionListUsersInputSchema,
1214
1413
  outputSchema: toolOutputSuccessSchema.extend({
1215
1414
  users: z.array(notionWorkspaceUserSchema),
@@ -1218,21 +1417,25 @@ export const notionListUsersTool = defineTool({
1218
1417
  });
1219
1418
  export const gmailSendEmailTool = defineTool({
1220
1419
  name: "gmail_send_email",
1420
+ description: `Send email or reply to an existing email thread via Gmail. Use thread_id (the Gmail Thread ID, not the Message-ID) to reply to an existing thread, or omit it to send a new email. IMPORTANT: Never put image URLs directly in html_body — remote URLs expire and will result in broken images. Always use image_urls to embed images as base64-encoded inline MIME parts (CID attachments), then reference them in html_body with <img src="cid:image-1.png">. image_urls must be signed URLs from our internal GCS image bucket.`,
1221
1421
  inputSchema: gmailSendEmailInputSchema,
1222
1422
  outputSchema: toolOutputSuccessSchema.merge(gmailSendSummarySchema)
1223
1423
  });
1224
1424
  export const gmailCreateDraftTool = defineTool({
1225
1425
  name: "gmail_create_draft",
1426
+ description: `Create a draft email in Gmail. Use thread_id (the Gmail Thread ID, not the Message-ID) to create a draft reply to an existing thread, or omit it to create a new draft email. The draft will appear in the user's Gmail Drafts folder for review before sending. IMPORTANT: Never put image URLs directly in html_body — remote URLs expire and will result in broken images. Always use image_urls to embed images as base64-encoded inline MIME parts (CID attachments), then reference them in html_body with <img src="cid:image-1.png">. image_urls must be signed URLs from our internal GCS image bucket.`,
1226
1427
  inputSchema: gmailCreateDraftInputSchema,
1227
1428
  outputSchema: toolOutputSuccessSchema.merge(gmailDraftSummarySchema)
1228
1429
  });
1229
1430
  export const searchPosthogSessionsTool = defineTool({
1230
1431
  name: "searchPosthogSessions",
1432
+ description: "Query PostHog session recordings for a specific user by their email address. Returns session recordings data and links to view sessions in PostHog. Use this when you need to replay user sessions, investigate user behavior, or understand how users interact with the application. Returns the most recent session recordings first.",
1231
1433
  inputSchema: searchPosthogSessionsInputSchema,
1232
1434
  outputSchema: z.union([posthogSearchSessionsFoundSchema, posthogSearchSessionsNotFoundSchema])
1233
1435
  });
1234
1436
  export const searchPosthogLogsTool = defineTool({
1235
1437
  name: "searchPosthogLogs",
1438
+ description: "Query PostHog logs with flexible filtering. Returns logs data and a link to view logs in PostHog. You can filter by user email, log severity levels (error, warn, info, debug), message text search, or combinations. At least one filter (user email, severity levels, or message search) should be provided to avoid overly broad queries. Use this when you need to investigate user activity, errors, or events in PostHog logs.",
1236
1439
  inputSchema: searchPosthogLogsInputSchema,
1237
1440
  outputSchema: toolOutputSuccessSchema.extend({
1238
1441
  userEmail: z.string().nullable(),
@@ -1248,6 +1451,7 @@ export const searchPosthogLogsTool = defineTool({
1248
1451
  });
1249
1452
  export const getPosthogSessionEventsTool = defineTool({
1250
1453
  name: "getPosthogSessionEvents",
1454
+ description: "Fetch and decode session replay events from PostHog. Returns summarized meaningful events (clicks, inputs, scroll, console logs, network errors, navigation) within a specified time window. Use this to investigate what a user did during a session - what they clicked, what they typed, any errors that occurred, etc. The events are decoded and summarized for easy analysis.",
1251
1455
  inputSchema: getPosthogSessionEventsInputSchema,
1252
1456
  outputSchema: toolOutputSuccessSchema.extend({
1253
1457
  sessionId: z.string(),
@@ -1263,6 +1467,7 @@ export const getPosthogSessionEventsTool = defineTool({
1263
1467
  });
1264
1468
  export const listPosthogEventNamesTool = defineTool({
1265
1469
  name: "listPosthogEventNames",
1470
+ description: "List PostHog event names with how often each occurred, most frequent first (US PostHog Cloud only). Scope with distinctId to profile a single user's activity, or with event/person propertyFilters and a date range.",
1266
1471
  inputSchema: listPosthogEventNamesInputSchema,
1267
1472
  outputSchema: toolOutputSuccessSchema.extend({
1268
1473
  eventCounts: z.array(posthogEventCountSchema),
@@ -1272,6 +1477,7 @@ export const listPosthogEventNamesTool = defineTool({
1272
1477
  });
1273
1478
  export const searchPosthogEventsTool = defineTool({
1274
1479
  name: "searchPosthogEvents",
1480
+ description: "Fetch PostHog analytics events, newest first (US PostHog Cloud only). Filter by eventName, distinctId, and event/person propertyFilters. Use listPosthogEventNames first to discover which event names exist.",
1275
1481
  inputSchema: searchPosthogEventsInputSchema,
1276
1482
  outputSchema: toolOutputSuccessSchema.extend({
1277
1483
  events: z.array(posthogEventSummarySchema),
@@ -1473,6 +1679,7 @@ export const imageEditInputSchema = z.object({
1473
1679
  });
1474
1680
  export const searchDatadogLogsTool = defineTool({
1475
1681
  name: "searchDatadogLogs",
1682
+ description: "Query Datadog logs. Filter by query string, indexes, time range. Returns logs with timestamps, status, messages, hosts, services, tags.",
1476
1683
  inputSchema: searchDatadogLogsInputSchema,
1477
1684
  outputSchema: toolOutputBaseSchema.extend({
1478
1685
  query: z.string().nullable(),
@@ -1487,6 +1694,7 @@ export const searchDatadogLogsTool = defineTool({
1487
1694
  });
1488
1695
  export const searchRumEventsTool = defineTool({
1489
1696
  name: "searchRumEvents",
1697
+ description: "Query Datadog RUM events. Filter by query string, time range. Returns sessions, views, actions, errors, resources, long tasks.",
1490
1698
  inputSchema: searchRumEventsInputSchema,
1491
1699
  outputSchema: toolOutputBaseSchema.extend({
1492
1700
  query: z.string().nullable(),
@@ -1501,6 +1709,7 @@ export const searchRumEventsTool = defineTool({
1501
1709
  });
1502
1710
  export const listRumEventsTool = defineTool({
1503
1711
  name: "listRumEvents",
1712
+ description: "List recent Datadog RUM events. Use for discovery when unsure what to query. Returns sessions, views, actions, errors, resources, long tasks.",
1504
1713
  inputSchema: listRumEventsInputSchema,
1505
1714
  outputSchema: toolOutputBaseSchema.extend({
1506
1715
  query: z.string().nullable(),
@@ -1515,6 +1724,7 @@ export const listRumEventsTool = defineTool({
1515
1724
  });
1516
1725
  export const aggregateRumEventsTool = defineTool({
1517
1726
  name: "aggregateRumEvents",
1727
+ description: "Aggregate Datadog RUM events into metrics. Compute percentiles, averages, sums, etc. Group by facets for breakdowns. Use for performance trends and error rates.",
1518
1728
  inputSchema: aggregateRumEventsInputSchema,
1519
1729
  outputSchema: toolOutputBaseSchema.extend({
1520
1730
  query: z.string().nullable(),
@@ -1533,16 +1743,19 @@ export const aggregateRumEventsTool = defineTool({
1533
1743
  });
1534
1744
  export const webExtractTool = defineTool({
1535
1745
  name: "web_extract",
1746
+ description: "Extract the full text content from one or more web page URLs. Use this when you need to read the complete contents of a specific page.",
1536
1747
  inputSchema: webExtractInputSchema,
1537
1748
  outputSchema: webExtractOutputSchema
1538
1749
  });
1539
1750
  export const webResearchTool = defineTool({
1540
1751
  name: "web_research",
1752
+ description: "Conduct deep, multi-source research on a topic. Autonomously searches across many sources and returns a comprehensive report with citations. Best for complex questions requiring synthesis across multiple sources. Takes longer than a regular search (up to 2 minutes).",
1541
1753
  inputSchema: webResearchInputSchema,
1542
1754
  outputSchema: webResearchOutputSchema
1543
1755
  });
1544
1756
  export const imageEditTool = defineTool({
1545
1757
  name: "image_edit",
1758
+ description: "Edit or transform an image from a URL using a natural language prompt. Supports crops, style changes, object removal/addition, color adjustments, and other visual edits. The edited image is automatically sent to the chat UI for the user to see.",
1546
1759
  inputSchema: imageEditInputSchema,
1547
1760
  outputSchema: imageEditOutputSchema
1548
1761
  });
@@ -1832,12 +2045,10 @@ export const attioGetRecordRequestSchema = z.object({
1832
2045
  recordId: attioRecordIdField
1833
2046
  });
1834
2047
  export const attioCreateRecordRequestSchema = z.object({
1835
- action: z.literal("create").describe("Create a new record. Unlike 'upsert', no matching attribute is needed, so this works for objects without a unique writable attribute (e.g. deals)."),
1836
2048
  objectSlug: attioObjectSlugField,
1837
2049
  values: z.string().describe('A JSON object string mapping attribute slugs to values (e.g. \'{"name":"Acme","domains":["acme.com"]}\'). For multi-value attributes, pass an array.')
1838
2050
  });
1839
2051
  export const attioUpdateRecordRequestSchema = z.object({
1840
- action: z.literal("update").describe("Update an existing record by its ID. Only the attributes present in 'values' are touched."),
1841
2052
  objectSlug: attioObjectSlugField,
1842
2053
  recordId: attioRecordIdField,
1843
2054
  values: z.string().describe("A JSON object string mapping the attribute slugs to update to their new values."),
@@ -1847,9 +2058,6 @@ export const attioUpdateRecordRequestSchema = z.object({
1847
2058
  .describe("'overwrite' (the default) replaces the values of multi-value attributes; 'append' adds to them without removing existing values. Pass null for the default.")
1848
2059
  });
1849
2060
  export const attioUpsertRecordsRequestSchema = z.object({
1850
- action: z
1851
- .literal("upsert")
1852
- .describe("Create or update one or more records, matched on a unique attribute. If a match is found the record is updated, otherwise a new one is created. Throws if ANY record in the batch fails, naming each failure; earlier records may already be written (upserts are safe to retry)."),
1853
2061
  objectSlug: attioObjectSlugField,
1854
2062
  matchingAttribute: z.string().describe("The unique, writable attribute slug to match on (e.g. 'email_addresses' for people, 'domains' for companies)."),
1855
2063
  records: z
@@ -1857,7 +2065,6 @@ export const attioUpsertRecordsRequestSchema = z.object({
1857
2065
  .describe('A JSON string representing a list of records to upsert. Each record maps attribute slugs to values; for multi-value attributes pass an array. Example: \'[{"email_addresses":["test@example.com"],"name":"John"}]\'.')
1858
2066
  });
1859
2067
  export const attioDeleteRecordRequestSchema = z.object({
1860
- action: z.literal("delete").describe("Permanently delete a record by its ID. This cannot be undone."),
1861
2068
  objectSlug: attioObjectSlugField,
1862
2069
  recordId: attioRecordIdField
1863
2070
  });
@@ -1869,25 +2076,17 @@ export const attioGetAttributeHistoryRequestSchema = z.object({
1869
2076
  limit: z.number().int().nullable().describe("Maximum number of history entries to return. Pass null for the default."),
1870
2077
  offset: z.number().int().nullable().describe("Number of entries to skip, for pagination. Pass null for 0.")
1871
2078
  });
1872
- export const attioRecordsRequestSchema = z.discriminatedUnion("action", [
2079
+ export const attioReadRecordsRequestSchema = z.discriminatedUnion("action", [
1873
2080
  attioQueryRecordsRequestSchema,
1874
2081
  attioSearchRecordsRequestSchema,
1875
2082
  attioGetRecordRequestSchema,
1876
- attioCreateRecordRequestSchema,
1877
- attioUpdateRecordRequestSchema,
1878
- attioUpsertRecordsRequestSchema,
1879
- attioDeleteRecordRequestSchema,
1880
2083
  attioGetAttributeHistoryRequestSchema
1881
2084
  ]);
1882
- export const attioRecordsInputSchema = z.object({
1883
- integrationId: z.string().describe("The integration ID of the Attio workspace to use."),
1884
- request: attioRecordsRequestSchema.describe("The record operation to perform and its arguments.")
1885
- });
1886
2085
  const attioTargetRecordFields = {
1887
2086
  objectSlug: z.string().describe("The object type slug of the record (e.g. 'people', 'companies')."),
1888
2087
  recordId: z.string().describe("The record ID (UUID).")
1889
2088
  };
1890
- export const attioTasksRequestSchema = z.discriminatedUnion("action", [
2089
+ export const attioReadTasksRequestSchema = z.discriminatedUnion("action", [
1891
2090
  z.object({
1892
2091
  action: z.literal("list").describe("List tasks, optionally filtered by linked record, assignee or completion state."),
1893
2092
  linkedObjectSlug: z.string().nullable().optional().describe("Filter to tasks linked to records of this object slug. Requires linkedRecordId."),
@@ -1896,26 +2095,24 @@ export const attioTasksRequestSchema = z.discriminatedUnion("action", [
1896
2095
  limit: z.number().int().nullable().optional().describe("Maximum tasks to return."),
1897
2096
  offset: z.number().int().nullable().optional().describe("Number of tasks to skip, for pagination.")
1898
2097
  }),
1899
- z.object({ action: z.literal("get").describe("Fetch a single task by ID."), taskId: z.string() }),
1900
- z.object({
1901
- action: z.literal("create").describe("Create a task, optionally linked to records and assigned to workspace members."),
1902
- content: z.string().describe("The task text (plaintext, max 2000 chars)."),
1903
- deadlineAt: z.string().nullable().optional().describe("Deadline as an ISO 8601 timestamp, or null for no deadline."),
1904
- isCompleted: z.boolean().nullable().optional().describe("Whether the task starts completed. Defaults to false."),
1905
- assignees: z.array(z.string()).nullable().optional().describe("Workspace member email addresses or member IDs (UUIDs) to assign."),
1906
- linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Records to link the task to.")
1907
- }),
1908
- z.object({
1909
- action: z.literal("update").describe("Update a task's deadline, completion state, assignees or linked records. Task content cannot be changed."),
1910
- taskId: z.string(),
1911
- deadlineAt: z.string().nullable().optional().describe("New deadline (ISO 8601), or null to clear."),
1912
- isCompleted: z.boolean().nullable().optional().describe("New completion state. Omit to leave unchanged."),
1913
- assignees: z.array(z.string()).nullable().optional().describe("Replacement assignee emails/IDs. Omit to leave unchanged."),
1914
- linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Replacement linked records. Omit to leave unchanged.")
1915
- }),
1916
- z.object({ action: z.literal("delete").describe("Permanently delete a task."), taskId: z.string() })
2098
+ z.object({ action: z.literal("get").describe("Fetch a single task by ID."), taskId: z.string() })
1917
2099
  ]);
1918
- export const attioNotesRequestSchema = z.discriminatedUnion("action", [
2100
+ export const attioCreateTaskRequestSchema = z.object({
2101
+ content: z.string().describe("The task text (plaintext, max 2000 chars)."),
2102
+ deadlineAt: z.string().nullable().optional().describe("Deadline as an ISO 8601 timestamp, or null for no deadline."),
2103
+ isCompleted: z.boolean().nullable().optional().describe("Whether the task starts completed. Defaults to false."),
2104
+ assignees: z.array(z.string()).nullable().optional().describe("Workspace member email addresses or member IDs (UUIDs) to assign."),
2105
+ linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Records to link the task to.")
2106
+ });
2107
+ export const attioUpdateTaskRequestSchema = z.object({
2108
+ taskId: z.string(),
2109
+ deadlineAt: z.string().nullable().optional().describe("New deadline (ISO 8601), or null to clear."),
2110
+ isCompleted: z.boolean().nullable().optional().describe("New completion state. Omit to leave unchanged."),
2111
+ assignees: z.array(z.string()).nullable().optional().describe("Replacement assignee emails/IDs. Omit to leave unchanged."),
2112
+ linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Replacement linked records. Omit to leave unchanged.")
2113
+ });
2114
+ export const attioDeleteTaskRequestSchema = z.object({ taskId: z.string() });
2115
+ export const attioReadNotesRequestSchema = z.discriminatedUnion("action", [
1919
2116
  z.object({
1920
2117
  action: z.literal("list").describe("List notes, optionally scoped to one record."),
1921
2118
  parentObjectSlug: z.string().nullable().optional().describe("Filter to notes on records of this object slug. Requires parentRecordId."),
@@ -1923,28 +2120,18 @@ export const attioNotesRequestSchema = z.discriminatedUnion("action", [
1923
2120
  limit: z.number().int().nullable().optional(),
1924
2121
  offset: z.number().int().nullable().optional()
1925
2122
  }),
1926
- z.object({ action: z.literal("get").describe("Fetch a single note by ID."), noteId: z.string() }),
1927
- z.object({
1928
- action: z.literal("create").describe("Create a note on a record."),
1929
- parentObjectSlug: z.string().describe("The object type slug of the record the note belongs to."),
1930
- parentRecordId: z.string().describe("The record ID the note belongs to."),
1931
- title: z.string().describe("The note title."),
1932
- content: z.string().describe("The note body."),
1933
- format: z.enum(["plaintext", "markdown"]).nullable().optional().describe("Content format. Defaults to markdown.")
1934
- }),
1935
- z.object({ action: z.literal("delete").describe("Permanently delete a note."), noteId: z.string() })
2123
+ z.object({ action: z.literal("get").describe("Fetch a single note by ID."), noteId: z.string() })
1936
2124
  ]);
1937
- export const attioCommentsRequestSchema = z.discriminatedUnion("action", [
1938
- z.object({
1939
- action: z.literal("create").describe("Create a comment. Target EITHER an existing thread (threadId, to reply) OR a record (objectSlug + recordId, to start a new thread)."),
1940
- content: z.string().describe("The comment text (plaintext)."),
1941
- authorWorkspaceMemberId: z.string().describe("The workspace member ID the comment is authored as. Use attio_workspace_members to find it."),
1942
- threadId: z.string().nullable().optional().describe("Reply to this thread. Pass null/omit when commenting on a record."),
1943
- objectSlug: z.string().nullable().optional().describe("With recordId: start a new comment thread on this record."),
1944
- recordId: z.string().nullable().optional()
1945
- }),
2125
+ export const attioCreateNoteRequestSchema = z.object({
2126
+ parentObjectSlug: z.string().describe("The object type slug of the record the note belongs to."),
2127
+ parentRecordId: z.string().describe("The record ID the note belongs to."),
2128
+ title: z.string().describe("The note title."),
2129
+ content: z.string().describe("The note body."),
2130
+ format: z.enum(["plaintext", "markdown"]).nullable().optional().describe("Content format. Defaults to markdown.")
2131
+ });
2132
+ export const attioDeleteNoteRequestSchema = z.object({ noteId: z.string() });
2133
+ export const attioReadCommentsRequestSchema = z.discriminatedUnion("action", [
1946
2134
  z.object({ action: z.literal("get").describe("Fetch a single comment by ID."), commentId: z.string() }),
1947
- z.object({ action: z.literal("delete").describe("Permanently delete a comment."), commentId: z.string() }),
1948
2135
  z.object({
1949
2136
  action: z.literal("list_threads").describe("List comment threads on a record."),
1950
2137
  objectSlug: z.string().nullable().optional().describe("With recordId: threads on this record."),
@@ -1954,17 +2141,26 @@ export const attioCommentsRequestSchema = z.discriminatedUnion("action", [
1954
2141
  }),
1955
2142
  z.object({ action: z.literal("get_thread").describe("Fetch a thread with all of its comments."), threadId: z.string() })
1956
2143
  ]);
1957
- export const attioListsRequestSchema = z.discriminatedUnion("action", [
2144
+ export const attioCreateCommentRequestSchema = z.object({
2145
+ content: z.string().describe("The comment text (plaintext)."),
2146
+ authorWorkspaceMemberId: z.string().describe("The workspace member ID the comment is authored as. Use attio_workspace_members to find it."),
2147
+ threadId: z.string().nullable().optional().describe("Reply to this thread. Pass null/omit when commenting on a record."),
2148
+ objectSlug: z.string().nullable().optional().describe("With recordId: start a new comment thread on this record."),
2149
+ recordId: z.string().nullable().optional()
2150
+ });
2151
+ export const attioDeleteCommentRequestSchema = z.object({ commentId: z.string() });
2152
+ export const attioReadListsRequestSchema = z.discriminatedUnion("action", [
1958
2153
  z.object({ action: z.literal("list").describe("List all lists in the workspace.") }),
1959
- z.object({ action: z.literal("get").describe("Fetch a list's configuration by ID or slug."), listIdOrSlug: z.string() }),
1960
- z.object({
1961
- action: z.literal("create").describe("Create a new list over an object."),
1962
- name: z.string().describe("Display name of the list."),
1963
- apiSlug: z.string().describe("Unique slug for the list (snake_case)."),
1964
- parentObjectSlug: z.string().describe("The object the list contains records of (e.g. 'companies')."),
1965
- workspaceAccess: z.enum(["full-access", "read-and-write", "read-only"]).nullable().optional().describe("Workspace-wide access level. Defaults to full-access.")
1966
- }),
1967
- z.object({ action: z.literal("update").describe("Rename a list."), listIdOrSlug: z.string(), name: z.string() }),
2154
+ z.object({ action: z.literal("get").describe("Fetch a list's configuration by ID or slug."), listIdOrSlug: z.string() })
2155
+ ]);
2156
+ export const attioCreateListRequestSchema = z.object({
2157
+ name: z.string().describe("Display name of the list."),
2158
+ apiSlug: z.string().describe("Unique slug for the list (snake_case)."),
2159
+ parentObjectSlug: z.string().describe("The object the list contains records of (e.g. 'companies')."),
2160
+ workspaceAccess: z.enum(["full-access", "read-and-write", "read-only"]).nullable().optional().describe("Workspace-wide access level. Defaults to full-access.")
2161
+ });
2162
+ export const attioUpdateListRequestSchema = z.object({ listIdOrSlug: z.string(), name: z.string() });
2163
+ export const attioReadListEntriesRequestSchema = z.discriminatedUnion("action", [
1968
2164
  z.object({
1969
2165
  action: z.literal("query_entries").describe("List entries in a list, with optional filter, parent-record lookup, and limit/offset pagination."),
1970
2166
  listIdOrSlug: z.string(),
@@ -1974,30 +2170,27 @@ export const attioListsRequestSchema = z.discriminatedUnion("action", [
1974
2170
  limit: z.number().int().nullable().optional().describe("Maximum entries to return (max 500)."),
1975
2171
  offset: z.number().int().nullable().optional()
1976
2172
  }),
1977
- z.object({
1978
- action: z.literal("add_entry").describe("Add a record to a list as a new entry. Throws on unique-attribute conflicts; the same record may appear in multiple entries."),
1979
- listIdOrSlug: z.string(),
1980
- parentObjectSlug: z.string().describe("Object slug of the record being added."),
1981
- parentRecordId: z.string().describe("Record ID being added."),
1982
- entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values (e.g. a stage).")
1983
- }),
1984
- z.object({
1985
- action: z.literal("upsert_entry").describe("Create or update a list entry keyed by its parent record: updates the existing entry if the record is already in the list, otherwise adds it."),
1986
- listIdOrSlug: z.string(),
1987
- parentObjectSlug: z.string(),
1988
- parentRecordId: z.string(),
1989
- entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values.")
1990
- }),
1991
- z.object({ action: z.literal("get_entry").describe("Fetch a single list entry."), listIdOrSlug: z.string(), entryId: z.string() }),
1992
- z.object({
1993
- action: z.literal("update_entry").describe("Update a list entry's attribute values (e.g. move stage)."),
1994
- listIdOrSlug: z.string(),
1995
- entryId: z.string(),
1996
- entryValues: z.string().describe("JSON object string mapping entry attribute slugs to new values."),
1997
- multiselectMode: z.enum(["overwrite", "append"]).nullable().optional().describe("'overwrite' (default) replaces multi-value attribute values; 'append' adds to them.")
1998
- }),
1999
- z.object({ action: z.literal("remove_entry").describe("Remove an entry from a list. The parent record itself is untouched."), listIdOrSlug: z.string(), entryId: z.string() })
2173
+ z.object({ action: z.literal("get_entry").describe("Fetch a single list entry."), listIdOrSlug: z.string(), entryId: z.string() })
2000
2174
  ]);
2175
+ export const attioAddListEntryRequestSchema = z.object({
2176
+ listIdOrSlug: z.string(),
2177
+ parentObjectSlug: z.string().describe("Object slug of the record being added."),
2178
+ parentRecordId: z.string().describe("Record ID being added."),
2179
+ entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values (e.g. a stage).")
2180
+ });
2181
+ export const attioUpsertListEntryRequestSchema = z.object({
2182
+ listIdOrSlug: z.string(),
2183
+ parentObjectSlug: z.string(),
2184
+ parentRecordId: z.string(),
2185
+ entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values.")
2186
+ });
2187
+ export const attioUpdateListEntryRequestSchema = z.object({
2188
+ listIdOrSlug: z.string(),
2189
+ entryId: z.string(),
2190
+ entryValues: z.string().describe("JSON object string mapping entry attribute slugs to new values."),
2191
+ multiselectMode: z.enum(["overwrite", "append"]).nullable().optional().describe("'overwrite' (default) replaces multi-value attribute values; 'append' adds to them.")
2192
+ });
2193
+ export const attioRemoveListEntryRequestSchema = z.object({ listIdOrSlug: z.string(), entryId: z.string() });
2001
2194
  export const attioMeetingsRequestSchema = z.discriminatedUnion("action", [
2002
2195
  z.object({
2003
2196
  action: z.literal("list").describe("List meetings, optionally filtered by linked record, participants or time range. Uses cursor pagination."),
@@ -2023,7 +2216,7 @@ export const attioMeetingsRequestSchema = z.discriminatedUnion("action", [
2023
2216
  cursor: z.string().nullable().optional()
2024
2217
  })
2025
2218
  ]);
2026
- export const attioFilesRequestSchema = z.discriminatedUnion("action", [
2219
+ export const attioReadFilesRequestSchema = z.discriminatedUnion("action", [
2027
2220
  z.object({
2028
2221
  action: z.literal("list").describe("List files attached to a record."),
2029
2222
  objectSlug: z.string().describe("Object slug of the record."),
@@ -2032,24 +2225,28 @@ export const attioFilesRequestSchema = z.discriminatedUnion("action", [
2032
2225
  cursor: z.string().nullable().optional()
2033
2226
  }),
2034
2227
  z.object({ action: z.literal("get").describe("Fetch a file's metadata by ID."), fileId: z.string() }),
2035
- z.object({
2036
- action: z.literal("upload").describe("Upload a file to a record (native Attio storage, max 50 MB)."),
2037
- objectSlug: z.string(),
2038
- recordId: z.string(),
2039
- fileName: z.string().describe("File name including extension."),
2040
- contentBase64: z.string().describe("The file content, base64-encoded."),
2041
- contentType: z.string().nullable().optional().describe("MIME type. Defaults to application/octet-stream.")
2042
- }),
2043
- z.object({ action: z.literal("get_download_url").describe("Get a signed download URL for a file."), fileId: z.string() }),
2044
- z.object({ action: z.literal("delete").describe("Permanently delete a file (deleting a folder deletes its descendants)."), fileId: z.string() })
2228
+ z.object({ action: z.literal("get_download_url").describe("Get a signed download URL for a file."), fileId: z.string() })
2045
2229
  ]);
2230
+ export const attioUploadFileRequestSchema = z.object({
2231
+ objectSlug: z.string(),
2232
+ recordId: z.string(),
2233
+ fileName: z.string().describe("File name including extension."),
2234
+ contentBase64: z.string().describe("The file content, base64-encoded."),
2235
+ contentType: z.string().nullable().optional().describe("MIME type. Defaults to application/octet-stream.")
2236
+ });
2237
+ export const attioDeleteFileRequestSchema = z.object({ fileId: z.string() });
2046
2238
  const attioSchemaTargetFields = {
2047
2239
  target: z.enum(["objects", "lists"]).describe("Whether the attribute lives on an object or a list."),
2048
2240
  identifier: z.string().describe("The object slug (e.g. 'deals') or list ID/slug the attribute belongs to.")
2049
2241
  };
2050
- export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2242
+ export const attioReadSchemaRequestSchema = z.discriminatedUnion("action", [
2051
2243
  z.object({ action: z.literal("list_objects").describe("List all object types in the workspace with their attributes and field definitions. Call this before creating or updating records.") }),
2052
2244
  z.object({ action: z.literal("get_object").describe("Fetch one object's configuration."), objectSlug: z.string() }),
2245
+ z.object({ action: z.literal("list_attributes").describe("List the attributes defined on an object or list."), ...attioSchemaTargetFields }),
2246
+ z.object({ action: z.literal("list_statuses").describe("List the statuses of a status attribute (e.g. deal stages)."), ...attioSchemaTargetFields, attributeSlug: z.string() }),
2247
+ z.object({ action: z.literal("list_select_options").describe("List the options of a select attribute."), ...attioSchemaTargetFields, attributeSlug: z.string() })
2248
+ ]);
2249
+ export const attioModifySchemaRequestSchema = z.discriminatedUnion("action", [
2053
2250
  z.object({
2054
2251
  action: z.literal("create_object").describe("Create a custom object type. This changes the workspace schema for every user."),
2055
2252
  apiSlug: z.string().describe("Unique slug (snake_case)."),
@@ -2063,7 +2260,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2063
2260
  singularNoun: z.string().nullable().optional(),
2064
2261
  pluralNoun: z.string().nullable().optional()
2065
2262
  }),
2066
- z.object({ action: z.literal("list_attributes").describe("List the attributes defined on an object or list."), ...attioSchemaTargetFields }),
2067
2263
  z.object({
2068
2264
  action: z.literal("create_attribute").describe("Create a new attribute on an object or list. This changes the workspace schema for every user."),
2069
2265
  ...attioSchemaTargetFields,
@@ -2084,7 +2280,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2084
2280
  title: z.string().nullable().optional(),
2085
2281
  isRequired: z.boolean().nullable().optional()
2086
2282
  }),
2087
- z.object({ action: z.literal("list_statuses").describe("List the statuses of a status attribute (e.g. deal stages)."), ...attioSchemaTargetFields, attributeSlug: z.string() }),
2088
2283
  z.object({
2089
2284
  action: z.literal("create_status").describe("Add a new status to a status attribute. Rerun terse generate afterwards to refresh generated constants."),
2090
2285
  ...attioSchemaTargetFields,
@@ -2099,7 +2294,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2099
2294
  title: z.string().nullable().optional(),
2100
2295
  isArchived: z.boolean().nullable().optional()
2101
2296
  }),
2102
- z.object({ action: z.literal("list_select_options").describe("List the options of a select attribute."), ...attioSchemaTargetFields, attributeSlug: z.string() }),
2103
2297
  z.object({
2104
2298
  action: z.literal("create_select_option").describe("Add an option to a select attribute. Rerun terse generate afterwards to refresh generated constants."),
2105
2299
  ...attioSchemaTargetFields,
@@ -2193,56 +2387,166 @@ const attioToolInput = (request) => z.object({
2193
2387
  integrationId: z.string().describe("The integration ID of the Attio workspace to use."),
2194
2388
  request: request.describe("The operation to perform and its arguments.")
2195
2389
  });
2196
- export const attioTasksInputSchema = attioToolInput(attioTasksRequestSchema);
2197
- export const attioNotesInputSchema = attioToolInput(attioNotesRequestSchema);
2198
- export const attioCommentsInputSchema = attioToolInput(attioCommentsRequestSchema);
2199
- export const attioListsInputSchema = attioToolInput(attioListsRequestSchema);
2390
+ export const attioReadRecordsInputSchema = attioToolInput(attioReadRecordsRequestSchema);
2391
+ export const attioCreateRecordInputSchema = attioToolInput(attioCreateRecordRequestSchema);
2392
+ export const attioUpdateRecordInputSchema = attioToolInput(attioUpdateRecordRequestSchema);
2393
+ export const attioUpsertRecordsInputSchema = attioToolInput(attioUpsertRecordsRequestSchema);
2394
+ export const attioDeleteRecordInputSchema = attioToolInput(attioDeleteRecordRequestSchema);
2395
+ export const attioReadTasksInputSchema = attioToolInput(attioReadTasksRequestSchema);
2396
+ export const attioCreateTaskInputSchema = attioToolInput(attioCreateTaskRequestSchema);
2397
+ export const attioUpdateTaskInputSchema = attioToolInput(attioUpdateTaskRequestSchema);
2398
+ export const attioDeleteTaskInputSchema = attioToolInput(attioDeleteTaskRequestSchema);
2399
+ export const attioReadNotesInputSchema = attioToolInput(attioReadNotesRequestSchema);
2400
+ export const attioCreateNoteInputSchema = attioToolInput(attioCreateNoteRequestSchema);
2401
+ export const attioDeleteNoteInputSchema = attioToolInput(attioDeleteNoteRequestSchema);
2402
+ export const attioReadCommentsInputSchema = attioToolInput(attioReadCommentsRequestSchema);
2403
+ export const attioCreateCommentInputSchema = attioToolInput(attioCreateCommentRequestSchema);
2404
+ export const attioDeleteCommentInputSchema = attioToolInput(attioDeleteCommentRequestSchema);
2405
+ export const attioReadListsInputSchema = attioToolInput(attioReadListsRequestSchema);
2406
+ export const attioCreateListInputSchema = attioToolInput(attioCreateListRequestSchema);
2407
+ export const attioUpdateListInputSchema = attioToolInput(attioUpdateListRequestSchema);
2408
+ export const attioReadListEntriesInputSchema = attioToolInput(attioReadListEntriesRequestSchema);
2409
+ export const attioAddListEntryInputSchema = attioToolInput(attioAddListEntryRequestSchema);
2410
+ export const attioUpsertListEntryInputSchema = attioToolInput(attioUpsertListEntryRequestSchema);
2411
+ export const attioUpdateListEntryInputSchema = attioToolInput(attioUpdateListEntryRequestSchema);
2412
+ export const attioRemoveListEntryInputSchema = attioToolInput(attioRemoveListEntryRequestSchema);
2200
2413
  export const attioMeetingsInputSchema = attioToolInput(attioMeetingsRequestSchema);
2201
- export const attioFilesInputSchema = attioToolInput(attioFilesRequestSchema);
2202
- export const attioSchemaInputSchema = attioToolInput(attioSchemaRequestSchema);
2414
+ export const attioReadFilesInputSchema = attioToolInput(attioReadFilesRequestSchema);
2415
+ export const attioUploadFileInputSchema = attioToolInput(attioUploadFileRequestSchema);
2416
+ export const attioDeleteFileInputSchema = attioToolInput(attioDeleteFileRequestSchema);
2417
+ export const attioReadSchemaInputSchema = attioToolInput(attioReadSchemaRequestSchema);
2418
+ export const attioModifySchemaInputSchema = attioToolInput(attioModifySchemaRequestSchema);
2203
2419
  const attioToolOutputBaseSchema = toolOutputBaseSchema.omit({ success: true });
2204
- export const attioTasksTool = defineTool({
2205
- name: "attio_tasks",
2206
- inputSchema: attioTasksInputSchema,
2207
- outputSchema: attioToolOutputBaseSchema.extend({
2208
- tasks: z.array(attioTaskSchema).optional(),
2209
- task: attioTaskSchema.optional(),
2210
- count: z.number().int().optional()
2211
- })
2212
- });
2213
- export const attioNotesTool = defineTool({
2214
- name: "attio_notes",
2215
- inputSchema: attioNotesInputSchema,
2216
- outputSchema: attioToolOutputBaseSchema.extend({
2217
- notes: z.array(attioNoteSchema).optional(),
2218
- note: attioNoteSchema.optional(),
2219
- count: z.number().int().optional()
2220
- })
2221
- });
2222
- export const attioCommentsTool = defineTool({
2223
- name: "attio_comments",
2224
- inputSchema: attioCommentsInputSchema,
2225
- outputSchema: attioToolOutputBaseSchema.extend({
2226
- comment: attioCommentSchema.optional(),
2227
- threads: z.array(attioThreadSchema).optional(),
2228
- thread: attioThreadSchema.optional(),
2229
- count: z.number().int().optional()
2230
- })
2231
- });
2232
- export const attioListsTool = defineTool({
2233
- name: "attio_lists",
2234
- inputSchema: attioListsInputSchema,
2235
- outputSchema: attioToolOutputBaseSchema.extend({
2236
- lists: z.array(attioListSchema).optional(),
2237
- list: attioListSchema.optional(),
2238
- entries: z.array(attioListEntrySchema).optional(),
2239
- entry: attioListEntrySchema.optional(),
2240
- count: z.number().int().optional(),
2241
- offset: z.number().int().optional()
2242
- })
2420
+ const attioTasksOutputSchema = attioToolOutputBaseSchema.extend({
2421
+ tasks: z.array(attioTaskSchema).optional(),
2422
+ task: attioTaskSchema.optional(),
2423
+ count: z.number().int().optional()
2424
+ });
2425
+ export const attioReadTasksTool = defineTool({
2426
+ name: "attio_read_tasks",
2427
+ description: `Read Attio tasks. Actions: 'list' (filter by linked record or completion state; limit/offset pagination) and 'get' (fetch by task ID). Tasks are follow-ups and reminders tied to CRM records.`,
2428
+ inputSchema: attioReadTasksInputSchema,
2429
+ outputSchema: attioTasksOutputSchema
2430
+ });
2431
+ export const attioCreateTaskTool = defineTool({
2432
+ name: "attio_create_task",
2433
+ description: `Create an Attio task: content (plaintext) plus optional deadline, assignees (workspace-member emails or IDs) and linked records.`,
2434
+ inputSchema: attioCreateTaskInputSchema,
2435
+ outputSchema: attioTasksOutputSchema
2436
+ });
2437
+ export const attioUpdateTaskTool = defineTool({
2438
+ name: "attio_update_task",
2439
+ description: `Update an Attio task's deadline, completion state, assignees or linked records. Task content cannot be changed.`,
2440
+ inputSchema: attioUpdateTaskInputSchema,
2441
+ outputSchema: attioTasksOutputSchema
2442
+ });
2443
+ export const attioDeleteTaskTool = defineTool({
2444
+ name: "attio_delete_task",
2445
+ description: `Permanently delete an Attio task.`,
2446
+ inputSchema: attioDeleteTaskInputSchema,
2447
+ outputSchema: attioTasksOutputSchema
2448
+ });
2449
+ const attioNotesOutputSchema = attioToolOutputBaseSchema.extend({
2450
+ notes: z.array(attioNoteSchema).optional(),
2451
+ note: attioNoteSchema.optional(),
2452
+ count: z.number().int().optional()
2453
+ });
2454
+ export const attioReadNotesTool = defineTool({
2455
+ name: "attio_read_notes",
2456
+ description: `Read Attio notes on records. Actions: 'list' (optionally scoped to one record; limit/offset pagination) and 'get' (fetch by note ID).`,
2457
+ inputSchema: attioReadNotesInputSchema,
2458
+ outputSchema: attioNotesOutputSchema
2459
+ });
2460
+ export const attioCreateNoteTool = defineTool({
2461
+ name: "attio_create_note",
2462
+ description: `Create a note on an Attio record: title + markdown or plaintext content. Use for logging research, call summaries or context onto CRM records.`,
2463
+ inputSchema: attioCreateNoteInputSchema,
2464
+ outputSchema: attioNotesOutputSchema
2465
+ });
2466
+ export const attioDeleteNoteTool = defineTool({
2467
+ name: "attio_delete_note",
2468
+ description: `Permanently delete an Attio note.`,
2469
+ inputSchema: attioDeleteNoteInputSchema,
2470
+ outputSchema: attioNotesOutputSchema
2471
+ });
2472
+ const attioCommentsOutputSchema = attioToolOutputBaseSchema.extend({
2473
+ comment: attioCommentSchema.optional(),
2474
+ threads: z.array(attioThreadSchema).optional(),
2475
+ thread: attioThreadSchema.optional(),
2476
+ count: z.number().int().optional()
2477
+ });
2478
+ export const attioReadCommentsTool = defineTool({
2479
+ name: "attio_read_comments",
2480
+ description: `Read Attio comments and threads on records. Actions: 'get' (a single comment), 'list_threads' (threads on a record), 'get_thread' (a thread with all its comments).`,
2481
+ inputSchema: attioReadCommentsInputSchema,
2482
+ outputSchema: attioCommentsOutputSchema
2483
+ });
2484
+ export const attioCreateCommentTool = defineTool({
2485
+ name: "attio_create_comment",
2486
+ description: `Create an Attio comment: reply to a thread via threadId, or start a new thread on a record via objectSlug + recordId. Requires an author workspace member ID (use attio_workspace_members to find it).`,
2487
+ inputSchema: attioCreateCommentInputSchema,
2488
+ outputSchema: attioCommentsOutputSchema
2489
+ });
2490
+ export const attioDeleteCommentTool = defineTool({
2491
+ name: "attio_delete_comment",
2492
+ description: `Permanently delete an Attio comment.`,
2493
+ inputSchema: attioDeleteCommentInputSchema,
2494
+ outputSchema: attioCommentsOutputSchema
2495
+ });
2496
+ const attioListsOutputSchema = attioToolOutputBaseSchema.extend({
2497
+ lists: z.array(attioListSchema).optional(),
2498
+ list: attioListSchema.optional(),
2499
+ entries: z.array(attioListEntrySchema).optional(),
2500
+ entry: attioListEntrySchema.optional(),
2501
+ count: z.number().int().optional(),
2502
+ offset: z.number().int().optional()
2503
+ });
2504
+ export const attioReadListsTool = defineTool({
2505
+ name: "attio_read_lists",
2506
+ description: `Read Attio lists. Actions: 'list' (all lists in the workspace) and 'get' (a list's configuration by ID or slug). List entries have their own tools (attio_read_list_entries and the entry write tools).`,
2507
+ inputSchema: attioReadListsInputSchema,
2508
+ outputSchema: attioListsOutputSchema
2509
+ });
2510
+ export const attioCreateListTool = defineTool({
2511
+ name: "attio_create_list",
2512
+ description: `Create a new Attio list over an object. This changes the workspace for every user.`,
2513
+ inputSchema: attioCreateListInputSchema,
2514
+ outputSchema: attioListsOutputSchema
2515
+ });
2516
+ export const attioUpdateListTool = defineTool({ name: "attio_update_list", description: `Rename an Attio list.`, inputSchema: attioUpdateListInputSchema, outputSchema: attioListsOutputSchema });
2517
+ export const attioReadListEntriesTool = defineTool({
2518
+ name: "attio_read_list_entries",
2519
+ description: `Read entries of an Attio list. Actions: 'query_entries' (filter by entry attributes and/or parentRecordId; limit/offset pagination) and 'get_entry' (a single entry by ID).`,
2520
+ inputSchema: attioReadListEntriesInputSchema,
2521
+ outputSchema: attioListsOutputSchema
2522
+ });
2523
+ export const attioAddListEntryTool = defineTool({
2524
+ name: "attio_add_list_entry",
2525
+ description: `Add a record to an Attio list as a new entry, with optional entry attribute values (e.g. a stage). Throws on unique-attribute conflicts; the same record may appear in multiple entries.`,
2526
+ inputSchema: attioAddListEntryInputSchema,
2527
+ outputSchema: attioListsOutputSchema
2528
+ });
2529
+ export const attioUpsertListEntryTool = defineTool({
2530
+ name: "attio_upsert_list_entry",
2531
+ description: `Create or update an Attio list entry keyed by its parent record (idempotent membership): updates the existing entry if the record is already in the list, otherwise adds it.`,
2532
+ inputSchema: attioUpsertListEntryInputSchema,
2533
+ outputSchema: attioListsOutputSchema
2534
+ });
2535
+ export const attioUpdateListEntryTool = defineTool({
2536
+ name: "attio_update_list_entry",
2537
+ description: `Update an Attio list entry's attribute values (e.g. move its stage). multiselectMode 'append' adds to multi-value attributes instead of overwriting.`,
2538
+ inputSchema: attioUpdateListEntryInputSchema,
2539
+ outputSchema: attioListsOutputSchema
2540
+ });
2541
+ export const attioRemoveListEntryTool = defineTool({
2542
+ name: "attio_remove_list_entry",
2543
+ description: `Remove an entry from an Attio list. The parent record itself is untouched.`,
2544
+ inputSchema: attioRemoveListEntryInputSchema,
2545
+ outputSchema: attioListsOutputSchema
2243
2546
  });
2244
2547
  export const attioMeetingsTool = defineTool({
2245
2548
  name: "attio_meetings",
2549
+ description: `Read Attio meetings, call recordings and transcripts (read-only). Actions: 'list' (filter by linked record, participant emails or time range; cursor pagination via nextCursor), 'get', 'list_recordings' (recordings for a meeting), 'get_transcript' (transcript of a call recording). Use for call-summary and meeting-activity workflows.`,
2246
2550
  inputSchema: attioMeetingsInputSchema,
2247
2551
  outputSchema: attioToolOutputBaseSchema.extend({
2248
2552
  meetings: z.array(attioMeetingSchema).optional(),
@@ -2253,34 +2557,57 @@ export const attioMeetingsTool = defineTool({
2253
2557
  nextCursor: z.string().nullable().optional()
2254
2558
  })
2255
2559
  });
2256
- export const attioFilesTool = defineTool({
2257
- name: "attio_files",
2258
- inputSchema: attioFilesInputSchema,
2259
- outputSchema: attioToolOutputBaseSchema.extend({
2260
- files: z.array(attioFileSchema).optional(),
2261
- file: attioFileSchema.optional(),
2262
- downloadUrl: z.string().optional(),
2263
- count: z.number().int().optional(),
2264
- nextCursor: z.string().nullable().optional()
2265
- })
2266
- });
2267
- export const attioSchemaTool = defineTool({
2268
- name: "attio_schema",
2269
- inputSchema: attioSchemaInputSchema,
2270
- outputSchema: attioToolOutputBaseSchema.extend({
2271
- objects: z.array(attioObjectWithAttributesSchema).optional(),
2272
- object: attioObjectSchema.optional(),
2273
- attributes: z.array(attioAttributeSchema).optional(),
2274
- attribute: attioAttributeSchema.optional(),
2275
- statuses: z.array(attioStatusSchema).optional(),
2276
- status: attioStatusSchema.optional(),
2277
- selectOptions: z.array(attioSelectOptionEntitySchema).optional(),
2278
- selectOption: attioSelectOptionEntitySchema.optional(),
2279
- count: z.number().int().optional()
2280
- })
2560
+ const attioFilesOutputSchema = attioToolOutputBaseSchema.extend({
2561
+ files: z.array(attioFileSchema).optional(),
2562
+ file: attioFileSchema.optional(),
2563
+ downloadUrl: z.string().optional(),
2564
+ count: z.number().int().optional(),
2565
+ nextCursor: z.string().nullable().optional()
2566
+ });
2567
+ export const attioReadFilesTool = defineTool({
2568
+ name: "attio_read_files",
2569
+ description: `Read files attached to Attio records. Actions: 'list' (files on a record; cursor pagination), 'get' (file metadata), 'get_download_url' (signed URL for a file).`,
2570
+ inputSchema: attioReadFilesInputSchema,
2571
+ outputSchema: attioFilesOutputSchema
2572
+ });
2573
+ export const attioUploadFileTool = defineTool({
2574
+ name: "attio_upload_file",
2575
+ description: `Upload a file to an Attio record from base64 content (native Attio storage, max 50 MB).`,
2576
+ inputSchema: attioUploadFileInputSchema,
2577
+ outputSchema: attioFilesOutputSchema
2578
+ });
2579
+ export const attioDeleteFileTool = defineTool({
2580
+ name: "attio_delete_file",
2581
+ description: `Permanently delete a file from Attio (deleting a folder deletes its descendants).`,
2582
+ inputSchema: attioDeleteFileInputSchema,
2583
+ outputSchema: attioFilesOutputSchema
2584
+ });
2585
+ const attioSchemaOutputSchema = attioToolOutputBaseSchema.extend({
2586
+ objects: z.array(attioObjectWithAttributesSchema).optional(),
2587
+ object: attioObjectSchema.optional(),
2588
+ attributes: z.array(attioAttributeSchema).optional(),
2589
+ attribute: attioAttributeSchema.optional(),
2590
+ statuses: z.array(attioStatusSchema).optional(),
2591
+ status: attioStatusSchema.optional(),
2592
+ selectOptions: z.array(attioSelectOptionEntitySchema).optional(),
2593
+ selectOption: attioSelectOptionEntitySchema.optional(),
2594
+ count: z.number().int().optional()
2595
+ });
2596
+ export const attioReadSchemaTool = defineTool({
2597
+ name: "attio_read_schema",
2598
+ description: `Read the Attio workspace schema. Actions: 'list_objects' (all object types with attributes — call before creating/updating records), 'get_object', 'list_attributes', 'list_statuses' (e.g. deal stages), 'list_select_options'. Attributes on lists use target 'lists'; on objects, target 'objects'.`,
2599
+ inputSchema: attioReadSchemaInputSchema,
2600
+ outputSchema: attioSchemaOutputSchema
2601
+ });
2602
+ export const attioModifySchemaTool = defineTool({
2603
+ name: "attio_modify_schema",
2604
+ description: `Change the Attio workspace schema — these writes affect every user of the workspace. Actions: 'create_object', 'update_object', 'create_attribute', 'update_attribute', 'create_status', 'update_status', 'create_select_option', 'update_select_option'. Attributes on lists use target 'lists'; on objects, target 'objects'. After schema writes, rerun terse generate to refresh generated types/constants.`,
2605
+ inputSchema: attioModifySchemaInputSchema,
2606
+ outputSchema: attioSchemaOutputSchema
2281
2607
  });
2282
2608
  export const attioWorkspaceMembersTool = defineTool({
2283
2609
  name: "attio_workspace_members",
2610
+ description: `Look up Attio workspace members (the people who use the CRM, not CRM records). Actions: 'list' returns every member with name, email address and access level; 'get' fetches one member by ID. Use this to resolve a record's owner (an actor reference holding a workspace member ID) to a person, e.g. to find the email address for a Slack DM, or to find the member ID/email to write into an owner attribute.`,
2284
2611
  inputSchema: attioWorkspaceMembersInputSchema,
2285
2612
  outputSchema: attioToolOutputBaseSchema.extend({
2286
2613
  members: z.array(attioWorkspaceMemberSchema).optional(),
@@ -2288,20 +2615,47 @@ export const attioWorkspaceMembersTool = defineTool({
2288
2615
  count: z.number().int().optional()
2289
2616
  })
2290
2617
  });
2291
- export const attioRecordsTool = defineTool({
2292
- name: "attio_records",
2293
- inputSchema: attioRecordsInputSchema,
2294
- outputSchema: attioToolOutputBaseSchema.extend({
2295
- records: z.array(attioRecordSchema).optional(),
2296
- record: attioRecordSchema.optional(),
2297
- matches: z.array(attioSearchMatchSchema).optional(),
2298
- history: z.array(attioAttributeHistoryEntrySchema).optional(),
2299
- count: z.number().int().optional(),
2300
- offset: z.number().int().optional()
2301
- })
2618
+ const attioRecordsOutputSchema = attioToolOutputBaseSchema.extend({
2619
+ records: z.array(attioRecordSchema).optional(),
2620
+ record: attioRecordSchema.optional(),
2621
+ matches: z.array(attioSearchMatchSchema).optional(),
2622
+ history: z.array(attioAttributeHistoryEntrySchema).optional(),
2623
+ count: z.number().int().optional(),
2624
+ offset: z.number().int().optional()
2625
+ });
2626
+ export const attioReadRecordsTool = defineTool({
2627
+ name: "attio_read_records",
2628
+ description: `Read records in Attio. Actions: 'query' (filtered listing with limit/offset pagination), 'search' (fuzzy match by name/email/domain; eventually consistent — use 'query' for read-after-write), 'get' (fetch by record ID), and 'get_attribute_history' (historic values of one attribute, e.g. every stage a deal has been in). Use attio_read_schema with the 'list_objects' action first to discover objects and their attributes.`,
2629
+ inputSchema: attioReadRecordsInputSchema,
2630
+ outputSchema: attioRecordsOutputSchema
2631
+ });
2632
+ export const attioCreateRecordTool = defineTool({
2633
+ name: "attio_create_record",
2634
+ description: `Create a new record in Attio. Unlike attio_upsert_record, no matching attribute is needed, so this works for objects without a unique writable attribute (e.g. deals).`,
2635
+ inputSchema: attioCreateRecordInputSchema,
2636
+ outputSchema: attioRecordsOutputSchema
2637
+ });
2638
+ export const attioUpdateRecordTool = defineTool({
2639
+ name: "attio_update_record",
2640
+ description: `Update an existing Attio record by its ID. Only the attributes present in 'values' are touched; multiselectMode 'append' adds to multi-value attributes instead of overwriting them.`,
2641
+ inputSchema: attioUpdateRecordInputSchema,
2642
+ outputSchema: attioRecordsOutputSchema
2643
+ });
2644
+ export const attioUpsertRecordsTool = defineTool({
2645
+ name: "attio_upsert_record",
2646
+ description: `Create or update one or more Attio records, matched on a unique writable attribute (e.g. 'email_addresses' for people, 'domains' for companies). If a match is found the record is updated, otherwise a new one is created. Throws if ANY record in the batch fails, naming each failure; earlier records may already be written (upserts are safe to retry).`,
2647
+ inputSchema: attioUpsertRecordsInputSchema,
2648
+ outputSchema: attioRecordsOutputSchema
2649
+ });
2650
+ export const attioDeleteRecordTool = defineTool({
2651
+ name: "attio_delete_record",
2652
+ description: `Permanently delete an Attio record by its ID. This cannot be undone.`,
2653
+ inputSchema: attioDeleteRecordInputSchema,
2654
+ outputSchema: attioRecordsOutputSchema
2302
2655
  });
2303
2656
  export const listWorkOSUsersTool = defineTool({
2304
2657
  name: "listWorkOSUsers",
2658
+ description: "List users from the customer's WorkOS account. Supports filtering by email and organization ID. Returns user profiles including email, name, and creation date. Use pagination (after cursor) for large user sets.",
2305
2659
  inputSchema: listWorkOSUsersInputSchema,
2306
2660
  outputSchema: toolOutputBaseSchema.extend({
2307
2661
  users: z.array(workOSUserSummarySchema),
@@ -2311,6 +2665,7 @@ export const listWorkOSUsersTool = defineTool({
2311
2665
  });
2312
2666
  export const listWorkOSOrganizationsTool = defineTool({
2313
2667
  name: "listWorkOSOrganizations",
2668
+ description: "List organizations from the customer's WorkOS account. Returns organization names, domains, external IDs, and timestamps. Use pagination (after cursor) for large organization sets.",
2314
2669
  inputSchema: listWorkOSOrganizationsInputSchema,
2315
2670
  outputSchema: toolOutputBaseSchema.extend({
2316
2671
  organizations: z.array(workOSOrganizationSummarySchema),
@@ -2320,6 +2675,7 @@ export const listWorkOSOrganizationsTool = defineTool({
2320
2675
  });
2321
2676
  export const getWorkOSUserTool = defineTool({
2322
2677
  name: "getWorkOSUser",
2678
+ description: "Get detailed information about a specific WorkOS user by their user ID. Returns profile data including email, name, verification status, and timestamps.",
2323
2679
  inputSchema: getWorkOSUserInputSchema,
2324
2680
  outputSchema: toolOutputBaseSchema.extend({
2325
2681
  user: workOSUserSummarySchema,
@@ -2328,6 +2684,7 @@ export const getWorkOSUserTool = defineTool({
2328
2684
  });
2329
2685
  export const listLaunchDarklyFlagsTool = defineTool({
2330
2686
  name: "listLaunchDarklyFlags",
2687
+ description: "List all feature flags with enabled/disabled states per environment. Use summary=true for quick overview, summary=false for full details.",
2331
2688
  inputSchema: listLaunchDarklyFlagsInputSchema,
2332
2689
  outputSchema: toolOutputBaseSchema.extend({
2333
2690
  projectKey: z.string(),
@@ -2339,6 +2696,7 @@ export const listLaunchDarklyFlagsTool = defineTool({
2339
2696
  });
2340
2697
  export const getLaunchDarklyFlagDetailsTool = defineTool({
2341
2698
  name: "getLaunchDarklyFlagDetails",
2699
+ description: "Get detailed information about a specific feature flag including targeting rules, rollout strategies, variations, and per-environment configuration. Optionally includes change history when includeHistory=true.",
2342
2700
  inputSchema: getLaunchDarklyFlagDetailsInputSchema,
2343
2701
  outputSchema: toolOutputBaseSchema.extend({
2344
2702
  projectKey: z.string(),
@@ -2351,6 +2709,7 @@ export const getLaunchDarklyFlagDetailsTool = defineTool({
2351
2709
  });
2352
2710
  export const snowflakeExecuteQueryTool = defineTool({
2353
2711
  name: "snowflakeExecuteQuery",
2712
+ description: "Execute a read-only SQL query against a Snowflake data warehouse. Returns rows and column metadata. SQL safety is enforced by the Snowflake role configured for the integration — use a read-only role.",
2354
2713
  inputSchema: snowflakeExecuteQueryInputSchema,
2355
2714
  outputSchema: toolOutputBaseSchema.extend({
2356
2715
  rows: z.array(snowflakeQueryRowSchema),
@@ -2360,6 +2719,7 @@ export const snowflakeExecuteQueryTool = defineTool({
2360
2719
  });
2361
2720
  export const snowflakeExplainQueryTool = defineTool({
2362
2721
  name: "snowflakeExplainQuery",
2722
+ description: "Get the query execution plan for a Snowflake SQL query using EXPLAIN. Use this to understand how Snowflake will execute a query before running it.",
2363
2723
  inputSchema: snowflakeExplainQueryInputSchema,
2364
2724
  outputSchema: toolOutputBaseSchema.extend({
2365
2725
  explainPlan: z.array(snowflakeQueryRowSchema),
@@ -2369,6 +2729,7 @@ export const snowflakeExplainQueryTool = defineTool({
2369
2729
  });
2370
2730
  export const webSearchTool = defineTool({
2371
2731
  name: "web_search",
2732
+ description: "Search the web for up-to-date information. Returns ranked results with titles, URLs, and content snippets. Use for questions about current events, facts, or topics requiring web sources.",
2372
2733
  inputSchema: z.object({
2373
2734
  query: z.string().describe("The search query"),
2374
2735
  max_results: z.number().int().min(1).max(10).nullable().describe("Number of results to return (default 5)"),
@@ -2427,6 +2788,7 @@ export const memoryOutputSchema = toolOutputBaseSchema.extend({
2427
2788
  });
2428
2789
  export const memoryTool = defineTool({
2429
2790
  name: "memory",
2791
+ description: "Persistent memory stored under /memories that survives across runs. Commands: view (read a file or list a directory), create, str_replace, insert, delete, rename. Always view /memories before starting a task, and record durable progress and learnings as you work.",
2430
2792
  inputSchema: memoryInputSchema,
2431
2793
  outputSchema: memoryOutputSchema
2432
2794
  });
@@ -2466,15 +2828,36 @@ export const ToolDefinitions = {
2466
2828
  [getPosthogSessionEventsTool.name]: getPosthogSessionEventsTool,
2467
2829
  [listPosthogEventNamesTool.name]: listPosthogEventNamesTool,
2468
2830
  [searchPosthogEventsTool.name]: searchPosthogEventsTool,
2469
- [attioRecordsTool.name]: attioRecordsTool,
2831
+ [attioReadRecordsTool.name]: attioReadRecordsTool,
2832
+ [attioCreateRecordTool.name]: attioCreateRecordTool,
2833
+ [attioUpdateRecordTool.name]: attioUpdateRecordTool,
2834
+ [attioUpsertRecordsTool.name]: attioUpsertRecordsTool,
2835
+ [attioDeleteRecordTool.name]: attioDeleteRecordTool,
2470
2836
  [attioWorkspaceMembersTool.name]: attioWorkspaceMembersTool,
2471
- [attioTasksTool.name]: attioTasksTool,
2472
- [attioNotesTool.name]: attioNotesTool,
2473
- [attioCommentsTool.name]: attioCommentsTool,
2474
- [attioListsTool.name]: attioListsTool,
2837
+ [attioReadTasksTool.name]: attioReadTasksTool,
2838
+ [attioCreateTaskTool.name]: attioCreateTaskTool,
2839
+ [attioUpdateTaskTool.name]: attioUpdateTaskTool,
2840
+ [attioDeleteTaskTool.name]: attioDeleteTaskTool,
2841
+ [attioReadNotesTool.name]: attioReadNotesTool,
2842
+ [attioCreateNoteTool.name]: attioCreateNoteTool,
2843
+ [attioDeleteNoteTool.name]: attioDeleteNoteTool,
2844
+ [attioReadCommentsTool.name]: attioReadCommentsTool,
2845
+ [attioCreateCommentTool.name]: attioCreateCommentTool,
2846
+ [attioDeleteCommentTool.name]: attioDeleteCommentTool,
2847
+ [attioReadListsTool.name]: attioReadListsTool,
2848
+ [attioCreateListTool.name]: attioCreateListTool,
2849
+ [attioUpdateListTool.name]: attioUpdateListTool,
2850
+ [attioReadListEntriesTool.name]: attioReadListEntriesTool,
2851
+ [attioAddListEntryTool.name]: attioAddListEntryTool,
2852
+ [attioUpsertListEntryTool.name]: attioUpsertListEntryTool,
2853
+ [attioUpdateListEntryTool.name]: attioUpdateListEntryTool,
2854
+ [attioRemoveListEntryTool.name]: attioRemoveListEntryTool,
2475
2855
  [attioMeetingsTool.name]: attioMeetingsTool,
2476
- [attioFilesTool.name]: attioFilesTool,
2477
- [attioSchemaTool.name]: attioSchemaTool,
2856
+ [attioReadFilesTool.name]: attioReadFilesTool,
2857
+ [attioUploadFileTool.name]: attioUploadFileTool,
2858
+ [attioDeleteFileTool.name]: attioDeleteFileTool,
2859
+ [attioReadSchemaTool.name]: attioReadSchemaTool,
2860
+ [attioModifySchemaTool.name]: attioModifySchemaTool,
2478
2861
  [listWorkOSUsersTool.name]: listWorkOSUsersTool,
2479
2862
  [listWorkOSOrganizationsTool.name]: listWorkOSOrganizationsTool,
2480
2863
  [getWorkOSUserTool.name]: getWorkOSUserTool,