@hoststack.dev/mcp 0.8.0 → 0.9.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 +55 -1
- package/dist/hoststack-mcp.js.map +1 -1
- package/dist/index.js +55 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/hoststack-mcp.js
CHANGED
|
@@ -702,7 +702,7 @@ defineTool({
|
|
|
702
702
|
"",
|
|
703
703
|
"Returns: { columns: string[], rows: string[][], rowCount: number, truncated: boolean, durationMs: number }. Values come back as strings (psql --csv); cast on the caller side when needed.",
|
|
704
704
|
"",
|
|
705
|
-
"
|
|
705
|
+
"Example:",
|
|
706
706
|
' - query_database({ database_id: "db_abc", sql: "SELECT count(*) FROM users" }) \u2192 { columns: ["count"], rows: [["1234"]], \u2026 }',
|
|
707
707
|
` - query_database({ database_id: "db_abc", sql: "SELECT id, email FROM users WHERE created_at > now() - interval '1 day' LIMIT 50" })`
|
|
708
708
|
].join("\n"),
|
|
@@ -719,6 +719,60 @@ defineTool({
|
|
|
719
719
|
return respond({ summary, data: result });
|
|
720
720
|
}
|
|
721
721
|
});
|
|
722
|
+
defineTool({
|
|
723
|
+
name: "upgrade_database_to_ha",
|
|
724
|
+
category: "databases",
|
|
725
|
+
description: [
|
|
726
|
+
"Trigger a single-node \u2192 HA migration on a managed Postgres database. The agent runs pg_dump \u2192 bootstrap 3-node Patroni cluster (1 leader + 2 sync replicas + HAProxy) \u2192 pg_restore. Customer connections to this database are briefly read-only during the cutover; the standalone container stays running (read-only) for 24 h as a rollback target before automatic decommission.",
|
|
727
|
+
"",
|
|
728
|
+
"Requires: PATRONI_ENABLED env on the HostStack deployment + `teams.ha_beta = true` on the calling team. Returns 403 otherwise. Returns 400 if the database is already HA, not Postgres, not on the standard or pro tier, or has a pg_database_size over 1 GB (in-memory archive transfer cap).",
|
|
729
|
+
"",
|
|
730
|
+
"When to use: a customer needs failover protection on an existing standalone Postgres. For new databases on an HA-eligible team, just call create_database \u2014 the cluster path is automatic.",
|
|
731
|
+
"",
|
|
732
|
+
"Inputs:",
|
|
733
|
+
" - database_id: publicId of the postgres database to upgrade.",
|
|
734
|
+
"",
|
|
735
|
+
'Returns: 202 Accepted. The upgrade is async \u2014 poll get_database until `pg_engine_type === "patroni"` and `status === "available"` to confirm completion. The Cluster tab on the dashboard mirrors the same data.',
|
|
736
|
+
"",
|
|
737
|
+
'Example: upgrade_database_to_ha({ database_id: "db_abc" }) \u2192 { ok: true }'
|
|
738
|
+
].join("\n"),
|
|
739
|
+
input: {
|
|
740
|
+
database_id: z5.string().describe("Database publicId (e.g. db_abc) to upgrade to HA.")
|
|
741
|
+
},
|
|
742
|
+
handler: async (args2, ctx) => {
|
|
743
|
+
const teamId = await ctx.resolveTeamId();
|
|
744
|
+
await ctx.hoststack.databases.upgradeToHa(teamId, args2.database_id);
|
|
745
|
+
return respond({
|
|
746
|
+
summary: `HA migration started for ${args2.database_id}. Poll get_database until pg_engine_type=patroni to confirm.`
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
defineTool({
|
|
751
|
+
name: "get_database_cluster",
|
|
752
|
+
category: "databases",
|
|
753
|
+
description: [
|
|
754
|
+
"Get the live + retired cluster members and failover history for a Patroni HA Postgres database.",
|
|
755
|
+
"",
|
|
756
|
+
"When to use: confirm an HA cluster is healthy (1 leader + 2 sync replicas + 1 proxy + 1 etcd live) or investigate a failover that fired. For standalone databases this returns 400 \u2014 call get_database first if you need to branch.",
|
|
757
|
+
"",
|
|
758
|
+
"Inputs:",
|
|
759
|
+
" - database_id: publicId of the postgres database (must be HA).",
|
|
760
|
+
"",
|
|
761
|
+
"Returns: { members: { id, memberRole: 'etcd' | 'primary-candidate' | 'replica' | 'proxy', containerId, workerHostId, joinedAt, leftAt }[], failovers: { id, createdAt, oldLeader, newLeader }[] }.",
|
|
762
|
+
"",
|
|
763
|
+
'Example: get_database_cluster({ database_id: "db_abc" }) \u2192 { members: [...5 live rows], failovers: [] }'
|
|
764
|
+
].join("\n"),
|
|
765
|
+
input: {
|
|
766
|
+
database_id: z5.string().describe("Database publicId for the HA cluster.")
|
|
767
|
+
},
|
|
768
|
+
handler: async (args2, ctx) => {
|
|
769
|
+
const teamId = await ctx.resolveTeamId();
|
|
770
|
+
const result = await ctx.hoststack.databases.getCluster(teamId, args2.database_id);
|
|
771
|
+
const live = result.members.filter((m) => m.leftAt === null);
|
|
772
|
+
const summary = `${live.length} live members (${live.map((m) => m.memberRole).join(", ")}); ${result.failovers.length} historical failovers.`;
|
|
773
|
+
return respond({ summary, data: result });
|
|
774
|
+
}
|
|
775
|
+
});
|
|
722
776
|
|
|
723
777
|
// src/tools/deploys.ts
|
|
724
778
|
import { z as z6 } from "zod";
|