@hasna/microservices 0.0.10 → 0.0.11

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 (90) hide show
  1. package/bin/index.js +86 -1
  2. package/bin/mcp.js +86 -1
  3. package/dist/index.js +86 -1
  4. package/microservices/microservice-analytics/package.json +27 -0
  5. package/microservices/microservice-analytics/src/cli/index.ts +373 -0
  6. package/microservices/microservice-analytics/src/db/analytics.ts +564 -0
  7. package/microservices/microservice-analytics/src/db/database.ts +93 -0
  8. package/microservices/microservice-analytics/src/db/migrations.ts +50 -0
  9. package/microservices/microservice-analytics/src/index.ts +37 -0
  10. package/microservices/microservice-analytics/src/mcp/index.ts +334 -0
  11. package/microservices/microservice-assets/package.json +27 -0
  12. package/microservices/microservice-assets/src/cli/index.ts +375 -0
  13. package/microservices/microservice-assets/src/db/assets.ts +370 -0
  14. package/microservices/microservice-assets/src/db/database.ts +93 -0
  15. package/microservices/microservice-assets/src/db/migrations.ts +51 -0
  16. package/microservices/microservice-assets/src/index.ts +32 -0
  17. package/microservices/microservice-assets/src/mcp/index.ts +346 -0
  18. package/microservices/microservice-compliance/package.json +27 -0
  19. package/microservices/microservice-compliance/src/cli/index.ts +467 -0
  20. package/microservices/microservice-compliance/src/db/compliance.ts +633 -0
  21. package/microservices/microservice-compliance/src/db/database.ts +93 -0
  22. package/microservices/microservice-compliance/src/db/migrations.ts +63 -0
  23. package/microservices/microservice-compliance/src/index.ts +46 -0
  24. package/microservices/microservice-compliance/src/mcp/index.ts +438 -0
  25. package/microservices/microservice-habits/package.json +27 -0
  26. package/microservices/microservice-habits/src/cli/index.ts +315 -0
  27. package/microservices/microservice-habits/src/db/database.ts +93 -0
  28. package/microservices/microservice-habits/src/db/habits.ts +451 -0
  29. package/microservices/microservice-habits/src/db/migrations.ts +46 -0
  30. package/microservices/microservice-habits/src/index.ts +31 -0
  31. package/microservices/microservice-habits/src/mcp/index.ts +313 -0
  32. package/microservices/microservice-health/package.json +27 -0
  33. package/microservices/microservice-health/src/cli/index.ts +484 -0
  34. package/microservices/microservice-health/src/db/database.ts +93 -0
  35. package/microservices/microservice-health/src/db/health.ts +708 -0
  36. package/microservices/microservice-health/src/db/migrations.ts +70 -0
  37. package/microservices/microservice-health/src/index.ts +63 -0
  38. package/microservices/microservice-health/src/mcp/index.ts +437 -0
  39. package/microservices/microservice-notifications/package.json +27 -0
  40. package/microservices/microservice-notifications/src/cli/index.ts +349 -0
  41. package/microservices/microservice-notifications/src/db/database.ts +93 -0
  42. package/microservices/microservice-notifications/src/db/migrations.ts +62 -0
  43. package/microservices/microservice-notifications/src/db/notifications.ts +509 -0
  44. package/microservices/microservice-notifications/src/index.ts +41 -0
  45. package/microservices/microservice-notifications/src/mcp/index.ts +422 -0
  46. package/microservices/microservice-products/package.json +27 -0
  47. package/microservices/microservice-products/src/cli/index.ts +416 -0
  48. package/microservices/microservice-products/src/db/categories.ts +154 -0
  49. package/microservices/microservice-products/src/db/database.ts +93 -0
  50. package/microservices/microservice-products/src/db/migrations.ts +58 -0
  51. package/microservices/microservice-products/src/db/pricing-tiers.ts +66 -0
  52. package/microservices/microservice-products/src/db/products.ts +452 -0
  53. package/microservices/microservice-products/src/index.ts +53 -0
  54. package/microservices/microservice-products/src/mcp/index.ts +453 -0
  55. package/microservices/microservice-projects/package.json +27 -0
  56. package/microservices/microservice-projects/src/cli/index.ts +480 -0
  57. package/microservices/microservice-projects/src/db/database.ts +93 -0
  58. package/microservices/microservice-projects/src/db/migrations.ts +65 -0
  59. package/microservices/microservice-projects/src/db/projects.ts +715 -0
  60. package/microservices/microservice-projects/src/index.ts +57 -0
  61. package/microservices/microservice-projects/src/mcp/index.ts +501 -0
  62. package/microservices/microservice-proposals/package.json +27 -0
  63. package/microservices/microservice-proposals/src/cli/index.ts +400 -0
  64. package/microservices/microservice-proposals/src/db/database.ts +93 -0
  65. package/microservices/microservice-proposals/src/db/migrations.ts +52 -0
  66. package/microservices/microservice-proposals/src/db/proposals.ts +532 -0
  67. package/microservices/microservice-proposals/src/index.ts +37 -0
  68. package/microservices/microservice-proposals/src/mcp/index.ts +375 -0
  69. package/microservices/microservice-reading/package.json +27 -0
  70. package/microservices/microservice-reading/src/cli/index.ts +464 -0
  71. package/microservices/microservice-reading/src/db/database.ts +93 -0
  72. package/microservices/microservice-reading/src/db/migrations.ts +59 -0
  73. package/microservices/microservice-reading/src/db/reading.ts +524 -0
  74. package/microservices/microservice-reading/src/index.ts +51 -0
  75. package/microservices/microservice-reading/src/mcp/index.ts +368 -0
  76. package/microservices/microservice-travel/package.json +27 -0
  77. package/microservices/microservice-travel/src/cli/index.ts +505 -0
  78. package/microservices/microservice-travel/src/db/database.ts +93 -0
  79. package/microservices/microservice-travel/src/db/migrations.ts +77 -0
  80. package/microservices/microservice-travel/src/db/travel.ts +802 -0
  81. package/microservices/microservice-travel/src/index.ts +60 -0
  82. package/microservices/microservice-travel/src/mcp/index.ts +495 -0
  83. package/microservices/microservice-wiki/package.json +27 -0
  84. package/microservices/microservice-wiki/src/cli/index.ts +345 -0
  85. package/microservices/microservice-wiki/src/db/database.ts +93 -0
  86. package/microservices/microservice-wiki/src/db/migrations.ts +55 -0
  87. package/microservices/microservice-wiki/src/db/wiki.ts +395 -0
  88. package/microservices/microservice-wiki/src/index.ts +32 -0
  89. package/microservices/microservice-wiki/src/mcp/index.ts +344 -0
  90. package/package.json +1 -1
@@ -0,0 +1,375 @@
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
+ createProposal,
8
+ getProposal,
9
+ listProposals,
10
+ updateProposal,
11
+ deleteProposal,
12
+ sendProposal,
13
+ markViewed,
14
+ acceptProposal,
15
+ declineProposal,
16
+ convertToInvoice,
17
+ listExpiring,
18
+ getProposalStats,
19
+ searchProposals,
20
+ countProposals,
21
+ createTemplate,
22
+ listTemplates,
23
+ deleteTemplate,
24
+ useTemplate,
25
+ } from "../db/proposals.js";
26
+
27
+ const itemSchema = z.object({
28
+ description: z.string(),
29
+ quantity: z.number(),
30
+ unit_price: z.number(),
31
+ amount: z.number(),
32
+ });
33
+
34
+ const server = new McpServer({
35
+ name: "microservice-proposals",
36
+ version: "0.0.1",
37
+ });
38
+
39
+ // --- Proposals ---
40
+
41
+ server.registerTool(
42
+ "create_proposal",
43
+ {
44
+ title: "Create Proposal",
45
+ description: "Create a new proposal.",
46
+ inputSchema: {
47
+ title: z.string(),
48
+ client_name: z.string(),
49
+ client_email: z.string().optional(),
50
+ items: z.array(itemSchema).optional(),
51
+ tax_rate: z.number().optional(),
52
+ discount: z.number().optional(),
53
+ currency: z.string().optional(),
54
+ valid_until: z.string().optional(),
55
+ notes: z.string().optional(),
56
+ terms: z.string().optional(),
57
+ },
58
+ },
59
+ async (params) => {
60
+ const proposal = createProposal(params);
61
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
62
+ }
63
+ );
64
+
65
+ server.registerTool(
66
+ "get_proposal",
67
+ {
68
+ title: "Get Proposal",
69
+ description: "Get a proposal by ID.",
70
+ inputSchema: { id: z.string() },
71
+ },
72
+ async ({ id }) => {
73
+ const proposal = getProposal(id);
74
+ if (!proposal) {
75
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
76
+ }
77
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
78
+ }
79
+ );
80
+
81
+ server.registerTool(
82
+ "list_proposals",
83
+ {
84
+ title: "List Proposals",
85
+ description: "List proposals with optional filters.",
86
+ inputSchema: {
87
+ status: z.enum(["draft", "sent", "viewed", "accepted", "declined", "expired"]).optional(),
88
+ client_name: z.string().optional(),
89
+ search: z.string().optional(),
90
+ limit: z.number().optional(),
91
+ },
92
+ },
93
+ async (params) => {
94
+ const proposals = listProposals(params);
95
+ return {
96
+ content: [
97
+ {
98
+ type: "text",
99
+ text: JSON.stringify({ proposals, count: proposals.length }, null, 2),
100
+ },
101
+ ],
102
+ };
103
+ }
104
+ );
105
+
106
+ server.registerTool(
107
+ "update_proposal",
108
+ {
109
+ title: "Update Proposal",
110
+ description: "Update an existing proposal.",
111
+ inputSchema: {
112
+ id: z.string(),
113
+ title: z.string().optional(),
114
+ client_name: z.string().optional(),
115
+ client_email: z.string().optional(),
116
+ items: z.array(itemSchema).optional(),
117
+ tax_rate: z.number().optional(),
118
+ discount: z.number().optional(),
119
+ currency: z.string().optional(),
120
+ valid_until: z.string().optional(),
121
+ notes: z.string().optional(),
122
+ terms: z.string().optional(),
123
+ },
124
+ },
125
+ async ({ id, ...input }) => {
126
+ const proposal = updateProposal(id, input);
127
+ if (!proposal) {
128
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
129
+ }
130
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
131
+ }
132
+ );
133
+
134
+ server.registerTool(
135
+ "delete_proposal",
136
+ {
137
+ title: "Delete Proposal",
138
+ description: "Delete a proposal by ID.",
139
+ inputSchema: { id: z.string() },
140
+ },
141
+ async ({ id }) => {
142
+ const deleted = deleteProposal(id);
143
+ return { content: [{ type: "text", text: JSON.stringify({ id, deleted }) }] };
144
+ }
145
+ );
146
+
147
+ server.registerTool(
148
+ "send_proposal",
149
+ {
150
+ title: "Send Proposal",
151
+ description: "Send a proposal — sets status to 'sent' and records sent_at timestamp.",
152
+ inputSchema: { id: z.string() },
153
+ },
154
+ async ({ id }) => {
155
+ const proposal = sendProposal(id);
156
+ if (!proposal) {
157
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
158
+ }
159
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
160
+ }
161
+ );
162
+
163
+ server.registerTool(
164
+ "mark_proposal_viewed",
165
+ {
166
+ title: "Mark Proposal Viewed",
167
+ description: "Mark a proposal as viewed — sets status to 'viewed' and records viewed_at timestamp.",
168
+ inputSchema: { id: z.string() },
169
+ },
170
+ async ({ id }) => {
171
+ const proposal = markViewed(id);
172
+ if (!proposal) {
173
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
174
+ }
175
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
176
+ }
177
+ );
178
+
179
+ server.registerTool(
180
+ "accept_proposal",
181
+ {
182
+ title: "Accept Proposal",
183
+ description: "Accept a proposal — sets status to 'accepted' and records responded_at timestamp.",
184
+ inputSchema: { id: z.string() },
185
+ },
186
+ async ({ id }) => {
187
+ const proposal = acceptProposal(id);
188
+ if (!proposal) {
189
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
190
+ }
191
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
192
+ }
193
+ );
194
+
195
+ server.registerTool(
196
+ "decline_proposal",
197
+ {
198
+ title: "Decline Proposal",
199
+ description: "Decline a proposal with an optional reason.",
200
+ inputSchema: {
201
+ id: z.string(),
202
+ reason: z.string().optional(),
203
+ },
204
+ },
205
+ async ({ id, reason }) => {
206
+ const proposal = declineProposal(id, reason);
207
+ if (!proposal) {
208
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
209
+ }
210
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
211
+ }
212
+ );
213
+
214
+ server.registerTool(
215
+ "convert_proposal_to_invoice",
216
+ {
217
+ title: "Convert Proposal to Invoice",
218
+ description: "Convert a proposal into invoice-ready data.",
219
+ inputSchema: { id: z.string() },
220
+ },
221
+ async ({ id }) => {
222
+ const invoiceData = convertToInvoice(id);
223
+ if (!invoiceData) {
224
+ return { content: [{ type: "text", text: `Proposal '${id}' not found.` }], isError: true };
225
+ }
226
+ return { content: [{ type: "text", text: JSON.stringify(invoiceData, null, 2) }] };
227
+ }
228
+ );
229
+
230
+ server.registerTool(
231
+ "list_expiring_proposals",
232
+ {
233
+ title: "List Expiring Proposals",
234
+ description: "List proposals expiring within a given number of days.",
235
+ inputSchema: { days: z.number().default(30) },
236
+ },
237
+ async ({ days }) => {
238
+ const proposals = listExpiring(days);
239
+ return {
240
+ content: [
241
+ {
242
+ type: "text",
243
+ text: JSON.stringify({ proposals, count: proposals.length }, null, 2),
244
+ },
245
+ ],
246
+ };
247
+ }
248
+ );
249
+
250
+ server.registerTool(
251
+ "get_proposal_stats",
252
+ {
253
+ title: "Get Proposal Stats",
254
+ description: "Get proposal statistics including conversion rate, total value, and status breakdown.",
255
+ inputSchema: {},
256
+ },
257
+ async () => {
258
+ const stats = getProposalStats();
259
+ return { content: [{ type: "text", text: JSON.stringify(stats, null, 2) }] };
260
+ }
261
+ );
262
+
263
+ server.registerTool(
264
+ "search_proposals",
265
+ {
266
+ title: "Search Proposals",
267
+ description: "Search proposals by title, client name, email, or notes.",
268
+ inputSchema: { query: z.string() },
269
+ },
270
+ async ({ query }) => {
271
+ const results = searchProposals(query);
272
+ return {
273
+ content: [
274
+ { type: "text", text: JSON.stringify({ results, count: results.length }, null, 2) },
275
+ ],
276
+ };
277
+ }
278
+ );
279
+
280
+ server.registerTool(
281
+ "count_proposals",
282
+ {
283
+ title: "Count Proposals",
284
+ description: "Get the total number of proposals.",
285
+ inputSchema: {},
286
+ },
287
+ async () => {
288
+ const count = countProposals();
289
+ return { content: [{ type: "text", text: JSON.stringify({ count }) }] };
290
+ }
291
+ );
292
+
293
+ // --- Templates ---
294
+
295
+ server.registerTool(
296
+ "create_proposal_template",
297
+ {
298
+ title: "Create Proposal Template",
299
+ description: "Create a reusable proposal template.",
300
+ inputSchema: {
301
+ name: z.string(),
302
+ items: z.array(itemSchema).optional(),
303
+ terms: z.string().optional(),
304
+ notes: z.string().optional(),
305
+ },
306
+ },
307
+ async (params) => {
308
+ const template = createTemplate(params);
309
+ return { content: [{ type: "text", text: JSON.stringify(template, null, 2) }] };
310
+ }
311
+ );
312
+
313
+ server.registerTool(
314
+ "list_proposal_templates",
315
+ {
316
+ title: "List Proposal Templates",
317
+ description: "List all proposal templates.",
318
+ inputSchema: {},
319
+ },
320
+ async () => {
321
+ const templates = listTemplates();
322
+ return {
323
+ content: [
324
+ { type: "text", text: JSON.stringify({ templates, count: templates.length }, null, 2) },
325
+ ],
326
+ };
327
+ }
328
+ );
329
+
330
+ server.registerTool(
331
+ "delete_proposal_template",
332
+ {
333
+ title: "Delete Proposal Template",
334
+ description: "Delete a proposal template by ID.",
335
+ inputSchema: { id: z.string() },
336
+ },
337
+ async ({ id }) => {
338
+ const deleted = deleteTemplate(id);
339
+ return { content: [{ type: "text", text: JSON.stringify({ id, deleted }) }] };
340
+ }
341
+ );
342
+
343
+ server.registerTool(
344
+ "use_proposal_template",
345
+ {
346
+ title: "Use Proposal Template",
347
+ description: "Create a new proposal from a template.",
348
+ inputSchema: {
349
+ template_id: z.string(),
350
+ title: z.string(),
351
+ client_name: z.string(),
352
+ client_email: z.string().optional(),
353
+ valid_until: z.string().optional(),
354
+ },
355
+ },
356
+ async ({ template_id, ...overrides }) => {
357
+ const proposal = useTemplate(template_id, overrides);
358
+ if (!proposal) {
359
+ return { content: [{ type: "text", text: `Template '${template_id}' not found.` }], isError: true };
360
+ }
361
+ return { content: [{ type: "text", text: JSON.stringify(proposal, null, 2) }] };
362
+ }
363
+ );
364
+
365
+ // --- Start ---
366
+ async function main() {
367
+ const transport = new StdioServerTransport();
368
+ await server.connect(transport);
369
+ console.error("microservice-proposals MCP server running on stdio");
370
+ }
371
+
372
+ main().catch((error) => {
373
+ console.error("Fatal error:", error);
374
+ process.exit(1);
375
+ });
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@hasna/microservice-reading",
3
+ "version": "0.0.1",
4
+ "description": "Reading tracker microservice with SQLite — manage books, highlights, reading sessions, and stats",
5
+ "type": "module",
6
+ "bin": {
7
+ "microservice-reading": "./src/cli/index.ts",
8
+ "microservice-reading-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
+ }