sophos-central-mcp-server 0.2.5 → 0.2.7

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.
@@ -8,7 +8,7 @@
8
8
  * sophos_list_partner_admin_role_assignments,
9
9
  * sophos_add_partner_admin_role_assignment,
10
10
  * sophos_delete_partner_admin_role_assignment,
11
- * sophos_get_billing_usage
11
+ * sophos_get_billing_usage, sophos_get_billing_summary
12
12
  * Partner/organization-level tools using globalRequest.
13
13
  */
14
14
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -1 +1 @@
1
- {"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,YAAY,EACpB,cAAc,EAAE,cAAc,GAC7B,IAAI,CA+rBN"}
1
+ {"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,YAAY,EACpB,cAAc,EAAE,cAAc,GAC7B,IAAI,CAk6BN"}
@@ -8,7 +8,7 @@
8
8
  * sophos_list_partner_admin_role_assignments,
9
9
  * sophos_add_partner_admin_role_assignment,
10
10
  * sophos_delete_partner_admin_role_assignment,
11
- * sophos_get_billing_usage
11
+ * sophos_get_billing_usage, sophos_get_billing_summary
12
12
  * Partner/organization-level tools using globalRequest.
13
13
  */
14
14
  import { z } from "zod";
@@ -566,5 +566,195 @@ Returns:
566
566
  }
567
567
  return jsonResult(data);
568
568
  }));
569
+ // =========================================================================
570
+ // BILLING SUMMARY (aggregated)
571
+ // =========================================================================
572
+ server.registerTool("sophos_get_billing_summary", {
573
+ title: "Get Billing Summary by Customer",
574
+ description: `Get an aggregated billing summary for a specific month, ranked by customer revenue.
575
+
576
+ Auto-paginates through ALL billing line items and aggregates by customer.
577
+ Returns per-customer totals with product breakdown, sorted by monthly revenue descending.
578
+
579
+ Monthly cost per line item is calculated as: billableQuantity * unitPrice.
580
+ The netPrice field in raw billing data is the total order line value shared across
581
+ all customers on that line — NOT the per-customer cost.
582
+
583
+ Use compact=true to get a smaller response with coverage flags (hasMDR, mdrTier,
584
+ hasFirewall, firewallModels) instead of full product arrays. This fits all customers
585
+ in a single response without hitting the character limit.
586
+
587
+ Args:
588
+ - year (number): The year (e.g. 2026).
589
+ - month (number): The month (1-12).
590
+ - limit (number, optional): Return only the top N customers (default: all).
591
+ - compact (boolean, optional): Return coverage flags instead of full product arrays (default: false).
592
+
593
+ Returns:
594
+ Ranked list of customers with monthly cost, product breakdown, and estate totals.`,
595
+ inputSchema: {
596
+ year: z.number().int().min(2000).max(2100).describe("Year (e.g. 2026)"),
597
+ month: z.number().int().min(1).max(12).describe("Month (1-12)"),
598
+ limit: z
599
+ .number()
600
+ .int()
601
+ .min(1)
602
+ .optional()
603
+ .describe("Return only the top N customers (default: all)"),
604
+ compact: z
605
+ .boolean()
606
+ .optional()
607
+ .describe("Return coverage flags instead of full product arrays (default: false)"),
608
+ },
609
+ annotations: {
610
+ readOnlyHint: true,
611
+ destructiveHint: false,
612
+ idempotentHint: true,
613
+ openWorldHint: true,
614
+ },
615
+ }, withErrorHandling(async ({ year, month, limit, compact }) => {
616
+ // Auto-paginate to collect ALL billing line items
617
+ const allItems = [];
618
+ let cursor;
619
+ let pageCount = 0;
620
+ const maxPages = 20; // Safety limit
621
+ do {
622
+ const params = {
623
+ pageTotal: "true",
624
+ pageSize: "1000",
625
+ };
626
+ if (cursor)
627
+ params.cursor = cursor;
628
+ const data = await client.globalRequest(`/partner/v1/billing/usage/${year}/${month}`, { params });
629
+ if (Array.isArray(data.items)) {
630
+ allItems.push(...data.items);
631
+ }
632
+ cursor = data.pages?.nextKey ?? undefined;
633
+ pageCount++;
634
+ } while (cursor && pageCount < maxPages);
635
+ // Aggregate by customer
636
+ const customers = new Map();
637
+ for (const item of allItems) {
638
+ const name = String(item.assignedAccountIdentifier ?? "Unknown");
639
+ const accountId = item.accountId ?? null;
640
+ const quantity = Number(item.billableQuantity ?? 0);
641
+ const unitPrice = Number(item.unitPrice ?? 0);
642
+ const monthlyCost = quantity * unitPrice;
643
+ const productGroup = String(item.productGroup ?? "Other");
644
+ const productDesc = String(item.productDescription ?? "Unknown");
645
+ const productCode = String(item.productCode ?? "unknown");
646
+ if (!customers.has(name)) {
647
+ customers.set(name, {
648
+ name,
649
+ accountId,
650
+ monthlyTotal: 0,
651
+ products: new Map(),
652
+ totalUsers: 0,
653
+ totalServers: 0,
654
+ totalDevices: 0,
655
+ hasMDR: false,
656
+ mdrTier: null,
657
+ hasFirewall: false,
658
+ firewallModels: new Set(),
659
+ });
660
+ }
661
+ const cust = customers.get(name);
662
+ cust.monthlyTotal += monthlyCost;
663
+ // Track product breakdown
664
+ const key = productCode;
665
+ if (!cust.products.has(key)) {
666
+ cust.products.set(key, { description: productDesc, quantity: 0, monthlyCost: 0, productGroup });
667
+ }
668
+ const prod = cust.products.get(key);
669
+ prod.quantity += quantity;
670
+ prod.monthlyCost += monthlyCost;
671
+ // Track seat/device counts
672
+ if (productGroup === "User")
673
+ cust.totalUsers += quantity;
674
+ else if (productGroup === "Server")
675
+ cust.totalServers += quantity;
676
+ else if (productGroup === "Device")
677
+ cust.totalDevices += quantity;
678
+ // Track MDR coverage
679
+ const descLower = productDesc.toLowerCase();
680
+ if (descLower.includes("mdr complete")) {
681
+ cust.hasMDR = true;
682
+ cust.mdrTier = "Complete";
683
+ }
684
+ else if (descLower.includes("mdr essentials") && cust.mdrTier !== "Complete") {
685
+ cust.hasMDR = true;
686
+ cust.mdrTier = "Essentials";
687
+ }
688
+ // Track firewall coverage
689
+ if (productGroup === "Device" && (descLower.includes("xgs") || descLower.includes("xg ") ||
690
+ descLower.includes("sf sw") || descLower.includes("sf virtual") ||
691
+ descLower.includes("xstream protection") || descLower.includes("standard protection"))) {
692
+ cust.hasFirewall = true;
693
+ // Extract model from description
694
+ const modelMatch = productDesc.match(/^(XGS \d+|XG \d+|SF SW\/Virtual[^-]*)/i);
695
+ if (modelMatch)
696
+ cust.firewallModels.add(modelMatch[1].trim());
697
+ }
698
+ }
699
+ // Sort by monthly total descending
700
+ const sorted = [...customers.values()]
701
+ .sort((a, b) => b.monthlyTotal - a.monthlyTotal)
702
+ .slice(0, limit ?? customers.size);
703
+ // Build summary
704
+ const grandTotal = [...customers.values()].reduce((sum, c) => sum + c.monthlyTotal, 0);
705
+ const totalCustomers = customers.size;
706
+ if (compact) {
707
+ const compactSummary = sorted.map((c, i) => ({
708
+ rank: i + 1,
709
+ customer: c.name,
710
+ accountId: c.accountId,
711
+ monthlyAUD: Math.round(c.monthlyTotal * 100) / 100,
712
+ users: c.totalUsers,
713
+ servers: c.totalServers,
714
+ devices: c.totalDevices,
715
+ hasMDR: c.hasMDR,
716
+ mdrTier: c.mdrTier,
717
+ hasFirewall: c.hasFirewall,
718
+ firewallModels: [...c.firewallModels],
719
+ }));
720
+ return jsonResult({
721
+ period: `${year}-${String(month).padStart(2, "0")}`,
722
+ currency: "AUD",
723
+ totalCustomers,
724
+ totalLineItems: allItems.length,
725
+ grandTotalMonthlyAUD: Math.round(grandTotal * 100) / 100,
726
+ returnedCustomers: compactSummary.length,
727
+ customers: compactSummary,
728
+ });
729
+ }
730
+ const summary = sorted.map((c, i) => ({
731
+ rank: i + 1,
732
+ customer: c.name,
733
+ accountId: c.accountId,
734
+ monthlyAUD: Math.round(c.monthlyTotal * 100) / 100,
735
+ users: c.totalUsers,
736
+ servers: c.totalServers,
737
+ devices: c.totalDevices,
738
+ hasMDR: c.hasMDR,
739
+ mdrTier: c.mdrTier,
740
+ hasFirewall: c.hasFirewall,
741
+ firewallModels: [...c.firewallModels],
742
+ products: [...c.products.values()].map((p) => ({
743
+ product: p.description,
744
+ group: p.productGroup,
745
+ quantity: p.quantity,
746
+ monthlyAUD: Math.round(p.monthlyCost * 100) / 100,
747
+ })),
748
+ }));
749
+ return jsonResult({
750
+ period: `${year}-${String(month).padStart(2, "0")}`,
751
+ currency: "AUD",
752
+ totalCustomers,
753
+ totalLineItems: allItems.length,
754
+ grandTotalMonthlyAUD: Math.round(grandTotal * 100) / 100,
755
+ returnedCustomers: summary.length,
756
+ customers: summary,
757
+ });
758
+ }));
569
759
  }
570
760
  //# sourceMappingURL=partner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"partner.js","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"partner.js","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,366 @@
1
+ """Generate Rodin Business Solutions - Sophos Central Estate Health Report (PDF)."""
2
+ import sys, os
3
+ sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf-8', buffering=1)
4
+
5
+ from fpdf import FPDF
6
+ from datetime import datetime
7
+
8
+ # ── Sophos brand colours ──
9
+ SOPHOS_BLUE = (0, 53, 128)
10
+ SOPHOS_DARK = (34, 34, 34)
11
+ SOPHOS_RED = (200, 30, 30)
12
+ SOPHOS_AMBER = (210, 140, 0)
13
+ SOPHOS_GREEN = (40, 140, 60)
14
+ SOPHOS_GREY = (100, 100, 100)
15
+ WHITE = (255, 255, 255)
16
+ LIGHT_BG = (245, 247, 250)
17
+ ROW_ALT = (235, 240, 248)
18
+
19
+ class PDF(FPDF):
20
+ def header(self):
21
+ self.set_font("Helvetica", "B", 9)
22
+ self.set_text_color(*SOPHOS_GREY)
23
+ self.cell(0, 6, "Rodin Business Solutions | Sophos Central Estate Health Report | March 2026", align="L")
24
+ self.ln(4)
25
+ self.set_draw_color(*SOPHOS_BLUE)
26
+ self.set_line_width(0.6)
27
+ self.line(10, self.get_y(), 200, self.get_y())
28
+ self.ln(6)
29
+
30
+ def footer(self):
31
+ self.set_y(-15)
32
+ self.set_font("Helvetica", "", 8)
33
+ self.set_text_color(*SOPHOS_GREY)
34
+ self.cell(0, 10, f"Page {self.page_no()}/{{nb}} | Generated {datetime.now().strftime('%d/%m/%Y %H:%M')}", align="C")
35
+
36
+ def section_title(self, title, colour=SOPHOS_BLUE):
37
+ self.set_font("Helvetica", "B", 14)
38
+ self.set_text_color(*colour)
39
+ self.cell(0, 10, title)
40
+ self.ln(8)
41
+ self.set_text_color(*SOPHOS_DARK)
42
+
43
+ def sub_title(self, title, colour=SOPHOS_DARK):
44
+ self.set_font("Helvetica", "B", 11)
45
+ self.set_text_color(*colour)
46
+ self.cell(0, 8, title)
47
+ self.ln(6)
48
+ self.set_text_color(*SOPHOS_DARK)
49
+
50
+ def body_text(self, text):
51
+ self.set_font("Helvetica", "", 10)
52
+ self.set_text_color(*SOPHOS_DARK)
53
+ self.multi_cell(0, 5.5, text)
54
+ self.ln(2)
55
+
56
+ def table_header(self, cols):
57
+ self.set_font("Helvetica", "B", 9)
58
+ self.set_fill_color(*SOPHOS_BLUE)
59
+ self.set_text_color(*WHITE)
60
+ for label, w in cols:
61
+ self.cell(w, 7, label, border=0, fill=True, align="C")
62
+ self.ln()
63
+ self.set_text_color(*SOPHOS_DARK)
64
+
65
+ def table_row(self, cols, row_idx=0):
66
+ self.set_font("Helvetica", "", 9)
67
+ if row_idx % 2 == 1:
68
+ self.set_fill_color(*ROW_ALT)
69
+ fill = True
70
+ else:
71
+ self.set_fill_color(*WHITE)
72
+ fill = True
73
+ for val, w, align in cols:
74
+ self.cell(w, 6.5, str(val), border=0, fill=fill, align=align)
75
+ self.ln()
76
+
77
+
78
+ pdf = PDF(orientation="P", unit="mm", format="A4")
79
+ pdf.alias_nb_pages()
80
+ pdf.set_auto_page_break(auto=True, margin=20)
81
+
82
+ # ═══════════════════════════════════════════════════════════════════════════════
83
+ # COVER / EXECUTIVE SUMMARY
84
+ # ═══════════════════════════════════════════════════════════════════════════════
85
+ pdf.add_page()
86
+ pdf.ln(15)
87
+ pdf.set_font("Helvetica", "B", 28)
88
+ pdf.set_text_color(*SOPHOS_BLUE)
89
+ pdf.cell(0, 14, "Sophos Central", align="C")
90
+ pdf.ln(14)
91
+ pdf.set_font("Helvetica", "B", 22)
92
+ pdf.cell(0, 12, "Estate Health & Opportunity Report", align="C")
93
+ pdf.ln(16)
94
+ pdf.set_font("Helvetica", "", 13)
95
+ pdf.set_text_color(*SOPHOS_GREY)
96
+ pdf.cell(0, 8, "Rodin Business Solutions | March 2026", align="C")
97
+ pdf.ln(8)
98
+ pdf.cell(0, 8, "Prepared by Sophos Central MCP Automation", align="C")
99
+ pdf.ln(20)
100
+
101
+ # Summary boxes
102
+ pdf.set_draw_color(*SOPHOS_BLUE)
103
+ pdf.set_line_width(0.4)
104
+
105
+ metrics = [
106
+ ("153", "Total Tenants"),
107
+ ("115", "Healthy (75%)"),
108
+ ("34", "With Gaps (22%)"),
109
+ ("$38,923", "Monthly AUD"),
110
+ ]
111
+ box_w = 42
112
+ start_x = 12
113
+ for i, (val, label) in enumerate(metrics):
114
+ x = start_x + i * (box_w + 4)
115
+ pdf.set_xy(x, pdf.get_y())
116
+ pdf.set_fill_color(*LIGHT_BG)
117
+ pdf.rect(x, pdf.get_y(), box_w, 24, style="FD")
118
+ pdf.set_xy(x, pdf.get_y() + 3)
119
+ pdf.set_font("Helvetica", "B", 18)
120
+ pdf.set_text_color(*SOPHOS_BLUE)
121
+ pdf.cell(box_w, 10, val, align="C")
122
+ pdf.set_xy(x, pdf.get_y() + 10)
123
+ pdf.set_font("Helvetica", "", 9)
124
+ pdf.set_text_color(*SOPHOS_GREY)
125
+ pdf.cell(box_w, 6, label, align="C")
126
+
127
+ pdf.ln(32)
128
+
129
+ pdf.set_text_color(*SOPHOS_DARK)
130
+ pdf.section_title("Executive Summary")
131
+ pdf.body_text(
132
+ "This report provides a comprehensive health assessment of the Rodin Business Solutions "
133
+ "managed Sophos Central estate for March 2026. It identifies security configuration gaps "
134
+ "requiring remediation and highlights commercial opportunities where customers could benefit "
135
+ "from additional Sophos products."
136
+ )
137
+ pdf.body_text(
138
+ "Key findings:\n"
139
+ "- 4 tenants have tamper protection completely disabled (0%) - critical risk\n"
140
+ "- 1 tenant has server protection at 0% despite having enrolled servers\n"
141
+ "- 18 tenants have partial tamper protection gaps across computers or servers\n"
142
+ "- 14 tenants have no server protection enrolled (upsell opportunity)\n"
143
+ "- Multiple customers lack MDR or Sophos Firewall coverage (detailed in Section 4)"
144
+ )
145
+
146
+ # ═══════════════════════════════════════════════════════════════════════════════
147
+ # SECTION 2: CRITICAL HEALTH GAPS
148
+ # ═══════════════════════════════════════════════════════════════════════════════
149
+ pdf.add_page()
150
+ pdf.section_title("1. Critical Health Gaps", SOPHOS_RED)
151
+ pdf.body_text(
152
+ "The following tenants have tamper protection at 0% or server protection failures. "
153
+ "These represent the highest security risk and should be remediated immediately. "
154
+ "Without tamper protection, a threat actor who gains access can disable Sophos endpoint "
155
+ "protection entirely."
156
+ )
157
+
158
+ critical = [
159
+ ("Marco Polo Aged Care Services", "TP 0% computers AND servers", "Re-enable global TP immediately - aged care is high compliance risk"),
160
+ ("Unibuild", "TP 0% computers", "Re-enable global TP; check if intentionally disabled during deployment"),
161
+ ("MasterCraft Windows and Doors", "TP 0% computers", "Re-enable global TP"),
162
+ ("Martin Morris & Jones Sydney", "TP 0% computers", "Re-enable global TP; may be a stale/test tenant"),
163
+ ("WIN Sports & Entertainment Centres", "Server protection 0% (2 servers)", "Investigate why 2 enrolled servers show 0% protection"),
164
+ ]
165
+
166
+ cols = [("Customer", 55), ("Issue", 55), ("Recommended Action", 80)]
167
+ pdf.table_header(cols)
168
+ for i, (cust, issue, action) in enumerate(critical):
169
+ pdf.table_row([(cust, 55, "L"), (issue, 55, "L"), (action, 80, "L")], i)
170
+
171
+ pdf.ln(6)
172
+
173
+ # ═══════════════════════════════════════════════════════════════════════════════
174
+ # SECTION 3: HIGH & MODERATE GAPS
175
+ # ═══════════════════════════════════════════════════════════════════════════════
176
+ pdf.section_title("2. High Priority Gaps", SOPHOS_AMBER)
177
+ pdf.body_text(
178
+ "These tenants have tamper protection below 90% on servers or significant partial gaps. "
179
+ "In most cases this indicates 1-2 endpoints with TP disabled that need attention."
180
+ )
181
+
182
+ high = [
183
+ ("Durham Green", "TP 59% computers", "Multiple endpoints with TP off - audit and re-enable"),
184
+ ("Southern Truck Centre", "TP 99% PC, 66% servers", "1 of 3 servers has TP disabled"),
185
+ ("Gunderson Briggs", "TP 98% PC, 88% servers", "1 server + 1 computer TP disabled"),
186
+ ("IOH Injury & Occupational Health", "TP 99% PC, 88% servers", "1 server with TP disabled"),
187
+ ("Project Portfolio Management", "TP 80% servers", "1 server with TP disabled"),
188
+ ("Sydney Automotive Paints & Equipment", "TP 85% servers", "1 server with TP disabled"),
189
+ ]
190
+
191
+ cols = [("Customer", 60), ("Issue", 60), ("Action", 70)]
192
+ pdf.table_header(cols)
193
+ for i, (cust, issue, action) in enumerate(high):
194
+ pdf.table_row([(cust, 60, "L"), (issue, 60, "L"), (action, 70, "L")], i)
195
+
196
+ pdf.ln(6)
197
+
198
+ pdf.section_title("3. Moderate Gaps - Cleanup Required")
199
+ pdf.body_text(
200
+ "These tenants have tamper protection between 92-99%. Typically 1-2 stale or "
201
+ "decommissioned endpoints. Recommend checking if devices are still active and either "
202
+ "re-enabling TP or removing the stale device."
203
+ )
204
+
205
+ moderate = [
206
+ ("Australian Survey Solutions", "92%", "1-2 endpoints"),
207
+ ("Arex Pty Ltd", "92%", "1-2 endpoints"),
208
+ ("Kintyre Country Living", "96%", "1 endpoint"),
209
+ ("Van Mal Group Constructions", "96%", "1 endpoint"),
210
+ ("The Illawarra ITEC", "96%", "1 endpoint"),
211
+ ("The Royce Aged Care", "98%", "1 endpoint"),
212
+ ("Gordon MacDonald", "98%", "1 endpoint"),
213
+ ("Kiama Community College", "99%", "1 endpoint"),
214
+ ("Martin Morris & Jones Wollongong", "99%", "1 endpoint"),
215
+ ("Cram Foundation", "99%", "1 endpoint"),
216
+ ]
217
+
218
+ cols = [("Customer", 70), ("TP Score", 30), ("Likely Scope", 70)]
219
+ pdf.table_header(cols)
220
+ for i, (cust, score, scope) in enumerate(moderate):
221
+ pdf.table_row([(cust, 70, "L"), (score, 30, "C"), (scope, 70, "L")], i)
222
+
223
+ # ═══════════════════════════════════════════════════════════════════════════════
224
+ # SECTION 4: UPSELL - NO MDR
225
+ # ═══════════════════════════════════════════════════════════════════════════════
226
+ pdf.add_page()
227
+ pdf.section_title("4. Upsell Opportunities")
228
+
229
+ pdf.sub_title("4a. Customers Without MDR", SOPHOS_BLUE)
230
+ pdf.body_text(
231
+ "The following customers are on Sophos Endpoint only (no MDR Complete or Essentials). "
232
+ "These represent the highest-value upsell opportunity - MDR adds 24/7 threat detection "
233
+ "and response with the Sophos MDR team. Sorted by user count to prioritise larger estates."
234
+ )
235
+
236
+ no_mdr = [
237
+ ("Southern Truck Centre Wollongong", 41, 2, "$446.91", "Endpoint + XG 210 only. 43 protected assets with no MDR coverage."),
238
+ ("Kintyre Country Living", 3, 0, "$415.77", "XG 310 firewall + 3 users. Low user count but paying for premium firewall."),
239
+ ("Custom Built Frames & Trusses", 3, 1, "$33.57", "Endpoint only + XGS 107. Small but could bundle MDR with existing firewall."),
240
+ ("Gunderson Briggs", 23, 2, "$136.11", "Endpoint only + XGS 136. 25 assets - strong MDR candidate."),
241
+ ("The Illawarra ITEC Ltd", 3, 1, "$14.21", "Endpoint only. Small tenant."),
242
+ ("Tulich Project Management", 0, 2, "$13.24", "Servers only, no MDR. Should have at minimum MDR Essentials on servers."),
243
+ ]
244
+
245
+ cols = [("Customer", 52), ("Users", 14), ("Servers", 14), ("Current $", 22), ("Notes", 88)]
246
+ pdf.table_header(cols)
247
+ for i, (cust, users, servers, rev, notes) in enumerate(no_mdr):
248
+ pdf.table_row([(cust, 52, "L"), (str(users), 14, "C"), (str(servers), 14, "C"), (rev, 22, "R"), (notes, 88, "L")], i)
249
+
250
+ pdf.ln(6)
251
+
252
+ pdf.sub_title("4b. Customers Without Sophos Firewall", SOPHOS_BLUE)
253
+ pdf.body_text(
254
+ "The following customers with 20+ users have no Sophos firewall (XGS, SF Virtual, or XG) "
255
+ "in their billing. These are candidates for Sophos Firewall or SF Virtual deployment, "
256
+ "especially those already on MDR Complete who would benefit from firewall-endpoint integration."
257
+ )
258
+
259
+ no_fw = [
260
+ ("Sydwest Multicultural Services", 114, 5, "$1,253.48", "MDR Complete, 119 assets. Large estate with NO firewall - top priority."),
261
+ ("Master Builders Assoc NSW", 94, 11, "$1,163.00", "MDR Complete, 105 assets. Major opportunity for XGS deployment."),
262
+ ("Martin Moris & Jones", 79, 2, "$967.30", "MDR Complete. 81 assets, no firewall."),
263
+ ("QCC", 82, 2, "$871.58", "MDR Complete. 84 assets, no network protection."),
264
+ ("Ingenuity Design Group", 67, 17, "$557.20", "MDR Essentials, 84 assets. Also upgrade path to MDR Complete."),
265
+ ("Community Gateway", 54, 2, "$586.82", "MDR Complete. 56 assets, no firewall."),
266
+ ("Macarthur Diversity Services", 42, 0, "$427.14", "MDR Complete. 42 users, no firewall, no servers."),
267
+ ("Arrow Electrical Services", 54, 0, "$408.20", "MDR Complete + ZTNA. No firewall and no servers - check if needed."),
268
+ ]
269
+
270
+ cols = [("Customer", 52), ("Users", 14), ("Servers", 14), ("Current $", 22), ("Opportunity", 88)]
271
+ pdf.table_header(cols)
272
+ for i, (cust, users, servers, rev, notes) in enumerate(no_fw):
273
+ pdf.table_row([(cust, 52, "L"), (str(users), 14, "C"), (str(servers), 14, "C"), (rev, 22, "R"), (notes, 88, "L")], i)
274
+
275
+ pdf.ln(6)
276
+
277
+ pdf.sub_title("4c. MDR Essentials to Complete Upgrade Path", SOPHOS_BLUE)
278
+ pdf.body_text(
279
+ "These customers have MDR Essentials and could be upgraded to MDR Complete for full "
280
+ "24/7 managed threat response. MDR Complete adds human-led threat hunting, incident "
281
+ "response, and a dedicated response team."
282
+ )
283
+
284
+ essentials_upgrade = [
285
+ ("ReadiNow Corporation", 58, 66, "$1,121.98", "124 assets on Essentials. Largest Essentials customer - high value upgrade."),
286
+ ("Moduplay Group", 125, 2, "$816.40", "127 assets on Essentials + 3 firewalls. Large estate."),
287
+ ("Ingenuity Design Group", 67, 17, "$557.20", "84 assets on Essentials. Also no firewall."),
288
+ ("National Justice Project", 29, 0, "$149.64", "29 users on Essentials."),
289
+ ]
290
+
291
+ cols = [("Customer", 52), ("Users", 14), ("Servers", 14), ("Current $", 22), ("Notes", 88)]
292
+ pdf.table_header(cols)
293
+ for i, (cust, users, servers, rev, notes) in enumerate(essentials_upgrade):
294
+ pdf.table_row([(cust, 52, "L"), (str(users), 14, "C"), (str(servers), 14, "C"), (rev, 22, "R"), (notes, 88, "L")], i)
295
+
296
+ # ═══════════════════════════════════════════════════════════════════════════════
297
+ # SECTION 5: NO SERVER PROTECTION
298
+ # ═══════════════════════════════════════════════════════════════════════════════
299
+ pdf.add_page()
300
+ pdf.section_title("5. No Server Protection Enrolled")
301
+ pdf.body_text(
302
+ "14 tenants have no server protection enrolled in Sophos Central. These customers either "
303
+ "have no servers or their servers are unprotected. For customers with on-premises or "
304
+ "cloud infrastructure, server protection is essential."
305
+ )
306
+
307
+ no_server = [
308
+ "Big Fat Smile", "Intrec Management Pty Ltd", "ROKT Pty Limited",
309
+ "Golden West Holden", "Etheridge Ford", "Gateway Motor Group",
310
+ "C-Lite Pty Ltd", "C-Lite", "True Blue Chemicals",
311
+ "Sydney Auto Paint", "CHL Wollongong Pty Limited", "Pumps United",
312
+ "Seapost Pty Ltd t/as Dion's Bus Service", "Kiama Community College",
313
+ ]
314
+
315
+ cols = [("Customer", 95), ("Recommended Action", 95)]
316
+ pdf.table_header(cols)
317
+ for i, cust in enumerate(no_server):
318
+ action = "Assess server estate; deploy Sophos Server Protection or MDR Server"
319
+ pdf.table_row([(cust, 95, "L"), (action, 95, "L")], i)
320
+
321
+ # ═══════════════════════════════════════════════════════════════════════════════
322
+ # SECTION 6: ACTION PLAN
323
+ # ═══════════════════════════════════════════════════════════════════════════════
324
+ pdf.ln(8)
325
+ pdf.section_title("6. Recommended Action Plan")
326
+
327
+ pdf.sub_title("Immediate (This Week)", SOPHOS_RED)
328
+ pdf.body_text(
329
+ "1. Re-enable tamper protection on the 4 critical tenants (Marco Polo Aged Care, "
330
+ "Unibuild, MasterCraft, Martin Morris & Jones Sydney)\n"
331
+ "2. Investigate WIN Sports server protection at 0%\n"
332
+ "3. Fix Durham Green (59% TP) - multiple endpoints need TP re-enabled"
333
+ )
334
+
335
+ pdf.sub_title("Short Term (This Month)", SOPHOS_AMBER)
336
+ pdf.body_text(
337
+ "4. Remediate all server TP gaps (Southern Truck, Gunderson Briggs, IOH, PPM, Sydney Auto Paints)\n"
338
+ "5. Clean up moderate TP gaps (10 tenants with 92-99% scores - likely stale devices)\n"
339
+ "6. Begin conversations with top MDR upsell targets: Southern Truck Centre (41 users), "
340
+ "Gunderson Briggs (25 assets)"
341
+ )
342
+
343
+ pdf.sub_title("Quarterly Business Review Conversations", SOPHOS_BLUE)
344
+ pdf.body_text(
345
+ "7. Firewall opportunities: Sydwest Multicultural (114 users, no FW), Master Builders (105 assets, no FW), "
346
+ "QCC (84 assets, no FW)\n"
347
+ "8. MDR Complete upgrades: ReadiNow (124 assets), Moduplay (127 assets), Ingenuity Design (84 assets)\n"
348
+ "9. Server protection for the 14 tenants with no server enrollment\n"
349
+ "10. Review all 142 billing customers against the 153 tenants - 11 tenants have no billing "
350
+ "(may be trial, internal, or decommissioned)"
351
+ )
352
+
353
+ pdf.ln(4)
354
+ pdf.set_font("Helvetica", "I", 9)
355
+ pdf.set_text_color(*SOPHOS_GREY)
356
+ pdf.multi_cell(0, 5, (
357
+ "Data sourced from Sophos Central API via MCP Server v0.2.6. "
358
+ "Health data from Account Health Check API. Billing data from Partner Billing Usage API (March 2026). "
359
+ "All monetary values in AUD at partner net pricing."
360
+ ))
361
+
362
+ # ── Save ──
363
+ out_dir = r"C:\Users\Aaron.Jacobs\OneDrive - Sophos Ltd\projects"
364
+ out_path = os.path.join(out_dir, "Rodin_Sophos_Estate_Health_Report_March_2026.pdf")
365
+ pdf.output(out_path)
366
+ print(f"Report saved to: {out_path}")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sophos-central-mcp-server",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "MCP server for Sophos Central API - SOC monitoring, endpoint management, admin automation, and XDR investigation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",