terse-types 0.0.72 → 0.0.74

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
@@ -101,7 +101,8 @@ export const linearSearchPaginationSchema = z.object({
101
101
  });
102
102
  export const slackUserResponseSchema = z.object({
103
103
  id: z.string(),
104
- name: z.string()
104
+ name: z.string(),
105
+ email: z.string().optional()
105
106
  });
106
107
  export const slackChannelListItemSchema = z.object({
107
108
  id: z.string().optional(),
@@ -574,7 +575,7 @@ export const slackListChannelsInputSchema = z.object({
574
575
  });
575
576
  export const slackListUsersInputSchema = z.object({
576
577
  integrationId: z.string().describe("The integration ID of the Slack workspace (user_slack_integrations id)."),
577
- query: z.string().nullable().optional().describe("Optional search query to filter users by name. Case-insensitive partial match.")
578
+ query: z.string().nullable().optional().describe("Optional search query to filter users by name or email. Case-insensitive partial match.")
578
579
  });
579
580
  export const slackReadConversationInputSchema = z.object({
580
581
  integrationId: z.string().describe("The integration ID of the Slack workspace (user_slack_integrations id)."),
@@ -956,6 +957,7 @@ export const searchPosthogEventsInputSchema = z.object({
956
957
  });
957
958
  export const linearCreateTicketTool = defineTool({
958
959
  name: "linear_create_ticket",
960
+ description: "Create a new Linear issue/ticket.",
959
961
  inputSchema: linearCreateTicketInputSchema,
960
962
  outputSchema: toolOutputBaseSchema.extend({
961
963
  issue: linearIssueHandleSchema
@@ -963,6 +965,7 @@ export const linearCreateTicketTool = defineTool({
963
965
  });
964
966
  export const linearUpdateTicketTool = defineTool({
965
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.`,
966
969
  inputSchema: linearUpdateTicketInputSchema,
967
970
  outputSchema: toolOutputBaseSchema.extend({
968
971
  issue: linearIssueHandleSchema
@@ -970,6 +973,7 @@ export const linearUpdateTicketTool = defineTool({
970
973
  });
971
974
  export const linearAddCommentTool = defineTool({
972
975
  name: "linear_add_comment",
976
+ description: `Add a comment to an existing Linear issue. Use linear_search_ticket to find the issue ID.`,
973
977
  inputSchema: linearAddCommentInputSchema,
974
978
  outputSchema: toolOutputBaseSchema.extend({
975
979
  comment: linearCommentHandleSchema
@@ -977,6 +981,7 @@ export const linearAddCommentTool = defineTool({
977
981
  });
978
982
  export const linearSearchTicketTool = defineTool({
979
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.`,
980
985
  inputSchema: linearSearchTicketInputSchema,
981
986
  outputSchema: toolOutputBaseSchema.extend({
982
987
  issues: z.array(linearIssueSummarySchema),
@@ -987,6 +992,8 @@ export const linearSearchTicketTool = defineTool({
987
992
  });
988
993
  export const linearReadTicketTool = defineTool({
989
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.`,
990
997
  inputSchema: linearReadTicketInputSchema,
991
998
  outputSchema: toolOutputBaseSchema.extend({
992
999
  issue: linearIssueDetailSchema,
@@ -995,6 +1002,7 @@ export const linearReadTicketTool = defineTool({
995
1002
  });
996
1003
  export const linearGetStatesTool = defineTool({
997
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").`,
998
1006
  inputSchema: linearGetStatesInputSchema,
999
1007
  outputSchema: toolOutputBaseSchema.extend({
1000
1008
  states: z.array(linearStateSummarySchema)
@@ -1002,6 +1010,7 @@ export const linearGetStatesTool = defineTool({
1002
1010
  });
1003
1011
  export const linearGetLabelsTool = defineTool({
1004
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.`,
1005
1014
  inputSchema: linearGetLabelsInputSchema,
1006
1015
  outputSchema: toolOutputBaseSchema.extend({
1007
1016
  labels: z.array(linearLabelSummarySchema)
@@ -1009,6 +1018,7 @@ export const linearGetLabelsTool = defineTool({
1009
1018
  });
1010
1019
  export const linearGetProjectsTool = defineTool({
1011
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.`,
1012
1022
  inputSchema: linearGetProjectsInputSchema,
1013
1023
  outputSchema: toolOutputBaseSchema.extend({
1014
1024
  projects: z.array(linearProjectSummarySchema)
@@ -1016,6 +1026,7 @@ export const linearGetProjectsTool = defineTool({
1016
1026
  });
1017
1027
  export const linearGetTeamsTool = defineTool({
1018
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.`,
1019
1030
  inputSchema: linearGetTeamsInputSchema,
1020
1031
  outputSchema: toolOutputBaseSchema.extend({
1021
1032
  teams: z.array(linearTeamSchema)
@@ -1023,6 +1034,7 @@ export const linearGetTeamsTool = defineTool({
1023
1034
  });
1024
1035
  export const linearGetUsersTool = defineTool({
1025
1036
  name: "linear_get_users",
1037
+ description: `List users in the Linear workspace. Use to pick assigneeId or subscriberIds when creating or updating issues.`,
1026
1038
  inputSchema: linearGetUsersInputSchema,
1027
1039
  outputSchema: toolOutputBaseSchema.extend({
1028
1040
  users: z.array(linearUserSummarySchema)
@@ -1030,6 +1042,7 @@ export const linearGetUsersTool = defineTool({
1030
1042
  });
1031
1043
  export const slackSendMessageTool = defineTool({
1032
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.`,
1033
1046
  inputSchema: slackSendMessageInputSchema,
1034
1047
  outputSchema: toolOutputBaseSchema.extend({
1035
1048
  message_ts: z.string().optional(),
@@ -1041,6 +1054,9 @@ export const slackSendMessageTool = defineTool({
1041
1054
  });
1042
1055
  export const slackListChannelsTool = defineTool({
1043
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.`,
1044
1060
  inputSchema: slackListChannelsInputSchema,
1045
1061
  outputSchema: toolOutputBaseSchema.extend({
1046
1062
  channels: z.array(slackChannelListItemSchema),
@@ -1051,6 +1067,8 @@ export const slackListChannelsTool = defineTool({
1051
1067
  });
1052
1068
  export const slackListUsersTool = defineTool({
1053
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.`,
1054
1072
  inputSchema: slackListUsersInputSchema,
1055
1073
  outputSchema: toolOutputBaseSchema.extend({
1056
1074
  users: z.array(slackUserResponseSchema),
@@ -1059,6 +1077,9 @@ export const slackListUsersTool = defineTool({
1059
1077
  });
1060
1078
  export const slackReadConversationTool = defineTool({
1061
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.`,
1062
1083
  inputSchema: slackReadConversationInputSchema,
1063
1084
  outputSchema: toolOutputBaseSchema.extend({
1064
1085
  channelId: z.string(),
@@ -1071,6 +1092,26 @@ export const slackReadConversationTool = defineTool({
1071
1092
  });
1072
1093
  export const searchGitHubCodeTool = defineTool({
1073
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`,
1074
1115
  inputSchema: searchGitHubCodeInputSchema,
1075
1116
  outputSchema: toolOutputBaseSchema.extend({
1076
1117
  totalCount: z.number().int(),
@@ -1085,6 +1126,24 @@ export const searchGitHubCodeTool = defineTool({
1085
1126
  });
1086
1127
  export const grepGitHubCodeTool = defineTool({
1087
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.`,
1088
1147
  inputSchema: grepGitHubCodeInputSchema,
1089
1148
  outputSchema: toolOutputBaseSchema.extend({
1090
1149
  totalCount: z.number().int(),
@@ -1100,6 +1159,13 @@ export const grepGitHubCodeTool = defineTool({
1100
1159
  });
1101
1160
  export const readGitHubFileTool = defineTool({
1102
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.`,
1103
1169
  inputSchema: readGitHubFileInputSchema,
1104
1170
  outputSchema: toolOutputBaseSchema.extend({
1105
1171
  repository: z.string(),
@@ -1114,6 +1180,13 @@ export const readGitHubFileTool = defineTool({
1114
1180
  });
1115
1181
  export const listGitHubDirectoryTool = defineTool({
1116
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.`,
1117
1190
  inputSchema: listGitHubDirectoryInputSchema,
1118
1191
  outputSchema: toolOutputBaseSchema.extend({
1119
1192
  repository: z.string(),
@@ -1130,6 +1203,14 @@ export const listGitHubDirectoryTool = defineTool({
1130
1203
  });
1131
1204
  export const listGitHubPullRequestsTool = defineTool({
1132
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).`,
1133
1214
  inputSchema: listGitHubPullRequestsInputSchema,
1134
1215
  outputSchema: toolOutputBaseSchema.extend({
1135
1216
  repository: z.string(),
@@ -1142,6 +1223,14 @@ export const listGitHubPullRequestsTool = defineTool({
1142
1223
  });
1143
1224
  export const listGitHubCommitsTool = defineTool({
1144
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.`,
1145
1234
  inputSchema: listGitHubCommitsInputSchema,
1146
1235
  outputSchema: toolOutputBaseSchema.extend({
1147
1236
  repository: z.string(),
@@ -1155,6 +1244,22 @@ export const listGitHubCommitsTool = defineTool({
1155
1244
  });
1156
1245
  export const summarizeGitHubPullRequestDiffTool = defineTool({
1157
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.`,
1158
1263
  inputSchema: summarizeGitHubPullRequestDiffInputSchema,
1159
1264
  outputSchema: toolOutputBaseSchema.extend({
1160
1265
  repository: z.string(),
@@ -1167,21 +1272,57 @@ export const summarizeGitHubPullRequestDiffTool = defineTool({
1167
1272
  });
1168
1273
  export const notionCreateOrUpdatePageTool = defineTool({
1169
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.`,
1170
1279
  inputSchema: notionCreateOrUpdatePageInputSchema,
1171
1280
  outputSchema: notionDatabaseRowMutationResultSchema
1172
1281
  });
1173
1282
  export const notionCreateOrUpdateDatabaseRowTool = defineTool({
1174
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.`,
1175
1287
  inputSchema: notionCreateOrUpdateDatabaseRowInputSchema,
1176
1288
  outputSchema: notionDatabaseRowMutationResultSchema
1177
1289
  });
1178
1290
  export const notionModifyBlocksTool = defineTool({
1179
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).`,
1180
1318
  inputSchema: notionModifyBlocksInputSchema,
1181
1319
  outputSchema: z.union([notionModifyBlocksSuccessSchema, notionModifyBlocksFailureSchema])
1182
1320
  });
1183
1321
  export const notionQueryPageTool = defineTool({
1184
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.`,
1185
1326
  inputSchema: notionQueryPageInputSchema,
1186
1327
  outputSchema: notionPageQueryMetadataSchema.extend({
1187
1328
  success: z.literal(true),
@@ -1194,11 +1335,63 @@ export const notionQueryPageTool = defineTool({
1194
1335
  });
1195
1336
  export const notionQueryDatabaseTool = defineTool({
1196
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.`,
1197
1380
  inputSchema: notionQueryDatabaseInputSchema,
1198
1381
  outputSchema: z.discriminatedUnion("success", [notionQueryDatabaseSuccessSchema, notionQueryDatabaseFailureSchema])
1199
1382
  });
1200
1383
  export const notionGetSchemaTool = defineTool({
1201
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.`,
1202
1395
  inputSchema: notionGetSchemaInputSchema,
1203
1396
  outputSchema: toolOutputSuccessSchema.extend({
1204
1397
  data_source_id: z.string(),
@@ -1209,6 +1402,13 @@ export const notionGetSchemaTool = defineTool({
1209
1402
  });
1210
1403
  export const notionListUsersTool = defineTool({
1211
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>"}]}}`,
1212
1412
  inputSchema: notionListUsersInputSchema,
1213
1413
  outputSchema: toolOutputSuccessSchema.extend({
1214
1414
  users: z.array(notionWorkspaceUserSchema),
@@ -1217,21 +1417,25 @@ export const notionListUsersTool = defineTool({
1217
1417
  });
1218
1418
  export const gmailSendEmailTool = defineTool({
1219
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.`,
1220
1421
  inputSchema: gmailSendEmailInputSchema,
1221
1422
  outputSchema: toolOutputSuccessSchema.merge(gmailSendSummarySchema)
1222
1423
  });
1223
1424
  export const gmailCreateDraftTool = defineTool({
1224
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.`,
1225
1427
  inputSchema: gmailCreateDraftInputSchema,
1226
1428
  outputSchema: toolOutputSuccessSchema.merge(gmailDraftSummarySchema)
1227
1429
  });
1228
1430
  export const searchPosthogSessionsTool = defineTool({
1229
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.",
1230
1433
  inputSchema: searchPosthogSessionsInputSchema,
1231
1434
  outputSchema: z.union([posthogSearchSessionsFoundSchema, posthogSearchSessionsNotFoundSchema])
1232
1435
  });
1233
1436
  export const searchPosthogLogsTool = defineTool({
1234
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.",
1235
1439
  inputSchema: searchPosthogLogsInputSchema,
1236
1440
  outputSchema: toolOutputSuccessSchema.extend({
1237
1441
  userEmail: z.string().nullable(),
@@ -1247,6 +1451,7 @@ export const searchPosthogLogsTool = defineTool({
1247
1451
  });
1248
1452
  export const getPosthogSessionEventsTool = defineTool({
1249
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.",
1250
1455
  inputSchema: getPosthogSessionEventsInputSchema,
1251
1456
  outputSchema: toolOutputSuccessSchema.extend({
1252
1457
  sessionId: z.string(),
@@ -1262,6 +1467,7 @@ export const getPosthogSessionEventsTool = defineTool({
1262
1467
  });
1263
1468
  export const listPosthogEventNamesTool = defineTool({
1264
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.",
1265
1471
  inputSchema: listPosthogEventNamesInputSchema,
1266
1472
  outputSchema: toolOutputSuccessSchema.extend({
1267
1473
  eventCounts: z.array(posthogEventCountSchema),
@@ -1271,6 +1477,7 @@ export const listPosthogEventNamesTool = defineTool({
1271
1477
  });
1272
1478
  export const searchPosthogEventsTool = defineTool({
1273
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.",
1274
1481
  inputSchema: searchPosthogEventsInputSchema,
1275
1482
  outputSchema: toolOutputSuccessSchema.extend({
1276
1483
  events: z.array(posthogEventSummarySchema),
@@ -1472,6 +1679,7 @@ export const imageEditInputSchema = z.object({
1472
1679
  });
1473
1680
  export const searchDatadogLogsTool = defineTool({
1474
1681
  name: "searchDatadogLogs",
1682
+ description: "Query Datadog logs. Filter by query string, indexes, time range. Returns logs with timestamps, status, messages, hosts, services, tags.",
1475
1683
  inputSchema: searchDatadogLogsInputSchema,
1476
1684
  outputSchema: toolOutputBaseSchema.extend({
1477
1685
  query: z.string().nullable(),
@@ -1486,6 +1694,7 @@ export const searchDatadogLogsTool = defineTool({
1486
1694
  });
1487
1695
  export const searchRumEventsTool = defineTool({
1488
1696
  name: "searchRumEvents",
1697
+ description: "Query Datadog RUM events. Filter by query string, time range. Returns sessions, views, actions, errors, resources, long tasks.",
1489
1698
  inputSchema: searchRumEventsInputSchema,
1490
1699
  outputSchema: toolOutputBaseSchema.extend({
1491
1700
  query: z.string().nullable(),
@@ -1500,6 +1709,7 @@ export const searchRumEventsTool = defineTool({
1500
1709
  });
1501
1710
  export const listRumEventsTool = defineTool({
1502
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.",
1503
1713
  inputSchema: listRumEventsInputSchema,
1504
1714
  outputSchema: toolOutputBaseSchema.extend({
1505
1715
  query: z.string().nullable(),
@@ -1514,6 +1724,7 @@ export const listRumEventsTool = defineTool({
1514
1724
  });
1515
1725
  export const aggregateRumEventsTool = defineTool({
1516
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.",
1517
1728
  inputSchema: aggregateRumEventsInputSchema,
1518
1729
  outputSchema: toolOutputBaseSchema.extend({
1519
1730
  query: z.string().nullable(),
@@ -1532,16 +1743,19 @@ export const aggregateRumEventsTool = defineTool({
1532
1743
  });
1533
1744
  export const webExtractTool = defineTool({
1534
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.",
1535
1747
  inputSchema: webExtractInputSchema,
1536
1748
  outputSchema: webExtractOutputSchema
1537
1749
  });
1538
1750
  export const webResearchTool = defineTool({
1539
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).",
1540
1753
  inputSchema: webResearchInputSchema,
1541
1754
  outputSchema: webResearchOutputSchema
1542
1755
  });
1543
1756
  export const imageEditTool = defineTool({
1544
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.",
1545
1759
  inputSchema: imageEditInputSchema,
1546
1760
  outputSchema: imageEditOutputSchema
1547
1761
  });
@@ -1831,12 +2045,10 @@ export const attioGetRecordRequestSchema = z.object({
1831
2045
  recordId: attioRecordIdField
1832
2046
  });
1833
2047
  export const attioCreateRecordRequestSchema = z.object({
1834
- 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)."),
1835
2048
  objectSlug: attioObjectSlugField,
1836
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.')
1837
2050
  });
1838
2051
  export const attioUpdateRecordRequestSchema = z.object({
1839
- action: z.literal("update").describe("Update an existing record by its ID. Only the attributes present in 'values' are touched."),
1840
2052
  objectSlug: attioObjectSlugField,
1841
2053
  recordId: attioRecordIdField,
1842
2054
  values: z.string().describe("A JSON object string mapping the attribute slugs to update to their new values."),
@@ -1846,9 +2058,6 @@ export const attioUpdateRecordRequestSchema = z.object({
1846
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.")
1847
2059
  });
1848
2060
  export const attioUpsertRecordsRequestSchema = z.object({
1849
- action: z
1850
- .literal("upsert")
1851
- .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)."),
1852
2061
  objectSlug: attioObjectSlugField,
1853
2062
  matchingAttribute: z.string().describe("The unique, writable attribute slug to match on (e.g. 'email_addresses' for people, 'domains' for companies)."),
1854
2063
  records: z
@@ -1856,7 +2065,6 @@ export const attioUpsertRecordsRequestSchema = z.object({
1856
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"}]\'.')
1857
2066
  });
1858
2067
  export const attioDeleteRecordRequestSchema = z.object({
1859
- action: z.literal("delete").describe("Permanently delete a record by its ID. This cannot be undone."),
1860
2068
  objectSlug: attioObjectSlugField,
1861
2069
  recordId: attioRecordIdField
1862
2070
  });
@@ -1868,25 +2076,17 @@ export const attioGetAttributeHistoryRequestSchema = z.object({
1868
2076
  limit: z.number().int().nullable().describe("Maximum number of history entries to return. Pass null for the default."),
1869
2077
  offset: z.number().int().nullable().describe("Number of entries to skip, for pagination. Pass null for 0.")
1870
2078
  });
1871
- export const attioRecordsRequestSchema = z.discriminatedUnion("action", [
2079
+ export const attioReadRecordsRequestSchema = z.discriminatedUnion("action", [
1872
2080
  attioQueryRecordsRequestSchema,
1873
2081
  attioSearchRecordsRequestSchema,
1874
2082
  attioGetRecordRequestSchema,
1875
- attioCreateRecordRequestSchema,
1876
- attioUpdateRecordRequestSchema,
1877
- attioUpsertRecordsRequestSchema,
1878
- attioDeleteRecordRequestSchema,
1879
2083
  attioGetAttributeHistoryRequestSchema
1880
2084
  ]);
1881
- export const attioRecordsInputSchema = z.object({
1882
- integrationId: z.string().describe("The integration ID of the Attio workspace to use."),
1883
- request: attioRecordsRequestSchema.describe("The record operation to perform and its arguments.")
1884
- });
1885
2085
  const attioTargetRecordFields = {
1886
2086
  objectSlug: z.string().describe("The object type slug of the record (e.g. 'people', 'companies')."),
1887
2087
  recordId: z.string().describe("The record ID (UUID).")
1888
2088
  };
1889
- export const attioTasksRequestSchema = z.discriminatedUnion("action", [
2089
+ export const attioReadTasksRequestSchema = z.discriminatedUnion("action", [
1890
2090
  z.object({
1891
2091
  action: z.literal("list").describe("List tasks, optionally filtered by linked record, assignee or completion state."),
1892
2092
  linkedObjectSlug: z.string().nullable().optional().describe("Filter to tasks linked to records of this object slug. Requires linkedRecordId."),
@@ -1895,26 +2095,24 @@ export const attioTasksRequestSchema = z.discriminatedUnion("action", [
1895
2095
  limit: z.number().int().nullable().optional().describe("Maximum tasks to return."),
1896
2096
  offset: z.number().int().nullable().optional().describe("Number of tasks to skip, for pagination.")
1897
2097
  }),
1898
- z.object({ action: z.literal("get").describe("Fetch a single task by ID."), taskId: z.string() }),
1899
- z.object({
1900
- action: z.literal("create").describe("Create a task, optionally linked to records and assigned to workspace members."),
1901
- content: z.string().describe("The task text (plaintext, max 2000 chars)."),
1902
- deadlineAt: z.string().nullable().optional().describe("Deadline as an ISO 8601 timestamp, or null for no deadline."),
1903
- isCompleted: z.boolean().nullable().optional().describe("Whether the task starts completed. Defaults to false."),
1904
- assignees: z.array(z.string()).nullable().optional().describe("Workspace member email addresses or member IDs (UUIDs) to assign."),
1905
- linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Records to link the task to.")
1906
- }),
1907
- z.object({
1908
- action: z.literal("update").describe("Update a task's deadline, completion state, assignees or linked records. Task content cannot be changed."),
1909
- taskId: z.string(),
1910
- deadlineAt: z.string().nullable().optional().describe("New deadline (ISO 8601), or null to clear."),
1911
- isCompleted: z.boolean().nullable().optional().describe("New completion state. Omit to leave unchanged."),
1912
- assignees: z.array(z.string()).nullable().optional().describe("Replacement assignee emails/IDs. Omit to leave unchanged."),
1913
- linkedRecords: z.array(z.object(attioTargetRecordFields)).nullable().optional().describe("Replacement linked records. Omit to leave unchanged.")
1914
- }),
1915
- 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() })
1916
2099
  ]);
1917
- 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", [
1918
2116
  z.object({
1919
2117
  action: z.literal("list").describe("List notes, optionally scoped to one record."),
1920
2118
  parentObjectSlug: z.string().nullable().optional().describe("Filter to notes on records of this object slug. Requires parentRecordId."),
@@ -1922,28 +2120,18 @@ export const attioNotesRequestSchema = z.discriminatedUnion("action", [
1922
2120
  limit: z.number().int().nullable().optional(),
1923
2121
  offset: z.number().int().nullable().optional()
1924
2122
  }),
1925
- z.object({ action: z.literal("get").describe("Fetch a single note by ID."), noteId: z.string() }),
1926
- z.object({
1927
- action: z.literal("create").describe("Create a note on a record."),
1928
- parentObjectSlug: z.string().describe("The object type slug of the record the note belongs to."),
1929
- parentRecordId: z.string().describe("The record ID the note belongs to."),
1930
- title: z.string().describe("The note title."),
1931
- content: z.string().describe("The note body."),
1932
- format: z.enum(["plaintext", "markdown"]).nullable().optional().describe("Content format. Defaults to markdown.")
1933
- }),
1934
- 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() })
1935
2124
  ]);
1936
- export const attioCommentsRequestSchema = z.discriminatedUnion("action", [
1937
- z.object({
1938
- 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)."),
1939
- content: z.string().describe("The comment text (plaintext)."),
1940
- authorWorkspaceMemberId: z.string().describe("The workspace member ID the comment is authored as. Use attio_workspace_members to find it."),
1941
- threadId: z.string().nullable().optional().describe("Reply to this thread. Pass null/omit when commenting on a record."),
1942
- objectSlug: z.string().nullable().optional().describe("With recordId: start a new comment thread on this record."),
1943
- recordId: z.string().nullable().optional()
1944
- }),
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", [
1945
2134
  z.object({ action: z.literal("get").describe("Fetch a single comment by ID."), commentId: z.string() }),
1946
- z.object({ action: z.literal("delete").describe("Permanently delete a comment."), commentId: z.string() }),
1947
2135
  z.object({
1948
2136
  action: z.literal("list_threads").describe("List comment threads on a record."),
1949
2137
  objectSlug: z.string().nullable().optional().describe("With recordId: threads on this record."),
@@ -1953,17 +2141,26 @@ export const attioCommentsRequestSchema = z.discriminatedUnion("action", [
1953
2141
  }),
1954
2142
  z.object({ action: z.literal("get_thread").describe("Fetch a thread with all of its comments."), threadId: z.string() })
1955
2143
  ]);
1956
- 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", [
1957
2153
  z.object({ action: z.literal("list").describe("List all lists in the workspace.") }),
1958
- z.object({ action: z.literal("get").describe("Fetch a list's configuration by ID or slug."), listIdOrSlug: z.string() }),
1959
- z.object({
1960
- action: z.literal("create").describe("Create a new list over an object."),
1961
- name: z.string().describe("Display name of the list."),
1962
- apiSlug: z.string().describe("Unique slug for the list (snake_case)."),
1963
- parentObjectSlug: z.string().describe("The object the list contains records of (e.g. 'companies')."),
1964
- workspaceAccess: z.enum(["full-access", "read-and-write", "read-only"]).nullable().optional().describe("Workspace-wide access level. Defaults to full-access.")
1965
- }),
1966
- 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", [
1967
2164
  z.object({
1968
2165
  action: z.literal("query_entries").describe("List entries in a list, with optional filter, parent-record lookup, and limit/offset pagination."),
1969
2166
  listIdOrSlug: z.string(),
@@ -1973,30 +2170,27 @@ export const attioListsRequestSchema = z.discriminatedUnion("action", [
1973
2170
  limit: z.number().int().nullable().optional().describe("Maximum entries to return (max 500)."),
1974
2171
  offset: z.number().int().nullable().optional()
1975
2172
  }),
1976
- z.object({
1977
- 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."),
1978
- listIdOrSlug: z.string(),
1979
- parentObjectSlug: z.string().describe("Object slug of the record being added."),
1980
- parentRecordId: z.string().describe("Record ID being added."),
1981
- entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values (e.g. a stage).")
1982
- }),
1983
- z.object({
1984
- 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."),
1985
- listIdOrSlug: z.string(),
1986
- parentObjectSlug: z.string(),
1987
- parentRecordId: z.string(),
1988
- entryValues: z.string().nullable().optional().describe("Optional JSON object string of entry attribute values.")
1989
- }),
1990
- z.object({ action: z.literal("get_entry").describe("Fetch a single list entry."), listIdOrSlug: z.string(), entryId: z.string() }),
1991
- z.object({
1992
- action: z.literal("update_entry").describe("Update a list entry's attribute values (e.g. move stage)."),
1993
- listIdOrSlug: z.string(),
1994
- entryId: z.string(),
1995
- entryValues: z.string().describe("JSON object string mapping entry attribute slugs to new values."),
1996
- multiselectMode: z.enum(["overwrite", "append"]).nullable().optional().describe("'overwrite' (default) replaces multi-value attribute values; 'append' adds to them.")
1997
- }),
1998
- 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() })
1999
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() });
2000
2194
  export const attioMeetingsRequestSchema = z.discriminatedUnion("action", [
2001
2195
  z.object({
2002
2196
  action: z.literal("list").describe("List meetings, optionally filtered by linked record, participants or time range. Uses cursor pagination."),
@@ -2022,7 +2216,7 @@ export const attioMeetingsRequestSchema = z.discriminatedUnion("action", [
2022
2216
  cursor: z.string().nullable().optional()
2023
2217
  })
2024
2218
  ]);
2025
- export const attioFilesRequestSchema = z.discriminatedUnion("action", [
2219
+ export const attioReadFilesRequestSchema = z.discriminatedUnion("action", [
2026
2220
  z.object({
2027
2221
  action: z.literal("list").describe("List files attached to a record."),
2028
2222
  objectSlug: z.string().describe("Object slug of the record."),
@@ -2031,24 +2225,28 @@ export const attioFilesRequestSchema = z.discriminatedUnion("action", [
2031
2225
  cursor: z.string().nullable().optional()
2032
2226
  }),
2033
2227
  z.object({ action: z.literal("get").describe("Fetch a file's metadata by ID."), fileId: z.string() }),
2034
- z.object({
2035
- action: z.literal("upload").describe("Upload a file to a record (native Attio storage, max 50 MB)."),
2036
- objectSlug: z.string(),
2037
- recordId: z.string(),
2038
- fileName: z.string().describe("File name including extension."),
2039
- contentBase64: z.string().describe("The file content, base64-encoded."),
2040
- contentType: z.string().nullable().optional().describe("MIME type. Defaults to application/octet-stream.")
2041
- }),
2042
- z.object({ action: z.literal("get_download_url").describe("Get a signed download URL for a file."), fileId: z.string() }),
2043
- 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() })
2044
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() });
2045
2238
  const attioSchemaTargetFields = {
2046
2239
  target: z.enum(["objects", "lists"]).describe("Whether the attribute lives on an object or a list."),
2047
2240
  identifier: z.string().describe("The object slug (e.g. 'deals') or list ID/slug the attribute belongs to.")
2048
2241
  };
2049
- export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2242
+ export const attioReadSchemaRequestSchema = z.discriminatedUnion("action", [
2050
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.") }),
2051
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", [
2052
2250
  z.object({
2053
2251
  action: z.literal("create_object").describe("Create a custom object type. This changes the workspace schema for every user."),
2054
2252
  apiSlug: z.string().describe("Unique slug (snake_case)."),
@@ -2062,7 +2260,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2062
2260
  singularNoun: z.string().nullable().optional(),
2063
2261
  pluralNoun: z.string().nullable().optional()
2064
2262
  }),
2065
- z.object({ action: z.literal("list_attributes").describe("List the attributes defined on an object or list."), ...attioSchemaTargetFields }),
2066
2263
  z.object({
2067
2264
  action: z.literal("create_attribute").describe("Create a new attribute on an object or list. This changes the workspace schema for every user."),
2068
2265
  ...attioSchemaTargetFields,
@@ -2083,7 +2280,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2083
2280
  title: z.string().nullable().optional(),
2084
2281
  isRequired: z.boolean().nullable().optional()
2085
2282
  }),
2086
- z.object({ action: z.literal("list_statuses").describe("List the statuses of a status attribute (e.g. deal stages)."), ...attioSchemaTargetFields, attributeSlug: z.string() }),
2087
2283
  z.object({
2088
2284
  action: z.literal("create_status").describe("Add a new status to a status attribute. Rerun terse generate afterwards to refresh generated constants."),
2089
2285
  ...attioSchemaTargetFields,
@@ -2098,7 +2294,6 @@ export const attioSchemaRequestSchema = z.discriminatedUnion("action", [
2098
2294
  title: z.string().nullable().optional(),
2099
2295
  isArchived: z.boolean().nullable().optional()
2100
2296
  }),
2101
- z.object({ action: z.literal("list_select_options").describe("List the options of a select attribute."), ...attioSchemaTargetFields, attributeSlug: z.string() }),
2102
2297
  z.object({
2103
2298
  action: z.literal("create_select_option").describe("Add an option to a select attribute. Rerun terse generate afterwards to refresh generated constants."),
2104
2299
  ...attioSchemaTargetFields,
@@ -2192,56 +2387,166 @@ const attioToolInput = (request) => z.object({
2192
2387
  integrationId: z.string().describe("The integration ID of the Attio workspace to use."),
2193
2388
  request: request.describe("The operation to perform and its arguments.")
2194
2389
  });
2195
- export const attioTasksInputSchema = attioToolInput(attioTasksRequestSchema);
2196
- export const attioNotesInputSchema = attioToolInput(attioNotesRequestSchema);
2197
- export const attioCommentsInputSchema = attioToolInput(attioCommentsRequestSchema);
2198
- 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);
2199
2413
  export const attioMeetingsInputSchema = attioToolInput(attioMeetingsRequestSchema);
2200
- export const attioFilesInputSchema = attioToolInput(attioFilesRequestSchema);
2201
- 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);
2202
2419
  const attioToolOutputBaseSchema = toolOutputBaseSchema.omit({ success: true });
2203
- export const attioTasksTool = defineTool({
2204
- name: "attio_tasks",
2205
- inputSchema: attioTasksInputSchema,
2206
- outputSchema: attioToolOutputBaseSchema.extend({
2207
- tasks: z.array(attioTaskSchema).optional(),
2208
- task: attioTaskSchema.optional(),
2209
- count: z.number().int().optional()
2210
- })
2211
- });
2212
- export const attioNotesTool = defineTool({
2213
- name: "attio_notes",
2214
- inputSchema: attioNotesInputSchema,
2215
- outputSchema: attioToolOutputBaseSchema.extend({
2216
- notes: z.array(attioNoteSchema).optional(),
2217
- note: attioNoteSchema.optional(),
2218
- count: z.number().int().optional()
2219
- })
2220
- });
2221
- export const attioCommentsTool = defineTool({
2222
- name: "attio_comments",
2223
- inputSchema: attioCommentsInputSchema,
2224
- outputSchema: attioToolOutputBaseSchema.extend({
2225
- comment: attioCommentSchema.optional(),
2226
- threads: z.array(attioThreadSchema).optional(),
2227
- thread: attioThreadSchema.optional(),
2228
- count: z.number().int().optional()
2229
- })
2230
- });
2231
- export const attioListsTool = defineTool({
2232
- name: "attio_lists",
2233
- inputSchema: attioListsInputSchema,
2234
- outputSchema: attioToolOutputBaseSchema.extend({
2235
- lists: z.array(attioListSchema).optional(),
2236
- list: attioListSchema.optional(),
2237
- entries: z.array(attioListEntrySchema).optional(),
2238
- entry: attioListEntrySchema.optional(),
2239
- count: z.number().int().optional(),
2240
- offset: z.number().int().optional()
2241
- })
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
2242
2546
  });
2243
2547
  export const attioMeetingsTool = defineTool({
2244
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.`,
2245
2550
  inputSchema: attioMeetingsInputSchema,
2246
2551
  outputSchema: attioToolOutputBaseSchema.extend({
2247
2552
  meetings: z.array(attioMeetingSchema).optional(),
@@ -2252,34 +2557,57 @@ export const attioMeetingsTool = defineTool({
2252
2557
  nextCursor: z.string().nullable().optional()
2253
2558
  })
2254
2559
  });
2255
- export const attioFilesTool = defineTool({
2256
- name: "attio_files",
2257
- inputSchema: attioFilesInputSchema,
2258
- outputSchema: attioToolOutputBaseSchema.extend({
2259
- files: z.array(attioFileSchema).optional(),
2260
- file: attioFileSchema.optional(),
2261
- downloadUrl: z.string().optional(),
2262
- count: z.number().int().optional(),
2263
- nextCursor: z.string().nullable().optional()
2264
- })
2265
- });
2266
- export const attioSchemaTool = defineTool({
2267
- name: "attio_schema",
2268
- inputSchema: attioSchemaInputSchema,
2269
- outputSchema: attioToolOutputBaseSchema.extend({
2270
- objects: z.array(attioObjectWithAttributesSchema).optional(),
2271
- object: attioObjectSchema.optional(),
2272
- attributes: z.array(attioAttributeSchema).optional(),
2273
- attribute: attioAttributeSchema.optional(),
2274
- statuses: z.array(attioStatusSchema).optional(),
2275
- status: attioStatusSchema.optional(),
2276
- selectOptions: z.array(attioSelectOptionEntitySchema).optional(),
2277
- selectOption: attioSelectOptionEntitySchema.optional(),
2278
- count: z.number().int().optional()
2279
- })
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
2280
2607
  });
2281
2608
  export const attioWorkspaceMembersTool = defineTool({
2282
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.`,
2283
2611
  inputSchema: attioWorkspaceMembersInputSchema,
2284
2612
  outputSchema: attioToolOutputBaseSchema.extend({
2285
2613
  members: z.array(attioWorkspaceMemberSchema).optional(),
@@ -2287,20 +2615,47 @@ export const attioWorkspaceMembersTool = defineTool({
2287
2615
  count: z.number().int().optional()
2288
2616
  })
2289
2617
  });
2290
- export const attioRecordsTool = defineTool({
2291
- name: "attio_records",
2292
- inputSchema: attioRecordsInputSchema,
2293
- outputSchema: attioToolOutputBaseSchema.extend({
2294
- records: z.array(attioRecordSchema).optional(),
2295
- record: attioRecordSchema.optional(),
2296
- matches: z.array(attioSearchMatchSchema).optional(),
2297
- history: z.array(attioAttributeHistoryEntrySchema).optional(),
2298
- count: z.number().int().optional(),
2299
- offset: z.number().int().optional()
2300
- })
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
2301
2655
  });
2302
2656
  export const listWorkOSUsersTool = defineTool({
2303
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.",
2304
2659
  inputSchema: listWorkOSUsersInputSchema,
2305
2660
  outputSchema: toolOutputBaseSchema.extend({
2306
2661
  users: z.array(workOSUserSummarySchema),
@@ -2310,6 +2665,7 @@ export const listWorkOSUsersTool = defineTool({
2310
2665
  });
2311
2666
  export const listWorkOSOrganizationsTool = defineTool({
2312
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.",
2313
2669
  inputSchema: listWorkOSOrganizationsInputSchema,
2314
2670
  outputSchema: toolOutputBaseSchema.extend({
2315
2671
  organizations: z.array(workOSOrganizationSummarySchema),
@@ -2319,6 +2675,7 @@ export const listWorkOSOrganizationsTool = defineTool({
2319
2675
  });
2320
2676
  export const getWorkOSUserTool = defineTool({
2321
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.",
2322
2679
  inputSchema: getWorkOSUserInputSchema,
2323
2680
  outputSchema: toolOutputBaseSchema.extend({
2324
2681
  user: workOSUserSummarySchema,
@@ -2327,6 +2684,7 @@ export const getWorkOSUserTool = defineTool({
2327
2684
  });
2328
2685
  export const listLaunchDarklyFlagsTool = defineTool({
2329
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.",
2330
2688
  inputSchema: listLaunchDarklyFlagsInputSchema,
2331
2689
  outputSchema: toolOutputBaseSchema.extend({
2332
2690
  projectKey: z.string(),
@@ -2338,6 +2696,7 @@ export const listLaunchDarklyFlagsTool = defineTool({
2338
2696
  });
2339
2697
  export const getLaunchDarklyFlagDetailsTool = defineTool({
2340
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.",
2341
2700
  inputSchema: getLaunchDarklyFlagDetailsInputSchema,
2342
2701
  outputSchema: toolOutputBaseSchema.extend({
2343
2702
  projectKey: z.string(),
@@ -2350,6 +2709,7 @@ export const getLaunchDarklyFlagDetailsTool = defineTool({
2350
2709
  });
2351
2710
  export const snowflakeExecuteQueryTool = defineTool({
2352
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.",
2353
2713
  inputSchema: snowflakeExecuteQueryInputSchema,
2354
2714
  outputSchema: toolOutputBaseSchema.extend({
2355
2715
  rows: z.array(snowflakeQueryRowSchema),
@@ -2359,6 +2719,7 @@ export const snowflakeExecuteQueryTool = defineTool({
2359
2719
  });
2360
2720
  export const snowflakeExplainQueryTool = defineTool({
2361
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.",
2362
2723
  inputSchema: snowflakeExplainQueryInputSchema,
2363
2724
  outputSchema: toolOutputBaseSchema.extend({
2364
2725
  explainPlan: z.array(snowflakeQueryRowSchema),
@@ -2368,6 +2729,7 @@ export const snowflakeExplainQueryTool = defineTool({
2368
2729
  });
2369
2730
  export const webSearchTool = defineTool({
2370
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.",
2371
2733
  inputSchema: z.object({
2372
2734
  query: z.string().describe("The search query"),
2373
2735
  max_results: z.number().int().min(1).max(10).nullable().describe("Number of results to return (default 5)"),
@@ -2426,6 +2788,7 @@ export const memoryOutputSchema = toolOutputBaseSchema.extend({
2426
2788
  });
2427
2789
  export const memoryTool = defineTool({
2428
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.",
2429
2792
  inputSchema: memoryInputSchema,
2430
2793
  outputSchema: memoryOutputSchema
2431
2794
  });
@@ -2465,15 +2828,36 @@ export const ToolDefinitions = {
2465
2828
  [getPosthogSessionEventsTool.name]: getPosthogSessionEventsTool,
2466
2829
  [listPosthogEventNamesTool.name]: listPosthogEventNamesTool,
2467
2830
  [searchPosthogEventsTool.name]: searchPosthogEventsTool,
2468
- [attioRecordsTool.name]: attioRecordsTool,
2831
+ [attioReadRecordsTool.name]: attioReadRecordsTool,
2832
+ [attioCreateRecordTool.name]: attioCreateRecordTool,
2833
+ [attioUpdateRecordTool.name]: attioUpdateRecordTool,
2834
+ [attioUpsertRecordsTool.name]: attioUpsertRecordsTool,
2835
+ [attioDeleteRecordTool.name]: attioDeleteRecordTool,
2469
2836
  [attioWorkspaceMembersTool.name]: attioWorkspaceMembersTool,
2470
- [attioTasksTool.name]: attioTasksTool,
2471
- [attioNotesTool.name]: attioNotesTool,
2472
- [attioCommentsTool.name]: attioCommentsTool,
2473
- [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,
2474
2855
  [attioMeetingsTool.name]: attioMeetingsTool,
2475
- [attioFilesTool.name]: attioFilesTool,
2476
- [attioSchemaTool.name]: attioSchemaTool,
2856
+ [attioReadFilesTool.name]: attioReadFilesTool,
2857
+ [attioUploadFileTool.name]: attioUploadFileTool,
2858
+ [attioDeleteFileTool.name]: attioDeleteFileTool,
2859
+ [attioReadSchemaTool.name]: attioReadSchemaTool,
2860
+ [attioModifySchemaTool.name]: attioModifySchemaTool,
2477
2861
  [listWorkOSUsersTool.name]: listWorkOSUsersTool,
2478
2862
  [listWorkOSOrganizationsTool.name]: listWorkOSOrganizationsTool,
2479
2863
  [getWorkOSUserTool.name]: getWorkOSUserTool,