@hasna/microservices 0.0.2 → 0.0.4

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 (89) hide show
  1. package/bin/index.js +70 -0
  2. package/bin/mcp.js +71 -1
  3. package/dist/index.js +70 -0
  4. package/microservices/microservice-ads/package.json +27 -0
  5. package/microservices/microservice-ads/src/cli/index.ts +407 -0
  6. package/microservices/microservice-ads/src/db/campaigns.ts +493 -0
  7. package/microservices/microservice-ads/src/db/database.ts +93 -0
  8. package/microservices/microservice-ads/src/db/migrations.ts +60 -0
  9. package/microservices/microservice-ads/src/index.ts +39 -0
  10. package/microservices/microservice-ads/src/mcp/index.ts +320 -0
  11. package/microservices/microservice-contracts/package.json +27 -0
  12. package/microservices/microservice-contracts/src/cli/index.ts +383 -0
  13. package/microservices/microservice-contracts/src/db/contracts.ts +496 -0
  14. package/microservices/microservice-contracts/src/db/database.ts +93 -0
  15. package/microservices/microservice-contracts/src/db/migrations.ts +58 -0
  16. package/microservices/microservice-contracts/src/index.ts +43 -0
  17. package/microservices/microservice-contracts/src/mcp/index.ts +308 -0
  18. package/microservices/microservice-domains/package.json +27 -0
  19. package/microservices/microservice-domains/src/cli/index.ts +438 -0
  20. package/microservices/microservice-domains/src/db/database.ts +93 -0
  21. package/microservices/microservice-domains/src/db/domains.ts +551 -0
  22. package/microservices/microservice-domains/src/db/migrations.ts +60 -0
  23. package/microservices/microservice-domains/src/index.ts +44 -0
  24. package/microservices/microservice-domains/src/mcp/index.ts +368 -0
  25. package/microservices/microservice-hiring/package.json +27 -0
  26. package/microservices/microservice-hiring/src/cli/index.ts +431 -0
  27. package/microservices/microservice-hiring/src/db/database.ts +93 -0
  28. package/microservices/microservice-hiring/src/db/hiring.ts +582 -0
  29. package/microservices/microservice-hiring/src/db/migrations.ts +68 -0
  30. package/microservices/microservice-hiring/src/index.ts +51 -0
  31. package/microservices/microservice-hiring/src/mcp/index.ts +464 -0
  32. package/microservices/microservice-payments/package.json +27 -0
  33. package/microservices/microservice-payments/src/cli/index.ts +357 -0
  34. package/microservices/microservice-payments/src/db/database.ts +93 -0
  35. package/microservices/microservice-payments/src/db/migrations.ts +63 -0
  36. package/microservices/microservice-payments/src/db/payments.ts +652 -0
  37. package/microservices/microservice-payments/src/index.ts +51 -0
  38. package/microservices/microservice-payments/src/mcp/index.ts +460 -0
  39. package/microservices/microservice-payroll/package.json +27 -0
  40. package/microservices/microservice-payroll/src/cli/index.ts +374 -0
  41. package/microservices/microservice-payroll/src/db/database.ts +93 -0
  42. package/microservices/microservice-payroll/src/db/migrations.ts +69 -0
  43. package/microservices/microservice-payroll/src/db/payroll.ts +741 -0
  44. package/microservices/microservice-payroll/src/index.ts +48 -0
  45. package/microservices/microservice-payroll/src/mcp/index.ts +420 -0
  46. package/microservices/microservice-shipping/package.json +27 -0
  47. package/microservices/microservice-shipping/src/cli/index.ts +398 -0
  48. package/microservices/microservice-shipping/src/db/database.ts +93 -0
  49. package/microservices/microservice-shipping/src/db/migrations.ts +61 -0
  50. package/microservices/microservice-shipping/src/db/shipping.ts +643 -0
  51. package/microservices/microservice-shipping/src/index.ts +53 -0
  52. package/microservices/microservice-shipping/src/mcp/index.ts +385 -0
  53. package/microservices/microservice-social/package.json +27 -0
  54. package/microservices/microservice-social/src/cli/index.ts +447 -0
  55. package/microservices/microservice-social/src/db/database.ts +93 -0
  56. package/microservices/microservice-social/src/db/migrations.ts +55 -0
  57. package/microservices/microservice-social/src/db/social.ts +672 -0
  58. package/microservices/microservice-social/src/index.ts +46 -0
  59. package/microservices/microservice-social/src/mcp/index.ts +435 -0
  60. package/microservices/microservice-subscriptions/package.json +27 -0
  61. package/microservices/microservice-subscriptions/src/cli/index.ts +400 -0
  62. package/microservices/microservice-subscriptions/src/db/database.ts +93 -0
  63. package/microservices/microservice-subscriptions/src/db/migrations.ts +57 -0
  64. package/microservices/microservice-subscriptions/src/db/subscriptions.ts +692 -0
  65. package/microservices/microservice-subscriptions/src/index.ts +41 -0
  66. package/microservices/microservice-subscriptions/src/mcp/index.ts +365 -0
  67. package/microservices/microservice-transcriber/package.json +28 -0
  68. package/microservices/microservice-transcriber/src/cli/index.ts +1347 -0
  69. package/microservices/microservice-transcriber/src/db/annotations.ts +37 -0
  70. package/microservices/microservice-transcriber/src/db/database.ts +82 -0
  71. package/microservices/microservice-transcriber/src/db/migrations.ts +72 -0
  72. package/microservices/microservice-transcriber/src/db/transcripts.ts +395 -0
  73. package/microservices/microservice-transcriber/src/index.ts +43 -0
  74. package/microservices/microservice-transcriber/src/lib/config.ts +77 -0
  75. package/microservices/microservice-transcriber/src/lib/diff.ts +91 -0
  76. package/microservices/microservice-transcriber/src/lib/downloader.ts +570 -0
  77. package/microservices/microservice-transcriber/src/lib/feeds.ts +62 -0
  78. package/microservices/microservice-transcriber/src/lib/live.ts +94 -0
  79. package/microservices/microservice-transcriber/src/lib/notion.ts +129 -0
  80. package/microservices/microservice-transcriber/src/lib/providers.ts +713 -0
  81. package/microservices/microservice-transcriber/src/lib/summarizer.ts +147 -0
  82. package/microservices/microservice-transcriber/src/lib/translator.ts +75 -0
  83. package/microservices/microservice-transcriber/src/lib/webhook.ts +37 -0
  84. package/microservices/microservice-transcriber/src/mcp/index.ts +1070 -0
  85. package/microservices/microservice-transcriber/src/server/index.ts +199 -0
  86. package/package.json +1 -1
  87. package/microservices/microservice-invoices/dashboard/dist/assets/index-Bngq7FNM.css +0 -1
  88. package/microservices/microservice-invoices/dashboard/dist/assets/index-aHW4ARZR.js +0 -124
  89. package/microservices/microservice-invoices/dashboard/dist/index.html +0 -13
@@ -0,0 +1,464 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { z } from "zod";
6
+ import {
7
+ createJob,
8
+ getJob,
9
+ listJobs,
10
+ updateJob,
11
+ closeJob,
12
+ deleteJob,
13
+ createApplicant,
14
+ getApplicant,
15
+ listApplicants,
16
+ updateApplicant,
17
+ advanceApplicant,
18
+ rejectApplicant,
19
+ searchApplicants,
20
+ listByStage,
21
+ getPipeline,
22
+ getHiringStats,
23
+ createInterview,
24
+ getInterview,
25
+ listInterviews,
26
+ updateInterview,
27
+ addInterviewFeedback,
28
+ deleteInterview,
29
+ } from "../db/hiring.js";
30
+
31
+ const server = new McpServer({
32
+ name: "microservice-hiring",
33
+ version: "0.0.1",
34
+ });
35
+
36
+ // --- Jobs ---
37
+
38
+ server.registerTool(
39
+ "create_job",
40
+ {
41
+ title: "Create Job",
42
+ description: "Create a new job posting.",
43
+ inputSchema: {
44
+ title: z.string(),
45
+ department: z.string().optional(),
46
+ location: z.string().optional(),
47
+ type: z.enum(["full-time", "part-time", "contract"]).optional(),
48
+ description: z.string().optional(),
49
+ requirements: z.array(z.string()).optional(),
50
+ salary_range: z.string().optional(),
51
+ posted_at: z.string().optional(),
52
+ },
53
+ },
54
+ async (params) => {
55
+ const job = createJob(params);
56
+ return { content: [{ type: "text", text: JSON.stringify(job, null, 2) }] };
57
+ }
58
+ );
59
+
60
+ server.registerTool(
61
+ "get_job",
62
+ {
63
+ title: "Get Job",
64
+ description: "Get a job posting by ID.",
65
+ inputSchema: { id: z.string() },
66
+ },
67
+ async ({ id }) => {
68
+ const job = getJob(id);
69
+ if (!job) {
70
+ return { content: [{ type: "text", text: `Job '${id}' not found.` }], isError: true };
71
+ }
72
+ return { content: [{ type: "text", text: JSON.stringify(job, null, 2) }] };
73
+ }
74
+ );
75
+
76
+ server.registerTool(
77
+ "list_jobs",
78
+ {
79
+ title: "List Jobs",
80
+ description: "List job postings with optional filters.",
81
+ inputSchema: {
82
+ status: z.enum(["open", "closed", "paused"]).optional(),
83
+ department: z.string().optional(),
84
+ type: z.enum(["full-time", "part-time", "contract"]).optional(),
85
+ limit: z.number().optional(),
86
+ },
87
+ },
88
+ async (params) => {
89
+ const jobs = listJobs(params);
90
+ return {
91
+ content: [{ type: "text", text: JSON.stringify({ jobs, count: jobs.length }, null, 2) }],
92
+ };
93
+ }
94
+ );
95
+
96
+ server.registerTool(
97
+ "update_job",
98
+ {
99
+ title: "Update Job",
100
+ description: "Update a job posting.",
101
+ inputSchema: {
102
+ id: z.string(),
103
+ title: z.string().optional(),
104
+ department: z.string().optional(),
105
+ location: z.string().optional(),
106
+ type: z.enum(["full-time", "part-time", "contract"]).optional(),
107
+ status: z.enum(["open", "closed", "paused"]).optional(),
108
+ description: z.string().optional(),
109
+ requirements: z.array(z.string()).optional(),
110
+ salary_range: z.string().optional(),
111
+ },
112
+ },
113
+ async ({ id, ...input }) => {
114
+ const job = updateJob(id, input);
115
+ if (!job) {
116
+ return { content: [{ type: "text", text: `Job '${id}' not found.` }], isError: true };
117
+ }
118
+ return { content: [{ type: "text", text: JSON.stringify(job, null, 2) }] };
119
+ }
120
+ );
121
+
122
+ server.registerTool(
123
+ "close_job",
124
+ {
125
+ title: "Close Job",
126
+ description: "Close a job posting.",
127
+ inputSchema: { id: z.string() },
128
+ },
129
+ async ({ id }) => {
130
+ const job = closeJob(id);
131
+ if (!job) {
132
+ return { content: [{ type: "text", text: `Job '${id}' not found.` }], isError: true };
133
+ }
134
+ return { content: [{ type: "text", text: JSON.stringify(job, null, 2) }] };
135
+ }
136
+ );
137
+
138
+ server.registerTool(
139
+ "delete_job",
140
+ {
141
+ title: "Delete Job",
142
+ description: "Delete a job posting by ID.",
143
+ inputSchema: { id: z.string() },
144
+ },
145
+ async ({ id }) => {
146
+ const deleted = deleteJob(id);
147
+ return { content: [{ type: "text", text: JSON.stringify({ id, deleted }) }] };
148
+ }
149
+ );
150
+
151
+ // --- Applicants ---
152
+
153
+ server.registerTool(
154
+ "add_applicant",
155
+ {
156
+ title: "Add Applicant",
157
+ description: "Add a new applicant to a job.",
158
+ inputSchema: {
159
+ job_id: z.string(),
160
+ name: z.string(),
161
+ email: z.string().optional(),
162
+ phone: z.string().optional(),
163
+ resume_url: z.string().optional(),
164
+ source: z.string().optional(),
165
+ notes: z.string().optional(),
166
+ },
167
+ },
168
+ async (params) => {
169
+ const applicant = createApplicant(params);
170
+ return { content: [{ type: "text", text: JSON.stringify(applicant, null, 2) }] };
171
+ }
172
+ );
173
+
174
+ server.registerTool(
175
+ "get_applicant",
176
+ {
177
+ title: "Get Applicant",
178
+ description: "Get an applicant by ID.",
179
+ inputSchema: { id: z.string() },
180
+ },
181
+ async ({ id }) => {
182
+ const applicant = getApplicant(id);
183
+ if (!applicant) {
184
+ return { content: [{ type: "text", text: `Applicant '${id}' not found.` }], isError: true };
185
+ }
186
+ return { content: [{ type: "text", text: JSON.stringify(applicant, null, 2) }] };
187
+ }
188
+ );
189
+
190
+ server.registerTool(
191
+ "list_applicants",
192
+ {
193
+ title: "List Applicants",
194
+ description: "List applicants with optional filters.",
195
+ inputSchema: {
196
+ job_id: z.string().optional(),
197
+ status: z.enum(["applied", "screening", "interviewing", "offered", "hired", "rejected"]).optional(),
198
+ source: z.string().optional(),
199
+ limit: z.number().optional(),
200
+ },
201
+ },
202
+ async (params) => {
203
+ const applicants = listApplicants(params);
204
+ return {
205
+ content: [
206
+ { type: "text", text: JSON.stringify({ applicants, count: applicants.length }, null, 2) },
207
+ ],
208
+ };
209
+ }
210
+ );
211
+
212
+ server.registerTool(
213
+ "update_applicant",
214
+ {
215
+ title: "Update Applicant",
216
+ description: "Update an applicant.",
217
+ inputSchema: {
218
+ id: z.string(),
219
+ name: z.string().optional(),
220
+ email: z.string().optional(),
221
+ phone: z.string().optional(),
222
+ resume_url: z.string().optional(),
223
+ status: z.enum(["applied", "screening", "interviewing", "offered", "hired", "rejected"]).optional(),
224
+ stage: z.string().optional(),
225
+ rating: z.number().optional(),
226
+ notes: z.string().optional(),
227
+ source: z.string().optional(),
228
+ },
229
+ },
230
+ async ({ id, ...input }) => {
231
+ const applicant = updateApplicant(id, input);
232
+ if (!applicant) {
233
+ return { content: [{ type: "text", text: `Applicant '${id}' not found.` }], isError: true };
234
+ }
235
+ return { content: [{ type: "text", text: JSON.stringify(applicant, null, 2) }] };
236
+ }
237
+ );
238
+
239
+ server.registerTool(
240
+ "advance_applicant",
241
+ {
242
+ title: "Advance Applicant",
243
+ description: "Advance an applicant to a new status in the hiring pipeline.",
244
+ inputSchema: {
245
+ id: z.string(),
246
+ status: z.enum(["screening", "interviewing", "offered", "hired"]),
247
+ },
248
+ },
249
+ async ({ id, status }) => {
250
+ const applicant = advanceApplicant(id, status);
251
+ if (!applicant) {
252
+ return { content: [{ type: "text", text: `Applicant '${id}' not found.` }], isError: true };
253
+ }
254
+ return { content: [{ type: "text", text: JSON.stringify(applicant, null, 2) }] };
255
+ }
256
+ );
257
+
258
+ server.registerTool(
259
+ "reject_applicant",
260
+ {
261
+ title: "Reject Applicant",
262
+ description: "Reject an applicant with an optional reason.",
263
+ inputSchema: {
264
+ id: z.string(),
265
+ reason: z.string().optional(),
266
+ },
267
+ },
268
+ async ({ id, reason }) => {
269
+ const applicant = rejectApplicant(id, reason);
270
+ if (!applicant) {
271
+ return { content: [{ type: "text", text: `Applicant '${id}' not found.` }], isError: true };
272
+ }
273
+ return { content: [{ type: "text", text: JSON.stringify(applicant, null, 2) }] };
274
+ }
275
+ );
276
+
277
+ server.registerTool(
278
+ "search_applicants",
279
+ {
280
+ title: "Search Applicants",
281
+ description: "Search applicants by name, email, notes, or source.",
282
+ inputSchema: { query: z.string() },
283
+ },
284
+ async ({ query }) => {
285
+ const results = searchApplicants(query);
286
+ return {
287
+ content: [
288
+ { type: "text", text: JSON.stringify({ results, count: results.length }, null, 2) },
289
+ ],
290
+ };
291
+ }
292
+ );
293
+
294
+ server.registerTool(
295
+ "list_by_stage",
296
+ {
297
+ title: "List by Stage",
298
+ description: "List applicants by stage.",
299
+ inputSchema: { stage: z.string() },
300
+ },
301
+ async ({ stage }) => {
302
+ const applicants = listByStage(stage);
303
+ return {
304
+ content: [
305
+ { type: "text", text: JSON.stringify({ applicants, count: applicants.length }, null, 2) },
306
+ ],
307
+ };
308
+ }
309
+ );
310
+
311
+ server.registerTool(
312
+ "get_pipeline",
313
+ {
314
+ title: "Get Pipeline",
315
+ description: "Get the hiring pipeline (applicant count by status) for a job.",
316
+ inputSchema: { job_id: z.string() },
317
+ },
318
+ async ({ job_id }) => {
319
+ const pipeline = getPipeline(job_id);
320
+ return { content: [{ type: "text", text: JSON.stringify(pipeline, null, 2) }] };
321
+ }
322
+ );
323
+
324
+ server.registerTool(
325
+ "get_hiring_stats",
326
+ {
327
+ title: "Get Hiring Stats",
328
+ description: "Get overall hiring statistics.",
329
+ inputSchema: {},
330
+ },
331
+ async () => {
332
+ const stats = getHiringStats();
333
+ return { content: [{ type: "text", text: JSON.stringify(stats, null, 2) }] };
334
+ }
335
+ );
336
+
337
+ // --- Interviews ---
338
+
339
+ server.registerTool(
340
+ "schedule_interview",
341
+ {
342
+ title: "Schedule Interview",
343
+ description: "Schedule an interview for an applicant.",
344
+ inputSchema: {
345
+ applicant_id: z.string(),
346
+ interviewer: z.string().optional(),
347
+ scheduled_at: z.string().optional(),
348
+ duration_min: z.number().optional(),
349
+ type: z.enum(["phone", "video", "onsite"]).optional(),
350
+ },
351
+ },
352
+ async (params) => {
353
+ const interview = createInterview(params);
354
+ return { content: [{ type: "text", text: JSON.stringify(interview, null, 2) }] };
355
+ }
356
+ );
357
+
358
+ server.registerTool(
359
+ "get_interview",
360
+ {
361
+ title: "Get Interview",
362
+ description: "Get an interview by ID.",
363
+ inputSchema: { id: z.string() },
364
+ },
365
+ async ({ id }) => {
366
+ const interview = getInterview(id);
367
+ if (!interview) {
368
+ return { content: [{ type: "text", text: `Interview '${id}' not found.` }], isError: true };
369
+ }
370
+ return { content: [{ type: "text", text: JSON.stringify(interview, null, 2) }] };
371
+ }
372
+ );
373
+
374
+ server.registerTool(
375
+ "list_interviews",
376
+ {
377
+ title: "List Interviews",
378
+ description: "List interviews with optional filters.",
379
+ inputSchema: {
380
+ applicant_id: z.string().optional(),
381
+ status: z.enum(["scheduled", "completed", "canceled"]).optional(),
382
+ type: z.enum(["phone", "video", "onsite"]).optional(),
383
+ limit: z.number().optional(),
384
+ },
385
+ },
386
+ async (params) => {
387
+ const interviews = listInterviews(params);
388
+ return {
389
+ content: [
390
+ { type: "text", text: JSON.stringify({ interviews, count: interviews.length }, null, 2) },
391
+ ],
392
+ };
393
+ }
394
+ );
395
+
396
+ server.registerTool(
397
+ "update_interview",
398
+ {
399
+ title: "Update Interview",
400
+ description: "Update an interview.",
401
+ inputSchema: {
402
+ id: z.string(),
403
+ interviewer: z.string().optional(),
404
+ scheduled_at: z.string().optional(),
405
+ duration_min: z.number().optional(),
406
+ type: z.enum(["phone", "video", "onsite"]).optional(),
407
+ status: z.enum(["scheduled", "completed", "canceled"]).optional(),
408
+ feedback: z.string().optional(),
409
+ rating: z.number().optional(),
410
+ },
411
+ },
412
+ async ({ id, ...input }) => {
413
+ const interview = updateInterview(id, input);
414
+ if (!interview) {
415
+ return { content: [{ type: "text", text: `Interview '${id}' not found.` }], isError: true };
416
+ }
417
+ return { content: [{ type: "text", text: JSON.stringify(interview, null, 2) }] };
418
+ }
419
+ );
420
+
421
+ server.registerTool(
422
+ "add_interview_feedback",
423
+ {
424
+ title: "Add Interview Feedback",
425
+ description: "Add feedback and optional rating to an interview.",
426
+ inputSchema: {
427
+ id: z.string(),
428
+ feedback: z.string(),
429
+ rating: z.number().optional(),
430
+ },
431
+ },
432
+ async ({ id, feedback, rating }) => {
433
+ const interview = addInterviewFeedback(id, feedback, rating);
434
+ if (!interview) {
435
+ return { content: [{ type: "text", text: `Interview '${id}' not found.` }], isError: true };
436
+ }
437
+ return { content: [{ type: "text", text: JSON.stringify(interview, null, 2) }] };
438
+ }
439
+ );
440
+
441
+ server.registerTool(
442
+ "delete_interview",
443
+ {
444
+ title: "Delete Interview",
445
+ description: "Delete an interview by ID.",
446
+ inputSchema: { id: z.string() },
447
+ },
448
+ async ({ id }) => {
449
+ const deleted = deleteInterview(id);
450
+ return { content: [{ type: "text", text: JSON.stringify({ id, deleted }) }] };
451
+ }
452
+ );
453
+
454
+ // --- Start ---
455
+ async function main() {
456
+ const transport = new StdioServerTransport();
457
+ await server.connect(transport);
458
+ console.error("microservice-hiring MCP server running on stdio");
459
+ }
460
+
461
+ main().catch((error) => {
462
+ console.error("Fatal error:", error);
463
+ process.exit(1);
464
+ });
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@hasna/microservice-payments",
3
+ "version": "0.0.1",
4
+ "description": "Payment processing and tracking microservice with SQLite — manage payments, disputes, and payouts",
5
+ "type": "module",
6
+ "bin": {
7
+ "microservice-payments": "./src/cli/index.ts",
8
+ "microservice-payments-mcp": "./src/mcp/index.ts"
9
+ },
10
+ "exports": {
11
+ ".": "./src/index.ts"
12
+ },
13
+ "scripts": {
14
+ "dev": "bun run ./src/cli/index.ts",
15
+ "test": "bun test"
16
+ },
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.26.0",
19
+ "commander": "^12.1.0",
20
+ "zod": "^3.24.0"
21
+ },
22
+ "license": "Apache-2.0",
23
+ "publishConfig": {
24
+ "registry": "https://registry.npmjs.org",
25
+ "access": "public"
26
+ }
27
+ }