@jclvsh/iris 0.3.0 → 0.5.0

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.
@@ -1,31 +1,41 @@
1
1
  import { z } from "zod";
2
2
  const CHANNELS = ["email", "instagram", "twitter"];
3
3
  export function registerChannelTools(server, client) {
4
- server.tool("list_connected_accounts", "list all connected social media accounts. requires channels:read scope.", {}, async () => {
4
+ server.tool("list_connected_accounts", "list all connected social media accounts. requires read scope.", {}, async () => {
5
5
  try {
6
6
  const result = await client.get("/channels/accounts");
7
7
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
8
8
  }
9
9
  catch (error) {
10
10
  return {
11
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
11
+ content: [
12
+ {
13
+ type: "text",
14
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
15
+ },
16
+ ],
12
17
  isError: true,
13
18
  };
14
19
  }
15
20
  });
16
- server.tool("check_channel_availability", "check which outreach channels are available and configured. requires channels:read scope.", {}, async () => {
21
+ server.tool("check_channel_availability", "check which outreach channels are available and configured. requires read scope.", {}, async () => {
17
22
  try {
18
23
  const result = await client.get("/channels/availability");
19
24
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
20
25
  }
21
26
  catch (error) {
22
27
  return {
23
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
32
+ },
33
+ ],
24
34
  isError: true,
25
35
  };
26
36
  }
27
37
  });
28
- server.tool("send_channel_message", "send a message through a specific channel in a conversation. requires channels:write scope.", {
38
+ server.tool("send_channel_message", "send a message through a specific channel in a conversation. requires send scope.", {
29
39
  channel: z.enum(CHANNELS).describe("outreach channel to use"),
30
40
  conversation_id: z.string().uuid().describe("conversation ID"),
31
41
  recipient_id: z
@@ -41,7 +51,12 @@ export function registerChannelTools(server, client) {
41
51
  }
42
52
  catch (error) {
43
53
  return {
44
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
58
+ },
59
+ ],
45
60
  isError: true,
46
61
  };
47
62
  }
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  export function registerContactTools(server, client) {
3
- server.tool("list_contacts", "list all contacts with optional search. requires contacts:read scope.", {
3
+ server.tool("list_contacts", "list all contacts with optional search. requires read scope.", {
4
4
  page: z.number().int().positive().optional().describe("page number (default 1)"),
5
5
  page_size: z.number().int().min(1).max(100).optional().describe("items per page (default 50, max 100)"),
6
6
  search: z.string().optional().describe("search by name, email, or company"),
@@ -18,12 +18,17 @@ export function registerContactTools(server, client) {
18
18
  }
19
19
  catch (error) {
20
20
  return {
21
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
21
+ content: [
22
+ {
23
+ type: "text",
24
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
25
+ },
26
+ ],
22
27
  isError: true,
23
28
  };
24
29
  }
25
30
  });
26
- server.tool("create_contact", "create a new contact. requires contacts:write scope.", {
31
+ server.tool("create_contact", "create a new contact. requires write scope.", {
27
32
  email: z.string().email().describe("contact email address"),
28
33
  first_name: z.string().max(100).optional().describe("first name"),
29
34
  last_name: z.string().max(100).optional().describe("last name"),
@@ -39,12 +44,17 @@ export function registerContactTools(server, client) {
39
44
  }
40
45
  catch (error) {
41
46
  return {
42
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
47
+ content: [
48
+ {
49
+ type: "text",
50
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
51
+ },
52
+ ],
43
53
  isError: true,
44
54
  };
45
55
  }
46
56
  });
47
- server.tool("get_contact", "get a contact by ID. requires contacts:read scope.", {
57
+ server.tool("get_contact", "get a contact by ID. requires read scope.", {
48
58
  id: z.string().uuid().describe("contact ID"),
49
59
  }, async ({ id }) => {
50
60
  try {
@@ -53,12 +63,17 @@ export function registerContactTools(server, client) {
53
63
  }
54
64
  catch (error) {
55
65
  return {
56
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
66
+ content: [
67
+ {
68
+ type: "text",
69
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
70
+ },
71
+ ],
57
72
  isError: true,
58
73
  };
59
74
  }
60
75
  });
61
- server.tool("update_contact", "update a contact's details. requires contacts:write scope.", {
76
+ server.tool("update_contact", "update a contact's details. requires write scope.", {
62
77
  id: z.string().uuid().describe("contact ID"),
63
78
  email: z.string().email().optional().describe("email address"),
64
79
  first_name: z.string().max(100).optional().describe("first name"),
@@ -75,12 +90,17 @@ export function registerContactTools(server, client) {
75
90
  }
76
91
  catch (error) {
77
92
  return {
78
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
97
+ },
98
+ ],
79
99
  isError: true,
80
100
  };
81
101
  }
82
102
  });
83
- server.tool("delete_contact", "soft-delete a contact. requires contacts:write scope.", {
103
+ server.tool("delete_contact", "soft-delete a contact. requires write scope.", {
84
104
  id: z.string().uuid().describe("contact ID"),
85
105
  }, async ({ id }) => {
86
106
  try {
@@ -89,12 +109,17 @@ export function registerContactTools(server, client) {
89
109
  }
90
110
  catch (error) {
91
111
  return {
92
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
112
+ content: [
113
+ {
114
+ type: "text",
115
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
116
+ },
117
+ ],
93
118
  isError: true,
94
119
  };
95
120
  }
96
121
  });
97
- server.tool("bulk_import_contacts", "import multiple contacts at once, optionally adding them to a campaign. requires contacts:write scope.", {
122
+ server.tool("bulk_import_contacts", "import multiple contacts at once, optionally adding them to a campaign. requires write scope.", {
98
123
  contacts: z
99
124
  .array(z.object({
100
125
  email: z.string().email().describe("contact email"),
@@ -115,24 +140,34 @@ export function registerContactTools(server, client) {
115
140
  }
116
141
  catch (error) {
117
142
  return {
118
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
143
+ content: [
144
+ {
145
+ type: "text",
146
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
147
+ },
148
+ ],
119
149
  isError: true,
120
150
  };
121
151
  }
122
152
  });
123
- server.tool("get_contact_usage", "get contact usage limits and current counts for the billing period. requires contacts:read scope.", {}, async () => {
153
+ server.tool("get_contact_usage", "get contact usage limits and current counts for the billing period. requires read scope.", {}, async () => {
124
154
  try {
125
155
  const result = await client.get("/contacts/usage");
126
156
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
127
157
  }
128
158
  catch (error) {
129
159
  return {
130
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
160
+ content: [
161
+ {
162
+ type: "text",
163
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
164
+ },
165
+ ],
131
166
  isError: true,
132
167
  };
133
168
  }
134
169
  });
135
- server.tool("list_contact_conversations", "list all conversations for a specific contact. requires contacts:read scope.", {
170
+ server.tool("list_contact_conversations", "list all conversations for a specific contact. requires read scope.", {
136
171
  id: z.string().uuid().describe("contact ID"),
137
172
  }, async ({ id }) => {
138
173
  try {
@@ -141,7 +176,12 @@ export function registerContactTools(server, client) {
141
176
  }
142
177
  catch (error) {
143
178
  return {
144
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
179
+ content: [
180
+ {
181
+ type: "text",
182
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
183
+ },
184
+ ],
145
185
  isError: true,
146
186
  };
147
187
  }
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  const CONVERSATION_STATUSES = ["active", "completed", "failed", "human_review"];
3
3
  export function registerConversationTools(server, client) {
4
- server.tool("list_conversations", "list conversations with optional filtering. requires conversations:read scope.", {
4
+ server.tool("list_conversations", "list conversations with optional filtering. requires read scope.", {
5
5
  page: z.number().int().positive().optional().describe("page number (default 1)"),
6
6
  page_size: z.number().int().min(1).max(100).optional().describe("items per page (default 50, max 100)"),
7
7
  status: z.enum(CONVERSATION_STATUSES).optional().describe("filter by conversation status"),
@@ -22,12 +22,17 @@ export function registerConversationTools(server, client) {
22
22
  }
23
23
  catch (error) {
24
24
  return {
25
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
25
+ content: [
26
+ {
27
+ type: "text",
28
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
29
+ },
30
+ ],
26
31
  isError: true,
27
32
  };
28
33
  }
29
34
  });
30
- server.tool("get_conversation", "get a conversation by ID with contact and campaign details. requires conversations:read scope.", {
35
+ server.tool("get_conversation", "get a conversation by ID with contact and campaign details. requires read scope.", {
31
36
  id: z.string().uuid().describe("conversation ID"),
32
37
  }, async ({ id }) => {
33
38
  try {
@@ -36,12 +41,17 @@ export function registerConversationTools(server, client) {
36
41
  }
37
42
  catch (error) {
38
43
  return {
39
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
44
+ content: [
45
+ {
46
+ type: "text",
47
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
48
+ },
49
+ ],
40
50
  isError: true,
41
51
  };
42
52
  }
43
53
  });
44
- server.tool("get_conversation_messages", "get all messages in a conversation. requires conversations:read scope.", {
54
+ server.tool("get_conversation_messages", "get all messages in a conversation. requires read scope.", {
45
55
  id: z.string().uuid().describe("conversation ID"),
46
56
  }, async ({ id }) => {
47
57
  try {
@@ -50,12 +60,17 @@ export function registerConversationTools(server, client) {
50
60
  }
51
61
  catch (error) {
52
62
  return {
53
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
63
+ content: [
64
+ {
65
+ type: "text",
66
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
67
+ },
68
+ ],
54
69
  isError: true,
55
70
  };
56
71
  }
57
72
  });
58
- server.tool("mark_conversation_read", "mark a conversation as read. requires conversations:write scope.", {
73
+ server.tool("mark_conversation_read", "mark a conversation as read. requires write scope.", {
59
74
  id: z.string().uuid().describe("conversation ID"),
60
75
  }, async ({ id }) => {
61
76
  try {
@@ -64,19 +79,29 @@ export function registerConversationTools(server, client) {
64
79
  }
65
80
  catch (error) {
66
81
  return {
67
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
82
+ content: [
83
+ {
84
+ type: "text",
85
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
86
+ },
87
+ ],
68
88
  isError: true,
69
89
  };
70
90
  }
71
91
  });
72
- server.tool("get_engagement_metrics", "get overall engagement metrics across all conversations. requires conversations:read scope.", {}, async () => {
92
+ server.tool("get_engagement_metrics", "get overall engagement metrics across all conversations. requires read scope.", {}, async () => {
73
93
  try {
74
94
  const result = await client.get("/conversations/engagement");
75
95
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
76
96
  }
77
97
  catch (error) {
78
98
  return {
79
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
103
+ },
104
+ ],
80
105
  isError: true,
81
106
  };
82
107
  }
@@ -12,7 +12,7 @@ const PROFILE_TYPES = [
12
12
  "other",
13
13
  ];
14
14
  export function registerDiscoveryTools(server, client) {
15
- server.tool("search_contacts", "kick off a multi-source contact discovery job (Apify-backed). returns a job_id and contacts when ready (waits up to 90s; if status=queued, poll get_discovery_job). closed source list: google_maps, instagram, twitter, tiktok, reddit. requires discovery:write scope.", {
15
+ server.tool("search_contacts", "kick off a multi-source contact discovery job (Apify-backed). returns a job_id and contacts when ready (waits up to 90s; if status=queued, poll get_discovery_job). closed source list: google_maps, instagram, twitter, tiktok, reddit. requires generate scope.", {
16
16
  keywords: z
17
17
  .array(z.string().min(1))
18
18
  .min(1)
@@ -37,11 +37,7 @@ export function registerDiscoveryTools(server, client) {
37
37
  .enum(PROFILE_TYPES)
38
38
  .optional()
39
39
  .describe("ICP profile type — drives default source mix when sources is omitted"),
40
- campaign_id: z
41
- .string()
42
- .uuid()
43
- .optional()
44
- .describe("campaign to attach discovered contacts to on finalize"),
40
+ campaign_id: z.string().uuid().optional().describe("campaign to attach discovered contacts to on finalize"),
45
41
  enrich_emails: z
46
42
  .boolean()
47
43
  .optional()
@@ -54,12 +50,17 @@ export function registerDiscoveryTools(server, client) {
54
50
  }
55
51
  catch (error) {
56
52
  return {
57
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
57
+ },
58
+ ],
58
59
  isError: true,
59
60
  };
60
61
  }
61
62
  });
62
- server.tool("search_campaign_contacts", "search for contacts matching a campaign's target profiles. requires discovery:write scope.", {
63
+ server.tool("search_campaign_contacts", "search for contacts matching a campaign's target profiles. requires generate scope.", {
63
64
  campaign_id: z.string().uuid().describe("campaign ID"),
64
65
  target_profile_id: z.string().uuid().optional().describe("specific target profile to search for"),
65
66
  }, async (args) => {
@@ -69,12 +70,17 @@ export function registerDiscoveryTools(server, client) {
69
70
  }
70
71
  catch (error) {
71
72
  return {
72
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
73
+ content: [
74
+ {
75
+ type: "text",
76
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
77
+ },
78
+ ],
73
79
  isError: true,
74
80
  };
75
81
  }
76
82
  });
77
- server.tool("get_discovery_job", "get the status, progress, and contacts of a discovery job. status values: pending, running, completed, failed. contacts populated only when status=completed. requires discovery:read scope.", {
83
+ server.tool("get_discovery_job", "get the status, progress, and contacts of a discovery job. status values: pending, running, completed, failed. contacts populated only when status=completed. requires read scope.", {
78
84
  id: z.string().uuid().describe("discovery job ID"),
79
85
  }, async ({ id }) => {
80
86
  try {
@@ -83,19 +89,29 @@ export function registerDiscoveryTools(server, client) {
83
89
  }
84
90
  catch (error) {
85
91
  return {
86
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
92
+ content: [
93
+ {
94
+ type: "text",
95
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
96
+ },
97
+ ],
87
98
  isError: true,
88
99
  };
89
100
  }
90
101
  });
91
- server.tool("list_discovery_sources", "list available discovery data sources and their status. requires discovery:read scope.", {}, async () => {
102
+ server.tool("list_discovery_sources", "list available discovery data sources and their status. requires read scope.", {}, async () => {
92
103
  try {
93
104
  const result = await client.get("/discovery/sources");
94
105
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
95
106
  }
96
107
  catch (error) {
97
108
  return {
98
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
109
+ content: [
110
+ {
111
+ type: "text",
112
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
113
+ },
114
+ ],
99
115
  isError: true,
100
116
  };
101
117
  }
@@ -1,42 +1,21 @@
1
1
  import { z } from "zod";
2
- const SCOPES = [
3
- "campaigns:read",
4
- "campaigns:write",
5
- "contacts:read",
6
- "contacts:write",
7
- "conversations:read",
8
- "conversations:write",
9
- "messages:read",
10
- "messages:write",
11
- "ai:read",
12
- "ai:write",
13
- "discovery:read",
14
- "discovery:write",
15
- "analytics:read",
16
- "billing:read",
17
- "channels:read",
18
- "channels:write",
19
- "notifications:read",
20
- "notifications:write",
21
- "webhooks:read",
22
- "webhooks:write",
23
- "keys:read",
24
- "keys:write",
25
- ];
2
+ const SCOPES = ["read", "write", "delete", "generate", "send", "admin"];
26
3
  export function registerKeyTools(server, client) {
27
- server.tool("get_current_api_key", "get details about the currently authenticated API key. requires keys:read scope.", {}, async () => {
4
+ server.tool("get_current_api_key", "get details about the currently authenticated API key.", {}, async () => {
28
5
  try {
29
6
  const result = await client.get("/keys/me");
30
7
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
31
8
  }
32
9
  catch (error) {
33
10
  return {
34
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
11
+ content: [
12
+ { type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` },
13
+ ],
35
14
  isError: true,
36
15
  };
37
16
  }
38
17
  });
39
- server.tool("list_api_keys", "list all API keys for the account. requires keys:read scope.", {
18
+ server.tool("list_api_keys", "list all API keys for the account. requires admin scope.", {
40
19
  page: z.number().int().positive().optional().describe("page number (default 1)"),
41
20
  page_size: z.number().int().min(1).max(100).optional().describe("items per page (default 50, max 100)"),
42
21
  }, async ({ page, page_size }) => {
@@ -51,17 +30,22 @@ export function registerKeyTools(server, client) {
51
30
  }
52
31
  catch (error) {
53
32
  return {
54
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
37
+ },
38
+ ],
55
39
  isError: true,
56
40
  };
57
41
  }
58
42
  });
59
- server.tool("create_api_key", "create a new API key. requires keys:write scope.", {
43
+ server.tool("create_api_key", "create a new API key. requires admin scope.", {
60
44
  name: z.string().min(1).max(100).describe("key name for identification"),
61
45
  scopes: z
62
46
  .array(z.enum(SCOPES))
63
47
  .optional()
64
- .describe('permission scopes (e.g. ["campaigns:read", "contacts:write"]). defaults to all scopes'),
48
+ .describe("permission scopes (any of: read, write, delete, generate, send, admin). defaults to all scopes"),
65
49
  expires_at: z.string().optional().describe("expiration date in ISO 8601 format"),
66
50
  }, async (args) => {
67
51
  try {
@@ -70,12 +54,17 @@ export function registerKeyTools(server, client) {
70
54
  }
71
55
  catch (error) {
72
56
  return {
73
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
57
+ content: [
58
+ {
59
+ type: "text",
60
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
61
+ },
62
+ ],
74
63
  isError: true,
75
64
  };
76
65
  }
77
66
  });
78
- server.tool("revoke_api_key", "revoke (delete) an API key. requires keys:write scope.", {
67
+ server.tool("revoke_api_key", "revoke (delete) an API key. requires admin scope.", {
79
68
  id: z.string().uuid().describe("API key ID to revoke"),
80
69
  }, async ({ id }) => {
81
70
  try {
@@ -84,7 +73,12 @@ export function registerKeyTools(server, client) {
84
73
  }
85
74
  catch (error) {
86
75
  return {
87
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
80
+ },
81
+ ],
88
82
  isError: true,
89
83
  };
90
84
  }
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  export function registerMessageTools(server, client) {
3
- server.tool("list_pending_messages", "list messages awaiting approval before sending. requires messages:read scope.", {
3
+ server.tool("list_pending_messages", "list messages awaiting approval before sending. requires read scope.", {
4
4
  page: z.number().int().positive().optional().describe("page number (default 1)"),
5
5
  page_size: z.number().int().min(1).max(100).optional().describe("items per page (default 50, max 100)"),
6
6
  campaign_id: z.string().uuid().optional().describe("filter by campaign ID"),
@@ -18,12 +18,17 @@ export function registerMessageTools(server, client) {
18
18
  }
19
19
  catch (error) {
20
20
  return {
21
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
21
+ content: [
22
+ {
23
+ type: "text",
24
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
25
+ },
26
+ ],
22
27
  isError: true,
23
28
  };
24
29
  }
25
30
  });
26
- server.tool("approve_message", "approve a pending message for sending. requires messages:write scope.", {
31
+ server.tool("approve_message", "approve a pending message for sending. requires send scope.", {
27
32
  id: z.string().uuid().describe("message ID"),
28
33
  }, async ({ id }) => {
29
34
  try {
@@ -32,12 +37,17 @@ export function registerMessageTools(server, client) {
32
37
  }
33
38
  catch (error) {
34
39
  return {
35
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
44
+ },
45
+ ],
36
46
  isError: true,
37
47
  };
38
48
  }
39
49
  });
40
- server.tool("reject_message", "reject a pending message with an optional reason. requires messages:write scope.", {
50
+ server.tool("reject_message", "reject a pending message with an optional reason. requires send scope.", {
41
51
  id: z.string().uuid().describe("message ID"),
42
52
  reason: z.string().max(500).optional().describe("reason for rejection"),
43
53
  }, async ({ id, reason }) => {
@@ -47,12 +57,17 @@ export function registerMessageTools(server, client) {
47
57
  }
48
58
  catch (error) {
49
59
  return {
50
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
60
+ content: [
61
+ {
62
+ type: "text",
63
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
64
+ },
65
+ ],
51
66
  isError: true,
52
67
  };
53
68
  }
54
69
  });
55
- server.tool("retry_message", "retry sending a failed message. requires messages:write scope.", {
70
+ server.tool("retry_message", "retry sending a failed message. requires send scope.", {
56
71
  id: z.string().uuid().describe("message ID"),
57
72
  }, async ({ id }) => {
58
73
  try {
@@ -61,12 +76,17 @@ export function registerMessageTools(server, client) {
61
76
  }
62
77
  catch (error) {
63
78
  return {
64
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
83
+ },
84
+ ],
65
85
  isError: true,
66
86
  };
67
87
  }
68
88
  });
69
- server.tool("submit_message_feedback", "submit feedback on an AI-generated message to improve future generations. requires messages:write scope.", {
89
+ server.tool("submit_message_feedback", "submit feedback on an AI-generated message to improve future generations. requires send scope.", {
70
90
  id: z.string().uuid().describe("message ID"),
71
91
  feedback: z.string().min(1).max(2000).describe("feedback text"),
72
92
  }, async ({ id, feedback }) => {
@@ -76,14 +96,19 @@ export function registerMessageTools(server, client) {
76
96
  }
77
97
  catch (error) {
78
98
  return {
79
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
103
+ },
104
+ ],
80
105
  isError: true,
81
106
  };
82
107
  }
83
108
  });
84
- server.tool("bulk_message_action", "approve or reject multiple messages at once. requires messages:write scope.", {
109
+ server.tool("bulk_message_action", "approve or reject multiple messages at once. requires send scope.", {
85
110
  action: z.enum(["approve", "reject"]).describe("action to perform"),
86
- ids: z.array(z.string().uuid()).min(1).max(100).describe("message IDs to act on"),
111
+ message_ids: z.array(z.string().uuid()).min(1).max(100).describe("message IDs to act on"),
87
112
  }, async (args) => {
88
113
  try {
89
114
  const result = await client.post("/messages/bulk", args);
@@ -91,7 +116,12 @@ export function registerMessageTools(server, client) {
91
116
  }
92
117
  catch (error) {
93
118
  return {
94
- content: [{ type: "text", text: `error: ${error instanceof Error ? error.message : String(error)}` }],
119
+ content: [
120
+ {
121
+ type: "text",
122
+ text: `error: ${error instanceof Error ? error.message : String(error)}`,
123
+ },
124
+ ],
95
125
  isError: true,
96
126
  };
97
127
  }