causly-server 0.0.0-stage → 1.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.
Files changed (91) hide show
  1. package/.env.example +120 -0
  2. package/CHANGELOG.md +121 -0
  3. package/LICENSE +21 -0
  4. package/README.md +205 -3
  5. package/bin/causly.js +192 -0
  6. package/index.js +229 -0
  7. package/package.json +59 -6
  8. package/packs/calendar.js +141 -0
  9. package/packs/command.js +22 -0
  10. package/packs/database.js +95 -0
  11. package/packs/directory.js +63 -0
  12. package/packs/discord.js +63 -0
  13. package/packs/docker.js +202 -0
  14. package/packs/files.js +106 -0
  15. package/packs/git.js +211 -0
  16. package/packs/github.js +321 -0
  17. package/packs/gmail.js +98 -0
  18. package/packs/leads.js +46 -0
  19. package/packs/linear.js +104 -0
  20. package/packs/loader.js +247 -0
  21. package/packs/manifest.json +1152 -0
  22. package/packs/meetings.js +141 -0
  23. package/packs/notion.js +185 -0
  24. package/packs/pipeline.js +151 -0
  25. package/packs/project.js +70 -0
  26. package/packs/registry.js +149 -0
  27. package/packs/reminders.js +57 -0
  28. package/packs/research.js +34 -0
  29. package/packs/secrets.js +77 -0
  30. package/packs/sentry.js +97 -0
  31. package/packs/seo.js +70 -0
  32. package/packs/slack.js +95 -0
  33. package/packs/stripe.js +127 -0
  34. package/packs/supabase.js +73 -0
  35. package/packs/telegram.js +70 -0
  36. package/packs/terraform.js +247 -0
  37. package/packs/vercel.js +114 -0
  38. package/packs/workflow.js +84 -0
  39. package/prompts/cofounder.js +66 -0
  40. package/prompts/playbooks.js +75 -0
  41. package/tools/backupOps.js +87 -0
  42. package/tools/boundaryAttest.js +184 -0
  43. package/tools/calendarOps.js +563 -0
  44. package/tools/cliOps.js +233 -0
  45. package/tools/commandOps.js +198 -0
  46. package/tools/dbOps.js +117 -0
  47. package/tools/directoryOps.js +96 -0
  48. package/tools/discordOps.js +133 -0
  49. package/tools/dockerOps.js +259 -0
  50. package/tools/envFile.js +89 -0
  51. package/tools/envLoader.js +85 -0
  52. package/tools/fileOps.js +125 -0
  53. package/tools/gitOps.js +170 -0
  54. package/tools/githubOps.js +357 -0
  55. package/tools/gmailOps.js +221 -0
  56. package/tools/googleAuth.js +51 -0
  57. package/tools/googleLogin.js +230 -0
  58. package/tools/leadOps.js +447 -0
  59. package/tools/linearOps.js +304 -0
  60. package/tools/logger.js +47 -0
  61. package/tools/meetingOps.js +697 -0
  62. package/tools/notionOps.js +215 -0
  63. package/tools/paths.js +36 -0
  64. package/tools/pipelineOps.js +511 -0
  65. package/tools/projectOps.js +192 -0
  66. package/tools/reminderAlerts.js +48 -0
  67. package/tools/reminderOps.js +129 -0
  68. package/tools/scheduler.js +46 -0
  69. package/tools/secretsOps.js +133 -0
  70. package/tools/security.js +488 -0
  71. package/tools/sentryOps.js +130 -0
  72. package/tools/seoOps.js +561 -0
  73. package/tools/services.js +295 -0
  74. package/tools/setupOps.js +245 -0
  75. package/tools/slackOps.js +151 -0
  76. package/tools/statusOps.js +104 -0
  77. package/tools/store.js +111 -0
  78. package/tools/stripeOps.js +299 -0
  79. package/tools/supabaseOps.js +94 -0
  80. package/tools/telegramOps.js +153 -0
  81. package/tools/terminal.js +124 -0
  82. package/tools/terraformOps.js +171 -0
  83. package/tools/toolWrapper.js +60 -0
  84. package/tools/toolsetOps.js +123 -0
  85. package/tools/transcribeOps.js +221 -0
  86. package/tools/updateCheck.js +58 -0
  87. package/tools/vercelOps.js +198 -0
  88. package/tools/verifyBoundaryAttest.js +25 -0
  89. package/tools/webOps.js +474 -0
  90. package/tools/workflowOps.js +371 -0
  91. package/tools/workspace.js +85 -0
package/packs/git.js ADDED
@@ -0,0 +1,211 @@
1
+ import { z } from "zod";
2
+ import * as gitOps from "../tools/gitOps.js";
3
+ import { wrap } from "../tools/toolWrapper.js";
4
+
5
+ export default function register(server) {
6
+ // ---------------- Git tools ----------------
7
+
8
+ server.registerTool(
9
+ "git_init",
10
+ {
11
+ description: "Initialize a new git repository in the given directory.",
12
+ inputSchema: { repo_path: z.string() },
13
+ },
14
+ wrap("git_init", gitOps.gitInit)
15
+ );
16
+
17
+ server.registerTool(
18
+ "git_status",
19
+ {
20
+ description: "Show the working tree status of a git repository.",
21
+ inputSchema: { repo_path: z.string() },
22
+ },
23
+ wrap("git_status", gitOps.gitStatus)
24
+ );
25
+
26
+ server.registerTool(
27
+ "git_add",
28
+ {
29
+ description: "Stage files for commit. Defaults to staging everything ('.').",
30
+ inputSchema: { repo_path: z.string(), files: z.union([z.string(), z.array(z.string())]).optional() },
31
+ },
32
+ wrap("git_add", gitOps.gitAdd)
33
+ );
34
+
35
+ server.registerTool(
36
+ "git_commit",
37
+ {
38
+ description: "Commit staged changes with a message.",
39
+ inputSchema: { repo_path: z.string(), message: z.string() },
40
+ },
41
+ wrap("git_commit", gitOps.gitCommit)
42
+ );
43
+
44
+ server.registerTool(
45
+ "git_push",
46
+ {
47
+ description: "Push commits to a remote.",
48
+ inputSchema: { repo_path: z.string(), remote: z.string().optional(), branch: z.string().optional() },
49
+ },
50
+ wrap("git_push", gitOps.gitPush)
51
+ );
52
+
53
+ server.registerTool(
54
+ "git_pull",
55
+ {
56
+ description: "Pull changes from a remote.",
57
+ inputSchema: { repo_path: z.string(), remote: z.string().optional(), branch: z.string().optional() },
58
+ },
59
+ wrap("git_pull", gitOps.gitPull)
60
+ );
61
+
62
+ server.registerTool(
63
+ "git_log",
64
+ {
65
+ description: "Show recent commit history.",
66
+ inputSchema: { repo_path: z.string(), max_count: z.number().optional() },
67
+ },
68
+ wrap("git_log", gitOps.gitLog)
69
+ );
70
+
71
+ server.registerTool(
72
+ "git_diff",
73
+ {
74
+ description: "Show uncommitted changes, optionally scoped to one file.",
75
+ inputSchema: { repo_path: z.string(), file: z.string().optional() },
76
+ },
77
+ wrap("git_diff", gitOps.gitDiff)
78
+ );
79
+
80
+ server.registerTool(
81
+ "git_branch",
82
+ {
83
+ description: "List local branches and show the current branch.",
84
+ inputSchema: { repo_path: z.string() },
85
+ },
86
+ wrap("git_branch", gitOps.gitBranch)
87
+ );
88
+
89
+ server.registerTool(
90
+ "git_create_branch",
91
+ {
92
+ description: "Create a new local branch, optionally checking it out immediately (default: yes).",
93
+ inputSchema: {
94
+ repo_path: z.string(),
95
+ branch_name: z.string(),
96
+ checkout: z.boolean().optional().describe("Defaults to true"),
97
+ },
98
+ },
99
+ wrap("git_create_branch", gitOps.gitCreateBranch)
100
+ );
101
+
102
+ server.registerTool(
103
+ "git_checkout",
104
+ {
105
+ description: "Checkout an existing local branch.",
106
+ inputSchema: { repo_path: z.string(), branch: z.string() },
107
+ },
108
+ wrap("git_checkout", gitOps.gitCheckout)
109
+ );
110
+
111
+ server.registerTool(
112
+ "git_merge",
113
+ {
114
+ description: "Merge the given branch into the current branch.",
115
+ inputSchema: { repo_path: z.string(), branch: z.string() },
116
+ },
117
+ wrap("git_merge", gitOps.gitMerge)
118
+ );
119
+
120
+ server.registerTool(
121
+ "git_reset",
122
+ {
123
+ description: "Reset the current branch to a ref. mode: 'soft' | 'mixed' | 'hard' (defaults to mixed). HIGH risk (can lose uncommitted work with --hard) — requires confirm: true.",
124
+ inputSchema: {
125
+ repo_path: z.string(),
126
+ mode: z.string().optional().describe("soft, mixed, or hard"),
127
+ ref: z.string().optional().describe("Defaults to HEAD"),
128
+ confirm: z.boolean().optional().describe("Must be true to proceed"),
129
+ },
130
+ },
131
+ wrap("git_reset", gitOps.gitReset)
132
+ );
133
+
134
+ server.registerTool(
135
+ "git_stash",
136
+ {
137
+ description: "Stash working changes. action: 'save' | 'pop' | 'apply' | 'list' | 'drop' (defaults to save).",
138
+ inputSchema: {
139
+ repo_path: z.string(),
140
+ action: z.string().optional().describe("save, pop, apply, list, or drop"),
141
+ message: z.string().optional().describe("Stash message, only used with save"),
142
+ stash_id: z.string().optional().describe("e.g. stash@{0}, used with pop/apply/drop"),
143
+ },
144
+ },
145
+ wrap("git_stash", gitOps.gitStash)
146
+ );
147
+
148
+ server.registerTool(
149
+ "git_show",
150
+ {
151
+ description: "Show details of a commit or object. Defaults to HEAD.",
152
+ inputSchema: { repo_path: z.string(), ref: z.string().optional() },
153
+ },
154
+ wrap("git_show", gitOps.gitShow)
155
+ );
156
+
157
+ server.registerTool(
158
+ "git_remote",
159
+ {
160
+ description: "Manage git remotes. action: 'list' | 'add' | 'remove' (defaults to list).",
161
+ inputSchema: {
162
+ repo_path: z.string(),
163
+ action: z.string().optional().describe("list, add, or remove"),
164
+ name: z.string().optional().describe("Remote name, required for add/remove"),
165
+ url: z.string().optional().describe("Remote URL, required for add"),
166
+ },
167
+ },
168
+ wrap("git_remote", gitOps.gitRemote)
169
+ );
170
+
171
+ server.registerTool(
172
+ "git_tag",
173
+ {
174
+ description: "Manage git tags. action: 'list' | 'create' | 'delete' (defaults to list).",
175
+ inputSchema: {
176
+ repo_path: z.string(),
177
+ action: z.string().optional().describe("list, create, or delete"),
178
+ tag_name: z.string().optional().describe("Required for create/delete"),
179
+ message: z.string().optional().describe("Annotation message, optional for create"),
180
+ },
181
+ },
182
+ wrap("git_tag", gitOps.gitTag)
183
+ );
184
+
185
+ server.registerTool(
186
+ "git_changed_files",
187
+ {
188
+ description: "List changed files in the working tree with their change type (modified/untracked/created/deleted/renamed).",
189
+ inputSchema: { repo_path: z.string() },
190
+ },
191
+ wrap("git_changed_files", gitOps.gitChangedFiles)
192
+ );
193
+
194
+ server.registerTool(
195
+ "git_diff_stat",
196
+ {
197
+ description: "Show a summary of changes (files changed, insertions, deletions) rather than the full diff.",
198
+ inputSchema: { repo_path: z.string(), file: z.string().optional() },
199
+ },
200
+ wrap("git_diff_stat", gitOps.gitDiffStat)
201
+ );
202
+
203
+ server.registerTool(
204
+ "git_check_clean",
205
+ {
206
+ description: "Check whether the working tree is clean (no uncommitted changes).",
207
+ inputSchema: { repo_path: z.string() },
208
+ },
209
+ wrap("git_check_clean", gitOps.gitCheckClean)
210
+ );
211
+ }
@@ -0,0 +1,321 @@
1
+ import { z } from "zod";
2
+ import * as githubOps from "../tools/githubOps.js";
3
+ import { wrap } from "../tools/toolWrapper.js";
4
+
5
+ export default function register(server) {
6
+ // ---------------- GitHub tools ----------------
7
+
8
+ server.registerTool(
9
+ "github_get_authenticated_user",
10
+ {
11
+ description: "Get the authenticated GitHub user's profile. Useful as a connectivity/auth check.",
12
+ inputSchema: {},
13
+ },
14
+ wrap("github_get_authenticated_user", githubOps.githubGetAuthenticatedUser)
15
+ );
16
+
17
+ server.registerTool(
18
+ "github_create_repo",
19
+ {
20
+ description: "Create a new GitHub repository for the authenticated user.",
21
+ inputSchema: {
22
+ name: z.string(),
23
+ description: z.string().optional(),
24
+ private: z.boolean().optional().describe("Defaults to false (public)"),
25
+ auto_init: z.boolean().optional().describe("Initialize with a README, defaults to true"),
26
+ },
27
+ },
28
+ wrap("github_create_repo", githubOps.githubCreateRepo)
29
+ );
30
+
31
+ server.registerTool(
32
+ "github_delete_repo",
33
+ {
34
+ description: "Delete a GitHub repository. Requires Administration: write on the token. DESTRUCTIVE — requires confirm: true.",
35
+ inputSchema: { owner: z.string(), repo: z.string(), confirm: z.boolean().optional().describe("Must be true to proceed") },
36
+ },
37
+ wrap("github_delete_repo", githubOps.githubDeleteRepo)
38
+ );
39
+
40
+ server.registerTool(
41
+ "github_list_repos",
42
+ {
43
+ description: "List repositories for the authenticated user.",
44
+ inputSchema: {
45
+ per_page: z.number().optional(),
46
+ sort: z.string().optional().describe("created, updated, pushed, or full_name"),
47
+ },
48
+ },
49
+ wrap("github_list_repos", githubOps.githubListRepos)
50
+ );
51
+
52
+ server.registerTool(
53
+ "github_create_issue",
54
+ {
55
+ description: "Create an issue on a GitHub repository.",
56
+ inputSchema: {
57
+ owner: z.string(),
58
+ repo: z.string(),
59
+ title: z.string(),
60
+ body: z.string().optional(),
61
+ labels: z.array(z.string()).optional(),
62
+ },
63
+ },
64
+ wrap("github_create_issue", githubOps.githubCreateIssue)
65
+ );
66
+
67
+ server.registerTool(
68
+ "github_list_issues",
69
+ {
70
+ description: "List issues on a GitHub repository.",
71
+ inputSchema: {
72
+ owner: z.string(),
73
+ repo: z.string(),
74
+ state: z.string().optional().describe("open, closed, or all"),
75
+ per_page: z.number().optional(),
76
+ },
77
+ },
78
+ wrap("github_list_issues", githubOps.githubListIssues)
79
+ );
80
+
81
+ server.registerTool(
82
+ "github_create_pull_request",
83
+ {
84
+ description: "Create a pull request on a GitHub repository.",
85
+ inputSchema: {
86
+ owner: z.string(),
87
+ repo: z.string(),
88
+ title: z.string(),
89
+ head: z.string().describe("Branch containing the changes"),
90
+ base: z.string().optional().describe("Branch to merge into, defaults to main"),
91
+ body: z.string().optional(),
92
+ },
93
+ },
94
+ wrap("github_create_pull_request", githubOps.githubCreatePullRequest)
95
+ );
96
+
97
+ server.registerTool(
98
+ "github_list_pull_requests",
99
+ {
100
+ description: "List pull requests on a GitHub repository.",
101
+ inputSchema: {
102
+ owner: z.string(),
103
+ repo: z.string(),
104
+ state: z.string().optional().describe("open, closed, or all"),
105
+ per_page: z.number().optional(),
106
+ },
107
+ },
108
+ wrap("github_list_pull_requests", githubOps.githubListPullRequests)
109
+ );
110
+
111
+ server.registerTool(
112
+ "github_add_comment",
113
+ {
114
+ description: "Add a comment to a GitHub issue or pull request.",
115
+ inputSchema: {
116
+ owner: z.string(),
117
+ repo: z.string(),
118
+ issue_number: z.number(),
119
+ body: z.string(),
120
+ },
121
+ },
122
+ wrap("github_add_comment", githubOps.githubAddComment)
123
+ );
124
+
125
+ server.registerTool(
126
+ "github_get_repo",
127
+ {
128
+ description: "Get a repository's details (default branch, visibility, open issues, language, etc).",
129
+ inputSchema: { owner: z.string(), repo: z.string() },
130
+ },
131
+ wrap("github_get_repo", githubOps.githubGetRepo)
132
+ );
133
+
134
+ server.registerTool(
135
+ "github_get_issue",
136
+ {
137
+ description: "Get a single issue's details.",
138
+ inputSchema: { owner: z.string(), repo: z.string(), issue_number: z.number() },
139
+ },
140
+ wrap("github_get_issue", githubOps.githubGetIssue)
141
+ );
142
+
143
+ server.registerTool(
144
+ "github_update_issue",
145
+ {
146
+ description: "Update an issue's title, body, state, or labels.",
147
+ inputSchema: {
148
+ owner: z.string(),
149
+ repo: z.string(),
150
+ issue_number: z.number(),
151
+ title: z.string().optional(),
152
+ body: z.string().optional(),
153
+ state: z.string().optional().describe("open or closed"),
154
+ labels: z.array(z.string()).optional(),
155
+ },
156
+ },
157
+ wrap("github_update_issue", githubOps.githubUpdateIssue)
158
+ );
159
+
160
+ server.registerTool(
161
+ "github_get_pull_request",
162
+ {
163
+ description: "Get a single pull request's details, including mergeable status.",
164
+ inputSchema: { owner: z.string(), repo: z.string(), pull_number: z.number() },
165
+ },
166
+ wrap("github_get_pull_request", githubOps.githubGetPullRequest)
167
+ );
168
+
169
+ server.registerTool(
170
+ "github_update_pull_request",
171
+ {
172
+ description: "Update a pull request's title, body, state, or base branch.",
173
+ inputSchema: {
174
+ owner: z.string(),
175
+ repo: z.string(),
176
+ pull_number: z.number(),
177
+ title: z.string().optional(),
178
+ body: z.string().optional(),
179
+ state: z.string().optional().describe("open or closed"),
180
+ base: z.string().optional(),
181
+ },
182
+ },
183
+ wrap("github_update_pull_request", githubOps.githubUpdatePullRequest)
184
+ );
185
+
186
+ server.registerTool(
187
+ "github_merge_pull_request",
188
+ {
189
+ description: "Merge a pull request. HIGH risk — requires confirm: true.",
190
+ inputSchema: {
191
+ owner: z.string(),
192
+ repo: z.string(),
193
+ pull_number: z.number(),
194
+ merge_method: z.string().optional().describe("merge, squash, or rebase — defaults to merge"),
195
+ commit_title: z.string().optional(),
196
+ commit_message: z.string().optional(),
197
+ confirm: z.boolean().optional().describe("Must be true to proceed"),
198
+ },
199
+ },
200
+ wrap("github_merge_pull_request", githubOps.githubMergePullRequest)
201
+ );
202
+
203
+ server.registerTool(
204
+ "github_get_pull_request_files",
205
+ {
206
+ description: "List the files changed in a pull request, with additions/deletions per file.",
207
+ inputSchema: { owner: z.string(), repo: z.string(), pull_number: z.number(), per_page: z.number().optional() },
208
+ },
209
+ wrap("github_get_pull_request_files", githubOps.githubGetPullRequestFiles)
210
+ );
211
+
212
+ server.registerTool(
213
+ "github_get_pull_request_diff",
214
+ {
215
+ description: "Get the full raw diff of a pull request.",
216
+ inputSchema: { owner: z.string(), repo: z.string(), pull_number: z.number() },
217
+ },
218
+ wrap("github_get_pull_request_diff", githubOps.githubGetPullRequestDiff)
219
+ );
220
+
221
+ server.registerTool(
222
+ "github_get_pull_request_comments",
223
+ {
224
+ description: "List conversation comments on a pull request.",
225
+ inputSchema: { owner: z.string(), repo: z.string(), pull_number: z.number(), per_page: z.number().optional() },
226
+ },
227
+ wrap("github_get_pull_request_comments", githubOps.githubGetPullRequestComments)
228
+ );
229
+
230
+ server.registerTool(
231
+ "github_get_pull_request_reviews",
232
+ {
233
+ description: "List reviews (approved/changes-requested/commented) on a pull request.",
234
+ inputSchema: { owner: z.string(), repo: z.string(), pull_number: z.number(), per_page: z.number().optional() },
235
+ },
236
+ wrap("github_get_pull_request_reviews", githubOps.githubGetPullRequestReviews)
237
+ );
238
+
239
+ server.registerTool(
240
+ "github_get_branch",
241
+ {
242
+ description: "Get details of a single branch, including protection status and latest commit SHA.",
243
+ inputSchema: { owner: z.string(), repo: z.string(), branch: z.string() },
244
+ },
245
+ wrap("github_get_branch", githubOps.githubGetBranch)
246
+ );
247
+
248
+ server.registerTool(
249
+ "github_list_branches",
250
+ {
251
+ description: "List branches on a repository.",
252
+ inputSchema: { owner: z.string(), repo: z.string(), per_page: z.number().optional() },
253
+ },
254
+ wrap("github_list_branches", githubOps.githubListBranches)
255
+ );
256
+
257
+ server.registerTool(
258
+ "github_list_workflows",
259
+ {
260
+ description: "List workflows defined in a repository (from .github/workflows).",
261
+ inputSchema: { owner: z.string(), repo: z.string() },
262
+ },
263
+ wrap("github_list_workflows", githubOps.githubListWorkflows)
264
+ );
265
+
266
+ server.registerTool(
267
+ "github_list_workflow_runs",
268
+ {
269
+ description: "List recent GitHub Actions workflow runs, optionally filtered by branch or status (e.g. 'failure', 'in_progress').",
270
+ inputSchema: {
271
+ owner: z.string(),
272
+ repo: z.string(),
273
+ branch: z.string().optional(),
274
+ status: z.string().optional(),
275
+ per_page: z.number().optional(),
276
+ },
277
+ },
278
+ wrap("github_list_workflow_runs", githubOps.githubListWorkflowRuns)
279
+ );
280
+
281
+ server.registerTool(
282
+ "github_get_workflow_run",
283
+ {
284
+ description: "Get details of a single workflow run (status, conclusion, branch, timestamps).",
285
+ inputSchema: { owner: z.string(), repo: z.string(), run_id: z.number() },
286
+ },
287
+ wrap("github_get_workflow_run", githubOps.githubGetWorkflowRun)
288
+ );
289
+
290
+ server.registerTool(
291
+ "github_get_workflow_run_jobs",
292
+ {
293
+ description: "List jobs in a workflow run, with per-job and per-step status/conclusion — use to find which job/step failed.",
294
+ inputSchema: { owner: z.string(), repo: z.string(), run_id: z.number() },
295
+ },
296
+ wrap("github_get_workflow_run_jobs", githubOps.githubGetWorkflowRunJobs)
297
+ );
298
+
299
+ server.registerTool(
300
+ "github_get_job_logs",
301
+ {
302
+ description: "Get the raw log text for a specific job — use after finding a failed job via github_get_workflow_run_jobs.",
303
+ inputSchema: { owner: z.string(), repo: z.string(), job_id: z.number() },
304
+ },
305
+ wrap("github_get_job_logs", githubOps.githubGetJobLogs)
306
+ );
307
+
308
+ server.registerTool(
309
+ "github_rerun_workflow",
310
+ {
311
+ description: "Re-run a workflow run. Set failed_only=true to re-run only the failed jobs instead of the whole run.",
312
+ inputSchema: {
313
+ owner: z.string(),
314
+ repo: z.string(),
315
+ run_id: z.number(),
316
+ failed_only: z.boolean().optional().describe("Defaults to false"),
317
+ },
318
+ },
319
+ wrap("github_rerun_workflow", githubOps.githubRerunWorkflow)
320
+ );
321
+ }
package/packs/gmail.js ADDED
@@ -0,0 +1,98 @@
1
+ import { z } from "zod";
2
+ import * as gmailOps from "../tools/gmailOps.js";
3
+ import { wrap } from "../tools/toolWrapper.js";
4
+
5
+ export default function register(server) {
6
+ // ---------------- Gmail tools ----------------
7
+
8
+ server.registerTool(
9
+ "gmail_get_profile",
10
+ {
11
+ description: "Get the authenticated Gmail account's profile — connectivity/auth check.",
12
+ inputSchema: {},
13
+ },
14
+ wrap("gmail_get_profile", gmailOps.gmailGetProfile)
15
+ );
16
+
17
+ server.registerTool(
18
+ "gmail_search",
19
+ {
20
+ description: "Search messages using Gmail search syntax (e.g. 'from:x@y.com is:unread').",
21
+ inputSchema: { query: z.string(), max_results: z.number().optional().describe("Defaults to 10") },
22
+ },
23
+ wrap("gmail_search", gmailOps.gmailSearch)
24
+ );
25
+
26
+ server.registerTool(
27
+ "gmail_list_messages",
28
+ {
29
+ description: "List recent messages, optionally scoped to a label.",
30
+ inputSchema: {
31
+ label_ids: z.string().optional().describe("e.g. INBOX, UNREAD"),
32
+ max_results: z.number().optional().describe("Defaults to 10"),
33
+ },
34
+ },
35
+ wrap("gmail_list_messages", gmailOps.gmailListMessages)
36
+ );
37
+
38
+ server.registerTool(
39
+ "gmail_get_message",
40
+ {
41
+ description: "Get a single message's decoded content by message ID.",
42
+ inputSchema: { message_id: z.string() },
43
+ },
44
+ wrap("gmail_get_message", gmailOps.gmailGetMessage)
45
+ );
46
+
47
+ server.registerTool(
48
+ "gmail_get_thread",
49
+ {
50
+ description: "Get a full thread (all messages in it) by thread ID.",
51
+ inputSchema: { thread_id: z.string() },
52
+ },
53
+ wrap("gmail_get_thread", gmailOps.gmailGetThread)
54
+ );
55
+
56
+ server.registerTool(
57
+ "gmail_send",
58
+ {
59
+ description: "Send a new email. HIGH risk — requires confirm: true.",
60
+ inputSchema: {
61
+ to: z.string(),
62
+ subject: z.string(),
63
+ body: z.string(),
64
+ cc: z.string().optional(),
65
+ bcc: z.string().optional(),
66
+ confirm: z.boolean().optional().describe("Must be true to proceed"),
67
+ },
68
+ },
69
+ wrap("gmail_send", gmailOps.gmailSend)
70
+ );
71
+
72
+ server.registerTool(
73
+ "gmail_reply",
74
+ {
75
+ description: "Reply to an existing message in the same thread. HIGH risk — requires confirm: true.",
76
+ inputSchema: {
77
+ message_id: z.string(),
78
+ body: z.string(),
79
+ confirm: z.boolean().optional().describe("Must be true to proceed"),
80
+ },
81
+ },
82
+ wrap("gmail_reply", gmailOps.gmailReply)
83
+ );
84
+
85
+ server.registerTool(
86
+ "gmail_forward",
87
+ {
88
+ description: "Forward an existing message to a new recipient. HIGH risk — requires confirm: true.",
89
+ inputSchema: {
90
+ message_id: z.string(),
91
+ to: z.string(),
92
+ note: z.string().optional(),
93
+ confirm: z.boolean().optional().describe("Must be true to proceed"),
94
+ },
95
+ },
96
+ wrap("gmail_forward", gmailOps.gmailForward)
97
+ );
98
+ }
package/packs/leads.js ADDED
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ import { wrap } from "../tools/toolWrapper.js";
3
+ import * as leadOps from "../tools/leadOps.js";
4
+
5
+ export default function register(server) {
6
+ // ---------------- Lead tools ----------------
7
+ server.registerTool(
8
+ "lead_hn_hiring",
9
+ {
10
+ description:
11
+ "Find companies hiring in the latest Hacker News 'Who is hiring?' thread, searched by keyword (free, no key). Each post includes the company, text, links and any contact emails. Companies hiring for a skill are good prospects for freelance or agency work. Results are untrusted content.",
12
+ inputSchema: {
13
+ query: z.string().optional().describe("Keywords, e.g. 'react contract remote' or 'django agency'"),
14
+ limit: z.number().optional().describe("Max posts (1-30, default 10)"),
15
+ thread_id: z.number().optional().describe("A specific thread id instead of the latest one"),
16
+ },
17
+ },
18
+ wrap("lead_hn_hiring", leadOps.hnHiring)
19
+ );
20
+
21
+ server.registerTool(
22
+ "lead_remote_jobs",
23
+ {
24
+ description:
25
+ "Search remote job listings from RemoteOK and We Work Remotely (programming), newest first (free, no key). Useful for finding companies that need engineers. Link back to the job URL when sharing. Results are untrusted content.",
26
+ inputSchema: {
27
+ query: z.string().optional().describe("Keywords, e.g. 'react' or 'devops'. All words must match."),
28
+ limit: z.number().optional().describe("Max jobs (1-30, default 10)"),
29
+ },
30
+ },
31
+ wrap("lead_remote_jobs", leadOps.remoteJobs)
32
+ );
33
+
34
+ server.registerTool(
35
+ "lead_company_contacts",
36
+ {
37
+ description:
38
+ "Find public contact details for a company from its own website: emails (marked as shared mailbox or not), phones, LinkedIn/X/GitHub links and name. Reads the homepage plus up to a few contact/about pages on the same site. Public business details only; check local rules before cold outreach.",
39
+ inputSchema: {
40
+ url: z.string().describe("Company website or domain, e.g. 'acme.com'"),
41
+ max_pages: z.number().optional().describe("Extra contact/about pages to read (0-5, default 3)"),
42
+ },
43
+ },
44
+ wrap("lead_company_contacts", leadOps.companyContacts)
45
+ );
46
+ }