@hoststack.dev/mcp 0.6.0 → 0.6.1

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 CHANGED
@@ -79,22 +79,24 @@ If `HOSTSTACK_API_KEY` is set in your shell, it gets baked into the snippet; oth
79
79
 
80
80
  ## Tool inventory
81
81
 
82
- 45 tools, grouped by resource:
83
-
84
- | Category | Read | Write |
85
- | ---------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
86
- | **projects** | `list_projects`, `get_project` | `create_project`, `update_project` |
87
- | **services** | `list_services`, `get_service`, `get_service_metrics`, `get_service_logs` | `update_service`, `update_service_config`, `suspend_service`, `resume_service` |
88
- | **deploys** | `list_deploys`, `get_deploy`, `get_deploy_logs` | `trigger_deploy`, `cancel_deploy` |
89
- | **environments** | `list_environments` | `create_environment`, `delete_environment`, `promote_deploy` |
90
- | **databases** | `list_databases`, `get_database` | (use the dashboard for create/delete/credentials) |
91
- | **volumes** | `list_volumes` | `create_volume`, `update_volume`, `delete_volume` |
92
- | **domains** | `list_domains` | `add_domain`, `verify_domain`, `remove_domain` |
93
- | **dns** | `list_dns_zones`, `list_dns_records`, `get_dns_record` | `create_dns_record`, `update_dns_record`, `delete_dns_record` |
94
- | **env-vars** | `list_env_vars` | `set_env_var`, `delete_env_var`, `bulk_set_env_vars` |
95
- | **cron** | `list_cron_executions`, `get_cron_execution` | — |
96
- | **activity-log** | `list_activity_log` | |
97
- | **meta** | `get_me` | — |
82
+ 55 tools, grouped by resource:
83
+
84
+ | Category | Read | Write |
85
+ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
86
+ | **projects** | `list_projects`, `get_project` | `create_project`, `update_project` |
87
+ | **services** | `list_services`, `get_service`, `get_service_metrics`, `get_service_metrics_history`, `get_service_logs`, `get_service_logs_bulk` | `update_service`, `update_service_config`, `suspend_service`, `resume_service` |
88
+ | **deploys** | `list_deploys`, `get_deploy`, `get_deploy_logs`, `diagnose_deploy` | `trigger_deploy`, `cancel_deploy` |
89
+ | **environments** | `list_environments` | `create_environment`, `delete_environment`, `promote_deploy` |
90
+ | **databases** | `list_databases`, `get_database` | `update_database` (use the dashboard for create/delete/credentials) |
91
+ | **volumes** | `list_volumes` | `create_volume`, `update_volume`, `delete_volume` |
92
+ | **domains** | `list_domains` | `add_domain`, `verify_domain`, `remove_domain` |
93
+ | **dns** | `list_dns_zones`, `list_dns_records`, `get_dns_record` | `create_dns_record`, `update_dns_record`, `delete_dns_record` |
94
+ | **env-vars** | `list_env_vars` | `set_env_var`, `delete_env_var`, `bulk_set_env_vars` |
95
+ | **cron** | `list_cron_executions`, `get_cron_execution` | — |
96
+ | **notifications** | `list_notification_channels` | `create_notification_channel`, `update_notification_channel`, `delete_notification_channel`, `test_notification_channel` |
97
+ | **alerts** | `list_alerts` | — |
98
+ | **activity-log** | `list_activity_log` | — |
99
+ | **meta** | `get_me` | — |
98
100
 
99
101
  A few design notes worth knowing as a caller:
100
102
 
@@ -2004,24 +2004,30 @@ defineTool({
2004
2004
  name: "get_service",
2005
2005
  category: "services",
2006
2006
  description: [
2007
- "Fetch a single service by ID, including its current status and configuration summary.",
2007
+ "Fetch a single service by ID with its current status AND its service_config row (resources, health-check tuning, scaling, restart policy).",
2008
2008
  "",
2009
- "When to use: drilling into a service after list_services, checking deploy/runtime status, or grabbing the repo+branch before triggering a deploy.",
2009
+ "When to use: drilling into a service after list_services, checking deploy/runtime status, grabbing the repo+branch before triggering a deploy, or inspecting the health-check / autoscale knobs before tweaking them via update_service_config.",
2010
2010
  "",
2011
2011
  "Inputs:",
2012
2012
  ' - service_id: publicId of the service (e.g. "svc_abc123").',
2013
2013
  "",
2014
- "Returns: { service: Service } \u2014 type, status, runtime, repoUrl, branch, autoDeploy, region, plan, createdAt, updatedAt.",
2014
+ "Returns: { service: Service, config: ServiceConfig } \u2014 service has type/status/runtime/repoUrl/branch/autoDeploy/region/plan/timestamps; config has memoryMb, cpuShares, diskSizeGb, port, protocol, healthCheckEnabled, healthCheckInterval, healthCheckTimeout, healthCheckGracePeriodSec, restartPolicy, preDeployCommand, min/maxInstances, scale thresholds.",
2015
2015
  "",
2016
- 'Example: get_service({ service_id: "svc_abc" }) \u2192 { service: { type: "web", status: "running", \u2026 } }'
2016
+ 'Example: get_service({ service_id: "svc_abc" }) \u2192 { service: { type: "web", status: "running", \u2026 }, config: { healthCheckGracePeriodSec: 120, \u2026 } }'
2017
2017
  ].join("\n"),
2018
2018
  input: {
2019
2019
  service_id: z13.string().describe("Service publicId (e.g. svc_abc123).")
2020
2020
  },
2021
2021
  handler: async (args2, ctx) => {
2022
2022
  const teamId = await ctx.resolveTeamId();
2023
- const response = await ctx.hoststack.services.get(teamId, args2.service_id);
2024
- const data = { service: shapeService(response.service) };
2023
+ const [serviceResponse, configResponse] = await Promise.all([
2024
+ ctx.hoststack.services.get(teamId, args2.service_id),
2025
+ ctx.hoststack.services.getConfig(teamId, args2.service_id)
2026
+ ]);
2027
+ const data = {
2028
+ service: shapeService(serviceResponse.service),
2029
+ config: shape(configResponse.config)
2030
+ };
2025
2031
  const status = data.service && "status" in data.service ? data.service.status : "unknown";
2026
2032
  return respond({ summary: `Service ${args2.service_id} is ${status}.`, data });
2027
2033
  }
@@ -2133,9 +2139,9 @@ defineTool({
2133
2139
  name: "update_service_config",
2134
2140
  category: "services",
2135
2141
  description: [
2136
- "Update build/runtime configuration for a service: build command, start command, install command, branch, root directory, dockerfile path, auto-deploy flag, instance count. All fields optional \u2014 pass only what you want to change.",
2142
+ "Update build/runtime configuration for a service. All fields optional \u2014 pass only what you want to change.",
2137
2143
  "",
2138
- "When to use: the user wants to tweak how a service builds or runs. Build/runtime fields (branch, install/build/start command, root, dockerfile) take effect on the next deploy \u2014 call trigger_deploy after if you need them applied immediately. instance_count rescales without a redeploy.",
2144
+ "When to use: the user wants to tweak how a service builds, runs, scales, or health-checks. Build/runtime fields (branch, install/build/start command, root, dockerfile) take effect on the next deploy \u2014 call trigger_deploy after if you need them applied immediately. Instance_count, resource and health-check changes rescale or rewire without a redeploy.",
2139
2145
  "",
2140
2146
  "Inputs:",
2141
2147
  " - service_id: publicId of the service.",
@@ -2144,12 +2150,26 @@ defineTool({
2144
2150
  " - root_directory (optional): build context root inside the repo.",
2145
2151
  " - dockerfile_path (optional): path to Dockerfile relative to root_directory. Pass null to clear.",
2146
2152
  " - auto_deploy (optional): boolean \u2014 auto-deploy on git push.",
2147
- " - instance_count (optional): integer \u22651 \u2014 pin both min and max instances to this value.",
2153
+ ' - health_check_path (optional): HTTP path the platform GETs to verify liveness (e.g. "/health"). Pass null for TCP-only check.',
2154
+ " - health_check_enabled (optional): boolean \u2014 toggle health checking on/off.",
2155
+ " - health_check_interval (optional): integer 5\u2013300 seconds \u2014 how often the check runs.",
2156
+ " - health_check_timeout (optional): integer 1\u201360 seconds \u2014 single-attempt timeout.",
2157
+ ' - health_check_grace_period_sec (optional): integer 1\u20131800 seconds \u2014 startup tolerance before failures count. RAISE THIS (e.g. 180) when the agent reports "Health check timed out" on a cold-boot app (Bun + Vite SSR typically need 90\u2013180s).',
2158
+ " - memory_mb (optional): integer 128\u201316384 \u2014 container memory cap.",
2159
+ " - cpu_shares (optional): integer 128\u20134096 \u2014 relative CPU weight.",
2160
+ " - disk_size_gb (optional): integer 1\u2013100 \u2014 ephemeral disk cap.",
2161
+ " - port (optional): integer 1\u201365535 \u2014 container port the platform forwards traffic to.",
2162
+ ' - protocol (optional): "http" | "tcp".',
2163
+ ' - restart_policy (optional): "always" | "on-failure" | "no".',
2164
+ " - pre_deploy_command (optional): shell command run before the new release accepts traffic (typical use: migrations).",
2165
+ " - instance_count (optional): integer 1\u201350 \u2014 pin both min and max instances to this value.",
2166
+ " - min_instances, max_instances (optional): integers \u2014 autoscale bounds. Use instead of instance_count when you want a range.",
2167
+ " - scale_cpu_threshold, scale_memory_threshold (optional): integer 10\u2013100 \u2014 autoscale trigger percentage.",
2148
2168
  ' - log_filter_rules (optional): list of { pattern, action } rules applied to runtime logs at query time. Pattern matches the message by case-insensitive substring; action is "drop" (filter out) or "downgrade" (flip stderr \u2192 stdout so it stops looking like an error). Pass [] to clear all rules. Capped at 50 rules.',
2149
2169
  "",
2150
2170
  "Returns: { service?: Service, config?: ServiceConfig } \u2014 whichever rows were touched.",
2151
2171
  "",
2152
- 'Example: update_service_config({ service_id: "svc_abc", start_command: "bun apps/api/src/index.ts" }) \u2192 { service: { startCommand: "bun apps/api/src/index.ts", \u2026 } }'
2172
+ 'Example: update_service_config({ service_id: "svc_abc", health_check_grace_period_sec: 180 }) \u2192 { config: { healthCheckGracePeriodSec: 180, \u2026 } }'
2153
2173
  ].join("\n"),
2154
2174
  input: {
2155
2175
  service_id: z13.string().describe("Service publicId."),
@@ -2160,7 +2180,25 @@ defineTool({
2160
2180
  root_directory: z13.string().optional().describe("Build context root."),
2161
2181
  dockerfile_path: z13.string().nullable().optional().describe("Path to Dockerfile relative to root. Null clears."),
2162
2182
  auto_deploy: z13.boolean().optional().describe("Auto-deploy on push."),
2183
+ health_check_path: z13.string().nullable().optional().describe('HTTP health-check path (e.g. "/health"). Null = TCP-only check.'),
2184
+ health_check_enabled: z13.boolean().optional().describe("Toggle health checking on/off."),
2185
+ health_check_interval: z13.number().int().min(5).max(300).optional().describe("How often the check runs, in seconds (5\u2013300)."),
2186
+ health_check_timeout: z13.number().int().min(1).max(60).optional().describe("Single-attempt timeout in seconds (1\u201360)."),
2187
+ health_check_grace_period_sec: z13.number().int().min(1).max(1800).optional().describe(
2188
+ "Startup grace period in seconds (1\u20131800). Raise this if the app needs more time to boot before health checks start counting failures."
2189
+ ),
2190
+ memory_mb: z13.number().int().min(128).max(16384).optional().describe("Container memory cap in MB (128\u201316384)."),
2191
+ cpu_shares: z13.number().int().min(128).max(4096).optional().describe("Relative CPU weight (128\u20134096)."),
2192
+ disk_size_gb: z13.number().int().min(1).max(100).optional().describe("Ephemeral disk size in GB (1\u2013100)."),
2193
+ port: z13.number().int().min(1).max(65535).optional().describe("Container port the platform forwards traffic to."),
2194
+ protocol: z13.enum(["http", "tcp"]).optional().describe("Traffic protocol."),
2195
+ restart_policy: z13.enum(["always", "on-failure", "no"]).optional().describe("Docker restart policy."),
2196
+ pre_deploy_command: z13.string().optional().describe("Shell command run before the new release accepts traffic."),
2163
2197
  instance_count: z13.number().int().positive().max(50).optional().describe("Pin min and max instances to this value (1\u201350)."),
2198
+ min_instances: z13.number().int().min(0).max(50).optional().describe("Autoscale lower bound. Use with max_instances for a range."),
2199
+ max_instances: z13.number().int().min(1).max(50).optional().describe("Autoscale upper bound. Use with min_instances for a range."),
2200
+ scale_cpu_threshold: z13.number().int().min(10).max(100).optional().describe("Autoscale CPU trigger percentage (10\u2013100)."),
2201
+ scale_memory_threshold: z13.number().int().min(10).max(100).optional().describe("Autoscale memory trigger percentage (10\u2013100)."),
2164
2202
  log_filter_rules: z13.array(
2165
2203
  z13.object({
2166
2204
  pattern: z13.string().min(1).max(200),
@@ -2182,11 +2220,35 @@ defineTool({
2182
2220
  if (args2.branch !== void 0) serviceUpdate["branch"] = args2.branch;
2183
2221
  if (args2.root_directory !== void 0) serviceUpdate["rootDirectory"] = args2.root_directory;
2184
2222
  if (args2.auto_deploy !== void 0) serviceUpdate["autoDeploy"] = args2.auto_deploy;
2223
+ if (args2.health_check_path !== void 0)
2224
+ serviceUpdate["healthCheckPath"] = args2.health_check_path;
2185
2225
  const configUpdate = {};
2226
+ if (args2.health_check_enabled !== void 0)
2227
+ configUpdate["healthCheckEnabled"] = args2.health_check_enabled;
2228
+ if (args2.health_check_interval !== void 0)
2229
+ configUpdate["healthCheckInterval"] = args2.health_check_interval;
2230
+ if (args2.health_check_timeout !== void 0)
2231
+ configUpdate["healthCheckTimeout"] = args2.health_check_timeout;
2232
+ if (args2.health_check_grace_period_sec !== void 0)
2233
+ configUpdate["healthCheckGracePeriodSec"] = args2.health_check_grace_period_sec;
2234
+ if (args2.memory_mb !== void 0) configUpdate["memoryMb"] = args2.memory_mb;
2235
+ if (args2.cpu_shares !== void 0) configUpdate["cpuShares"] = args2.cpu_shares;
2236
+ if (args2.disk_size_gb !== void 0) configUpdate["diskSizeGb"] = args2.disk_size_gb;
2237
+ if (args2.port !== void 0) configUpdate["port"] = args2.port;
2238
+ if (args2.protocol !== void 0) configUpdate["protocol"] = args2.protocol;
2239
+ if (args2.restart_policy !== void 0) configUpdate["restartPolicy"] = args2.restart_policy;
2240
+ if (args2.pre_deploy_command !== void 0)
2241
+ configUpdate["preDeployCommand"] = args2.pre_deploy_command;
2186
2242
  if (args2.instance_count !== void 0) {
2187
2243
  configUpdate["minInstances"] = args2.instance_count;
2188
2244
  configUpdate["maxInstances"] = args2.instance_count;
2189
2245
  }
2246
+ if (args2.min_instances !== void 0) configUpdate["minInstances"] = args2.min_instances;
2247
+ if (args2.max_instances !== void 0) configUpdate["maxInstances"] = args2.max_instances;
2248
+ if (args2.scale_cpu_threshold !== void 0)
2249
+ configUpdate["scaleCpuThreshold"] = args2.scale_cpu_threshold;
2250
+ if (args2.scale_memory_threshold !== void 0)
2251
+ configUpdate["scaleMemoryThreshold"] = args2.scale_memory_threshold;
2190
2252
  if (args2.log_filter_rules !== void 0) {
2191
2253
  configUpdate["logFilterRules"] = args2.log_filter_rules;
2192
2254
  }