@hoststack.dev/mcp 0.10.1 → 0.11.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/README.md +16 -16
- package/dist/hoststack-mcp.js +109 -3
- package/dist/hoststack-mcp.js.map +1 -1
- package/dist/index.js +109 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -87,22 +87,22 @@ If `HOSTSTACK_API_KEY` is set in your shell, it gets baked into the snippet; oth
|
|
|
87
87
|
|
|
88
88
|
60 tools, grouped by resource:
|
|
89
89
|
|
|
90
|
-
| Category | Read | Write
|
|
91
|
-
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
-
| **projects** | `list_projects`, `get_project` | `create_project`, `update_project`
|
|
93
|
-
| **services** | `list_services`, `get_service`, `get_service_metrics`, `get_service_metrics_history`, `get_service_logs`, `get_service_logs_bulk` | `create_service`, `create_dev_environment`, `update_service`, `update_service_config`, `suspend_service`, `resume_service`
|
|
94
|
-
| **deploys** | `list_deploys`, `get_deploy`, `get_deploy_logs`, `diagnose_deploy` | `trigger_deploy`, `cancel_deploy`
|
|
95
|
-
| **environments** | `list_environments` | `create_environment`, `delete_environment`, `promote_deploy`
|
|
96
|
-
| **databases** | `list_databases`, `get_database`, `get_database_cluster`, `query_database` | `update_database`, `upgrade_database_to_ha` (use the dashboard for create/delete/credentials)
|
|
97
|
-
| **volumes** | `list_volumes` | `create_volume`, `update_volume`, `delete_volume`
|
|
98
|
-
| **domains** | `list_domains` | `add_domain`, `verify_domain`, `remove_domain`
|
|
99
|
-
| **dns** | `list_dns_zones`, `list_dns_records`, `get_dns_record` | `create_dns_record`, `update_dns_record`, `delete_dns_record`
|
|
100
|
-
| **env-vars** | `list_env_vars` | `set_env_var`, `delete_env_var`, `bulk_set_env_vars`
|
|
101
|
-
| **cron** | `list_cron_executions`, `get_cron_execution` | —
|
|
102
|
-
| **notifications** | `list_notification_channels` | `create_notification_channel`, `update_notification_channel`, `delete_notification_channel`, `test_notification_channel`
|
|
103
|
-
| **alerts** | `list_alerts` | —
|
|
104
|
-
| **activity-log** | `list_activity_log` | —
|
|
105
|
-
| **meta** | `get_me` | —
|
|
90
|
+
| Category | Read | Write |
|
|
91
|
+
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| **projects** | `list_projects`, `get_project` | `create_project`, `update_project` |
|
|
93
|
+
| **services** | `list_services`, `get_service`, `get_service_metrics`, `get_service_metrics_history`, `get_service_logs`, `get_service_logs_bulk` | `create_service`, `create_dev_environment`, `update_service`, `update_service_config`, `suspend_service`, `resume_service` |
|
|
94
|
+
| **deploys** | `list_deploys`, `get_deploy`, `get_deploy_logs`, `diagnose_deploy` | `trigger_deploy`, `cancel_deploy` |
|
|
95
|
+
| **environments** | `list_environments` | `create_environment`, `delete_environment`, `promote_deploy` |
|
|
96
|
+
| **databases** | `list_databases`, `get_database`, `get_database_cluster`, `query_database` | `update_database`, `upgrade_database_to_ha` (use the dashboard for create/delete/credentials) |
|
|
97
|
+
| **volumes** | `list_volumes` | `create_volume`, `update_volume`, `delete_volume` |
|
|
98
|
+
| **domains** | `list_domains` | `add_domain`, `verify_domain`, `remove_domain` |
|
|
99
|
+
| **dns** | `list_dns_zones`, `list_dns_records`, `get_dns_record` | `create_dns_record`, `update_dns_record`, `delete_dns_record` |
|
|
100
|
+
| **env-vars** | `list_env_vars` | `set_env_var`, `delete_env_var`, `bulk_set_env_vars` |
|
|
101
|
+
| **cron** | `list_cron_executions`, `get_cron_execution` | — |
|
|
102
|
+
| **notifications** | `list_notification_channels` | `create_notification_channel`, `update_notification_channel`, `delete_notification_channel`, `test_notification_channel` |
|
|
103
|
+
| **alerts** | `list_alerts` | — |
|
|
104
|
+
| **activity-log** | `list_activity_log` | — |
|
|
105
|
+
| **meta** | `get_me` | — |
|
|
106
106
|
|
|
107
107
|
A few design notes worth knowing as a caller:
|
|
108
108
|
|
package/dist/hoststack-mcp.js
CHANGED
|
@@ -747,6 +747,36 @@ defineTool({
|
|
|
747
747
|
});
|
|
748
748
|
}
|
|
749
749
|
});
|
|
750
|
+
defineTool({
|
|
751
|
+
name: "upgrade_database_version",
|
|
752
|
+
category: "databases",
|
|
753
|
+
description: [
|
|
754
|
+
"Upgrade a standalone managed database (postgres or redis) to a newer engine version in place. The agent dumps the live data, recreates the container at the target version under the same DNS name, and restores \u2014 so connection URLs stay valid and services do NOT need a redeploy. The database is briefly unavailable (seconds) during the cut-over; on any failure the original container is rolled back automatically.",
|
|
755
|
+
"",
|
|
756
|
+
"`version` must be a supported, strictly-newer version for the engine (postgres: 18/17/16/15, redis: 8/7/6). Downgrades are rejected. Returns 400 for unsupported engines (mysql/mariadb/mongodb upgrades are not implemented yet), for HA (Patroni) clusters, or if the database is not currently `available`.",
|
|
757
|
+
"",
|
|
758
|
+
"When to use: a customer wants to move to a newer Postgres/Redis major version. Check get_database first \u2014 the `version` field shows the current version; compare against the engine latest.",
|
|
759
|
+
"",
|
|
760
|
+
"Inputs:",
|
|
761
|
+
" - database_id: publicId of the postgres/redis database to upgrade.",
|
|
762
|
+
' - version: target engine version (e.g. "18" for postgres, "8" for redis).',
|
|
763
|
+
"",
|
|
764
|
+
'Returns: 202 Accepted. The upgrade is async \u2014 poll get_database until `version` matches the target and `status === "available"` to confirm.',
|
|
765
|
+
"",
|
|
766
|
+
'Example: upgrade_database_version({ database_id: "db_abc", version: "18" }) \u2192 { ok: true }'
|
|
767
|
+
].join("\n"),
|
|
768
|
+
input: {
|
|
769
|
+
database_id: z5.string().describe("Database publicId (e.g. db_abc) to upgrade."),
|
|
770
|
+
version: z5.string().describe('Target engine version, e.g. "18" for postgres or "8" for redis.')
|
|
771
|
+
},
|
|
772
|
+
handler: async (args2, ctx) => {
|
|
773
|
+
const teamId = await ctx.resolveTeamId();
|
|
774
|
+
await ctx.hoststack.databases.upgradeVersion(teamId, args2.database_id, args2.version);
|
|
775
|
+
return respond({
|
|
776
|
+
summary: `Version upgrade to v${args2.version} started for ${args2.database_id}. Poll get_database until version=${args2.version} and status=available to confirm.`
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
});
|
|
750
780
|
defineTool({
|
|
751
781
|
name: "get_database_cluster",
|
|
752
782
|
category: "databases",
|
|
@@ -1986,7 +2016,9 @@ defineTool({
|
|
|
1986
2016
|
},
|
|
1987
2017
|
handler: async (args2, ctx) => {
|
|
1988
2018
|
const teamId = await ctx.resolveTeamId();
|
|
1989
|
-
const input = {
|
|
2019
|
+
const input = {
|
|
2020
|
+
name: args2.name
|
|
2021
|
+
};
|
|
1990
2022
|
if (args2.description !== void 0) input.description = args2.description;
|
|
1991
2023
|
if (args2.region !== void 0) input.region = args2.region;
|
|
1992
2024
|
const response = await ctx.hoststack.projects.create(teamId, input);
|
|
@@ -2062,7 +2094,7 @@ defineTool({
|
|
|
2062
2094
|
|
|
2063
2095
|
// src/tools/services.ts
|
|
2064
2096
|
import { z as z13 } from "zod";
|
|
2065
|
-
var DEV_ENV_IMAGE = "hoststack/dev-env:
|
|
2097
|
+
var DEV_ENV_IMAGE = "hoststack/dev-env:latest";
|
|
2066
2098
|
var DEV_ENV_VOLUME = { name: "workspace", mountPath: "/workspace", sizeGb: 10 };
|
|
2067
2099
|
var SERVICE_TYPES = [
|
|
2068
2100
|
"web_service",
|
|
@@ -2291,11 +2323,85 @@ defineTool({
|
|
|
2291
2323
|
const deploy = await ctx.hoststack.deploys.trigger(teamId, service.id);
|
|
2292
2324
|
const deployId = deploy.deploy?.id ?? null;
|
|
2293
2325
|
return respond({
|
|
2294
|
-
summary: `Created AI dev environment "${name}" (${service.publicId})${volumeAttached ? " with a /workspace volume" : ""} \u2014 deploying. Open
|
|
2326
|
+
summary: `Created AI dev environment "${name}" (${service.publicId})${volumeAttached ? " with a /workspace volume" : ""} \u2014 deploying. Open it in the dashboard's Development section (or the service's Terminal tab) once running.`,
|
|
2295
2327
|
data: { service: shapeService(service), volumeAttached, deployId }
|
|
2296
2328
|
});
|
|
2297
2329
|
}
|
|
2298
2330
|
});
|
|
2331
|
+
defineTool({
|
|
2332
|
+
name: "spin_up_dev_environment",
|
|
2333
|
+
category: "services",
|
|
2334
|
+
description: [
|
|
2335
|
+
"Spin up an agentic dev environment FROM an existing service so you can reproduce a bug, fix it, view it, and ship it. Creates a dev box (Claude/Codex/OpenCode + MCPs) that RUNS a clone of the app: the repo is auto-cloned into /workspace, the service env-vars are copied, and its linked database is cloned (so the box never touches the prod DB). The box gets an unguessable public dev URL and seamless `git push`.",
|
|
2336
|
+
"",
|
|
2337
|
+
'When to use: "spin up a dev environment for <service>", "I found a bug on <service>, give me a box to fix it". Distinct from create_dev_environment, which makes a BARE box not tied to any app.',
|
|
2338
|
+
"",
|
|
2339
|
+
"Inputs:",
|
|
2340
|
+
' - service_id: the source service to debug \u2014 numeric id or publicId ("svc_\u2026").',
|
|
2341
|
+
" - include_database_clone (optional): clone the linked database so the app runs on a copy of real data (default true).",
|
|
2342
|
+
' - name (optional): dev box name (default "<source>-dev").',
|
|
2343
|
+
"",
|
|
2344
|
+
"Returns: { service, devUrl, deployId }. Once it is live: open the Terminal tab, run `claude`, start the dev server (it must bind $PORT), and view the app at https://<devUrl>. Tear it all down later with delete_dev_environment.",
|
|
2345
|
+
"",
|
|
2346
|
+
'Example: spin_up_dev_environment({ service_id: "svc_api" }) \u2192 a dev box running a clone of the api service (repo + env-vars + cloned DB) with a public dev URL.'
|
|
2347
|
+
].join("\n"),
|
|
2348
|
+
input: {
|
|
2349
|
+
service_id: z13.union([z13.number().int().positive(), z13.string()]).describe("Source service to debug \u2014 numeric id or publicId."),
|
|
2350
|
+
include_database_clone: z13.boolean().optional().describe("Clone the linked database so the app runs on copied data (default true)."),
|
|
2351
|
+
name: z13.string().min(1).max(100).optional().describe('Dev box name (default "<source>-dev").')
|
|
2352
|
+
},
|
|
2353
|
+
handler: async (args2, ctx) => {
|
|
2354
|
+
const teamId = await ctx.resolveTeamId();
|
|
2355
|
+
const serviceId = await ctx.hoststack.resolveId(args2.service_id, {
|
|
2356
|
+
kind: "service",
|
|
2357
|
+
teamId
|
|
2358
|
+
});
|
|
2359
|
+
const opts = {};
|
|
2360
|
+
if (args2.include_database_clone !== void 0)
|
|
2361
|
+
opts.includeDatabaseClone = args2.include_database_clone;
|
|
2362
|
+
if (args2.name !== void 0) opts.name = args2.name;
|
|
2363
|
+
const result = await ctx.hoststack.services.spinUpDevEnvironment(teamId, serviceId, opts);
|
|
2364
|
+
return respond({
|
|
2365
|
+
summary: `Spun up dev environment "${result.service.name}" (${result.service.publicId}) \u2014 deploying. Once live: open the Terminal tab, run \`claude\`, start the dev server on $PORT, and view it at https://${result.devUrl}. \`git push\` works from inside.`,
|
|
2366
|
+
data: {
|
|
2367
|
+
service: shapeService(result.service),
|
|
2368
|
+
devUrl: result.devUrl,
|
|
2369
|
+
deployId: result.deployId
|
|
2370
|
+
}
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
});
|
|
2374
|
+
defineTool({
|
|
2375
|
+
name: "delete_dev_environment",
|
|
2376
|
+
category: "services",
|
|
2377
|
+
description: [
|
|
2378
|
+
"Tear down an agentic dev environment in one call: removes the dev box AND cascade-deletes its cloned database, its /workspace volume, and the auto-created `development` environment if it is now empty.",
|
|
2379
|
+
"",
|
|
2380
|
+
'When to use: "delete / tear down the dev environment", once you have shipped the fix and no longer need the box.',
|
|
2381
|
+
"",
|
|
2382
|
+
"Inputs:",
|
|
2383
|
+
" - service_id: the dev box to tear down \u2014 numeric id or publicId.",
|
|
2384
|
+
"",
|
|
2385
|
+
"Returns: { ok: true }. Irreversible \u2014 the cloned database and workspace volume are deleted.",
|
|
2386
|
+
"",
|
|
2387
|
+
'Example: delete_dev_environment({ service_id: "svc_api_dev" }) \u2192 removes the dev box, its cloned database, and the /workspace volume.'
|
|
2388
|
+
].join("\n"),
|
|
2389
|
+
input: {
|
|
2390
|
+
service_id: z13.union([z13.number().int().positive(), z13.string()]).describe("The dev box to tear down \u2014 numeric id or publicId.")
|
|
2391
|
+
},
|
|
2392
|
+
handler: async (args2, ctx) => {
|
|
2393
|
+
const teamId = await ctx.resolveTeamId();
|
|
2394
|
+
const serviceId = await ctx.hoststack.resolveId(args2.service_id, {
|
|
2395
|
+
kind: "service",
|
|
2396
|
+
teamId
|
|
2397
|
+
});
|
|
2398
|
+
await ctx.hoststack.services.tearDownDevEnvironment(teamId, serviceId);
|
|
2399
|
+
return respond({
|
|
2400
|
+
summary: "Dev environment torn down \u2014 box, cloned database, /workspace volume, and empty development environment removed.",
|
|
2401
|
+
data: { ok: true }
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
});
|
|
2299
2405
|
defineTool({
|
|
2300
2406
|
name: "get_service",
|
|
2301
2407
|
category: "services",
|