@hoststack.dev/mcp 0.6.1 → 0.7.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.
- package/dist/hoststack-mcp.js +24 -10
- package/dist/hoststack-mcp.js.map +1 -1
- package/dist/index.js +24 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/hoststack-mcp.js
CHANGED
|
@@ -483,21 +483,31 @@ defineTool({
|
|
|
483
483
|
"",
|
|
484
484
|
'By default events are AGGREGATED by (action, resourceId) so flapping events collapse to one row with a fire count + first/last timestamps \u2014 e.g. "service.auto_restarted on service 31, 8 times in the last hour, last at 14:22". Pass aggregate=false to see every raw row.',
|
|
485
485
|
"",
|
|
486
|
+
'ACTIVE vs HISTORICAL (v89): each aggregated entry now has an `active` boolean and a `lastResolvedAt` timestamp. `active=true` means the most recent occurrence has NOT been resolved \u2014 the alert is still on fire. The default `active=true` filter hides resolved/historical alerts so triage starts with "what is broken right now". Pass `active=false` to include resolved entries too (useful for post-mortems). Resolution is automatic for some alert kinds \u2014 e.g. `deploy.failed_consecutive` is cleared when the next deploy of the same service goes live.',
|
|
487
|
+
"",
|
|
488
|
+
'Database backup_failed entries (v89) include `containerStatus` / `containerHealth` / `containerExitCode` in lastMetadata when the agent could resolve the container at failure time, so you can tell "Redis is overloaded" apart from "Redis is restarting" without a second tool call.',
|
|
489
|
+
"",
|
|
490
|
+
"Deploy.failed_consecutive entries (v89) carry the offending `commitHash` in lastMetadata, and the streak now dedupes per (service, commitHash) \u2014 one critical per bad commit, not one every 6 retries.",
|
|
491
|
+
"",
|
|
486
492
|
"Inputs (all optional):",
|
|
487
493
|
' - since: ISO-8601 timestamp OR relative offset like "-1h" / "-2d". Default: -24h.',
|
|
488
494
|
" - until: ISO-8601 upper bound (ignored when aggregating \u2014 aggregated view always extends to now).",
|
|
489
495
|
" - limit: max rows (default 100, hard cap 500).",
|
|
490
496
|
" - aggregate: true (default) collapses by (action, resourceId); false returns raw rows.",
|
|
497
|
+
" - active: true (default) shows only alerts that are still on fire (resolved_at IS NULL on the most recent row). false includes resolved historical alerts.",
|
|
491
498
|
"",
|
|
492
|
-
"Returns: { alerts: Array, aggregated: boolean }. Each aggregated entry includes action, resourceType, resourceId, severity, count, firstFiredAt, lastFiredAt, lastMetadata. Each raw entry
|
|
499
|
+
"Returns: { alerts: Array, aggregated: boolean, activeOnly: boolean }. Each aggregated entry includes action, resourceType, resourceId, severity, count, firstFiredAt, lastFiredAt, lastResolvedAt (nullable), active (boolean), lastMetadata. Each raw entry adds resolvedAt (nullable).",
|
|
493
500
|
"",
|
|
494
|
-
"Example: list_alerts({ since: '-1h' }) \u2192 { alerts: [{ action: 'deploy.
|
|
501
|
+
"Example: list_alerts({ since: '-1h' }) \u2192 { alerts: [{ action: 'deploy.failed_consecutive', resourceId: 31, severity: 'critical', active: true, count: 3, lastFiredAt: '\u2026', lastResolvedAt: null, lastMetadata: { commitHash: 'abc1234' }, \u2026 }] }."
|
|
495
502
|
].join("\n"),
|
|
496
503
|
input: {
|
|
497
504
|
since: z3.string().optional().describe('ISO-8601 timestamp or relative offset (e.g. "-1h", "-2d"). Default: -24h.'),
|
|
498
505
|
until: z3.string().optional().describe("ISO-8601 upper bound. Only honored when aggregate=false."),
|
|
499
506
|
limit: z3.number().int().positive().max(500).optional().describe("Max rows (default 100, hard cap 500)."),
|
|
500
|
-
aggregate: z3.boolean().optional().describe("Collapse by (action, resourceId). Default true.")
|
|
507
|
+
aggregate: z3.boolean().optional().describe("Collapse by (action, resourceId). Default true."),
|
|
508
|
+
active: z3.boolean().optional().describe(
|
|
509
|
+
"Only return alerts still on fire (resolved_at IS NULL on the most recent row). Default true. Pass false to include resolved historical alerts."
|
|
510
|
+
)
|
|
501
511
|
},
|
|
502
512
|
handler: async (args2, ctx) => {
|
|
503
513
|
const teamId = await ctx.resolveTeamId();
|
|
@@ -506,11 +516,13 @@ defineTool({
|
|
|
506
516
|
if (args2.until !== void 0) params["until"] = args2.until;
|
|
507
517
|
if (args2.limit !== void 0) params["limit"] = String(args2.limit);
|
|
508
518
|
if (args2.aggregate === false) params["aggregate"] = "0";
|
|
519
|
+
if (args2.active === false) params["active"] = "0";
|
|
509
520
|
const response = await ctx.api.get(`/api/alerts/${teamId}`, params);
|
|
510
521
|
const items = Array.isArray(response.alerts) ? response.alerts.map(shape) : [];
|
|
511
522
|
const aggregated = Boolean(response.aggregated);
|
|
512
|
-
const
|
|
513
|
-
|
|
523
|
+
const activeOnly = args2.active !== false;
|
|
524
|
+
const summary = items.length === 0 ? activeOnly ? "No active alerts in the requested window \u2014 everything is operating normally." : "No alerts in the requested window (active or resolved)." : aggregated ? `Returned ${items.length} alert group${items.length === 1 ? "" : "s"}${activeOnly ? " (active only \u2014 pass active=false for resolved history)" : ""} (flapping events collapsed).` : `Returned ${items.length} raw alert event${items.length === 1 ? "" : "s"}.`;
|
|
525
|
+
return respond({ summary, data: { alerts: items, aggregated, activeOnly } });
|
|
514
526
|
}
|
|
515
527
|
});
|
|
516
528
|
|
|
@@ -613,7 +625,7 @@ defineTool({
|
|
|
613
625
|
"Inputs:",
|
|
614
626
|
' - database_id: publicId of the database (e.g. "db_\u2026").',
|
|
615
627
|
" - name (optional): new database name.",
|
|
616
|
-
' - plan (optional): "free" | "starter" | "standard" | "pro" \u2014 changes memory tier.',
|
|
628
|
+
' - plan (optional): "free" | "micro" | "starter" | "standard" | "pro" \u2014 changes memory tier.',
|
|
617
629
|
" - disk_size_gb (optional): new disk size in GB (must be \u2265 current).",
|
|
618
630
|
"",
|
|
619
631
|
"Returns: { database: Database } \u2014 the updated record.",
|
|
@@ -623,7 +635,7 @@ defineTool({
|
|
|
623
635
|
input: {
|
|
624
636
|
database_id: z5.string().describe("Database publicId (e.g. db_xyz)."),
|
|
625
637
|
name: z5.string().min(1).max(100).optional().describe("New database name."),
|
|
626
|
-
plan: z5.enum(["free", "starter", "standard", "pro"]).optional().describe("Plan tier (memory/CPU)."),
|
|
638
|
+
plan: z5.enum(["free", "micro", "starter", "standard", "pro"]).optional().describe("Plan tier (memory/CPU)."),
|
|
627
639
|
disk_size_gb: z5.number().int().min(1).max(1024).optional().describe("New disk size in GB. Must be \u2265 current.")
|
|
628
640
|
},
|
|
629
641
|
handler: async (args2, ctx) => {
|
|
@@ -682,7 +694,7 @@ defineTool({
|
|
|
682
694
|
"Inputs:",
|
|
683
695
|
' - service_id: publicId of the service (e.g. "svc_abc123"). Use list_services to find it.',
|
|
684
696
|
"",
|
|
685
|
-
|
|
697
|
+
'Returns: { items: Deploy[] } \u2014 each deploy includes id, publicId, status (pending|building|deploying|live|failed|cancelled), commitSha, commitMessage, branch, triggeredBy, startedAt, finishedAt, imageBuildMs (docker build / image-pull only; null on skip-build redeploys \u2014 v89), containerBootMs (deploying \u2192 live wall-clock; null on builds that failed before container start \u2014 v89), buildDurationMs (legacy alias of imageBuildMs kept for back-compat), totalDurationMs (full deploy wall-clock = finishedAt \u2212 startedAt). Use imageBuildMs + containerBootMs together to tell "build is slow" apart from "boot is slow".',
|
|
686
698
|
"",
|
|
687
699
|
'Example: list_deploys({ service_id: "svc_abc" }) \u2192 { items: [{ publicId: "dpl_\u2026", status: "live", commitMessage: "Fix login", \u2026 }, \u2026] }'
|
|
688
700
|
].join("\n"),
|
|
@@ -709,7 +721,7 @@ defineTool({
|
|
|
709
721
|
" - service_id: publicId of the service.",
|
|
710
722
|
' - deploy_id: publicId of the deploy (e.g. "dpl_\u2026").',
|
|
711
723
|
"",
|
|
712
|
-
"Returns: { deploy: Deploy } \u2014 full deploy record (status, commitSha, commitMessage, branch, buildDurationMs, totalDurationMs, finishedAt, etc).",
|
|
724
|
+
"Returns: { deploy: Deploy } \u2014 full deploy record (status, commitSha, commitMessage, branch, imageBuildMs + containerBootMs (v89 split timings; legacy buildDurationMs preserved as alias), totalDurationMs, finishedAt, etc).",
|
|
713
725
|
"",
|
|
714
726
|
'Example: get_deploy({ service_id: "svc_abc", deploy_id: "dpl_xyz" }) \u2192 { deploy: { status: "live", \u2026 } }'
|
|
715
727
|
].join("\n"),
|
|
@@ -1703,7 +1715,9 @@ defineTool({
|
|
|
1703
1715
|
type: z11.enum(["slack", "discord", "email"]).describe("Channel type."),
|
|
1704
1716
|
name: z11.string().min(1).max(128).describe("Human-readable label."),
|
|
1705
1717
|
webhook_url: z11.string().max(500).describe("Slack/Discord webhook URL or email address (when type=email)."),
|
|
1706
|
-
events: z11.array(z11.enum(NOTIFICATION_EVENTS)).describe(
|
|
1718
|
+
events: z11.array(z11.enum(NOTIFICATION_EVENTS)).describe(
|
|
1719
|
+
"List of events the channel subscribes to. Empty list = subscribe to nothing."
|
|
1720
|
+
)
|
|
1707
1721
|
},
|
|
1708
1722
|
handler: async (args2, ctx) => {
|
|
1709
1723
|
const teamId = await ctx.resolveTeamId();
|