@hoststack.dev/mcp 0.13.0 → 0.13.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.
@@ -2259,7 +2259,7 @@ defineTool({
2259
2259
  "Inputs:",
2260
2260
  ' - project_id: numeric id or publicId ("prj_\u2026") of the target project.',
2261
2261
  ' - name (optional): service name (default "dev-environment").',
2262
- ' - plan (optional): service size (default "micro").',
2262
+ ' - plan (optional): service size (default "standard" \u2014 2 GB, the smallest that fits a coding agent + build).',
2263
2263
  " - disk_gb (optional): /workspace volume size in GB (default 10, 1\u2013100).",
2264
2264
  " - hoststack_api_key (optional): sets HOSTSTACK_API_KEY so the hoststack MCP works inside the container.",
2265
2265
  " - poststack_api_key (optional): sets POSTSTACK_API_KEY so the poststack MCP works inside the container.",
@@ -2272,7 +2272,9 @@ defineTool({
2272
2272
  input: {
2273
2273
  project_id: z13.union([z13.number().int().positive(), z13.string()]).describe("Target project \u2014 numeric id or publicId."),
2274
2274
  name: z13.string().min(1).max(100).optional().describe('Service name (default "dev-environment").'),
2275
- plan: z13.enum(SERVICE_PLANS).optional().describe('Service size (default "micro").'),
2275
+ plan: z13.enum(SERVICE_PLANS).optional().describe(
2276
+ 'Service size (default "standard" \u2014 2 GB; smallest that fits a coding agent).'
2277
+ ),
2276
2278
  disk_gb: z13.number().int().min(1).max(100).optional().describe("/workspace volume size in GB (default 10)."),
2277
2279
  hoststack_api_key: z13.string().optional().describe("Value for HOSTSTACK_API_KEY (enables the hoststack MCP in-container)."),
2278
2280
  poststack_api_key: z13.string().optional().describe("Value for POSTSTACK_API_KEY (enables the poststack MCP in-container)."),
@@ -2420,6 +2422,41 @@ defineTool({
2420
2422
  });
2421
2423
  }
2422
2424
  });
2425
+ defineTool({
2426
+ name: "resize_dev_environment",
2427
+ category: "services",
2428
+ description: [
2429
+ "Resize a dev box (or any service) to a different size tier \u2014 the supported way to give it more memory/CPU/disk headroom (e.g. when ESLint/tsc OOMs).",
2430
+ "",
2431
+ "When to use: a dev box OOM-killed (see exitReason/recommendedSize from list_dev_environments), or you just want more headroom. This changes the SIZE TIER \u2014 unlike per-config memory/CPU overrides, which are clamped to the current tier and so cannot grow a box past it.",
2432
+ "",
2433
+ "How it applies: the new tier's memory + CPU take effect LIVE on the running container (no recreate, no dropped shell sessions); a larger disk takes effect on the next recreate (suspend\u2192resume). Dev boxes are floored to the OOM-safe minimum size server-side.",
2434
+ "",
2435
+ "Inputs:",
2436
+ " - service_id: the box to resize \u2014 numeric id or publicId.",
2437
+ ' - size: target tier (e.g. "standard", "large", "xlarge").',
2438
+ "",
2439
+ "Returns: { service } with the new plan.",
2440
+ "",
2441
+ 'Example: resize_dev_environment({ service_id: "svc_skyskraber_dev", size: "large" }) \u2192 bumps the box to the large tier, applied live.'
2442
+ ].join("\n"),
2443
+ input: {
2444
+ service_id: z13.union([z13.number().int().positive(), z13.string()]).describe("The box to resize \u2014 numeric id or publicId."),
2445
+ size: z13.string().min(1).describe('Target size tier, e.g. "standard", "large", "xlarge".')
2446
+ },
2447
+ handler: async (args2, ctx) => {
2448
+ const teamId = await ctx.resolveTeamId();
2449
+ const serviceId = await ctx.hoststack.resolveId(args2.service_id, {
2450
+ kind: "service",
2451
+ teamId
2452
+ });
2453
+ const { service } = await ctx.hoststack.services.resize(teamId, serviceId, args2.size);
2454
+ return respond({
2455
+ summary: `Resized to ${service.plan} \u2014 memory/CPU applied live; disk grows on next recreate.`,
2456
+ data: { service: shapeService(service) }
2457
+ });
2458
+ }
2459
+ });
2423
2460
  defineTool({
2424
2461
  name: "list_dev_environments",
2425
2462
  category: "services",
@@ -2428,7 +2465,7 @@ defineTool({
2428
2465
  "",
2429
2466
  `When to use: "show my dev environments", before opening/tearing one down, to find a box's id.`,
2430
2467
  "",
2431
- 'Returns: { items: [{ ...service, devUrl, databases }] } where `databases` lists the companion engines wired into the box (e.g. ["postgres","redis"]).',
2468
+ 'Returns: { items: [{ ...service, devUrl, databases, exitReason, recommendedSize }] } where `databases` lists the companion engines wired into the box (e.g. ["postgres","redis"]). `exitReason` is "oom_killed" / "crashed" / null for the box\'s last container exit; when it is "oom_killed", `recommendedSize` is the next tier up to rescale to (use resize_dev_environment).',
2432
2469
  "",
2433
2470
  "Example: list_dev_environments() \u2192 every dev box for the active team."
2434
2471
  ].join("\n"),
@@ -2436,13 +2473,16 @@ defineTool({
2436
2473
  handler: async (_args, ctx) => {
2437
2474
  const teamId = await ctx.resolveTeamId();
2438
2475
  const { environments } = await ctx.hoststack.services.listDevEnvironments(teamId);
2476
+ const oomCount = environments.filter((e) => e.exitReason === "oom_killed").length;
2439
2477
  return respond({
2440
- summary: `${environments.length} dev environment${environments.length === 1 ? "" : "s"}.`,
2478
+ summary: `${environments.length} dev environment${environments.length === 1 ? "" : "s"}.` + (oomCount > 0 ? ` ${oomCount} recently OOM-killed \u2014 consider resize_dev_environment.` : ""),
2441
2479
  data: {
2442
2480
  items: environments.map((env) => ({
2443
2481
  ...shapeService(env),
2444
2482
  devUrl: env.devUrl ?? null,
2445
- databases: env.databases ?? []
2483
+ databases: env.databases ?? [],
2484
+ exitReason: env.exitReason ?? null,
2485
+ recommendedSize: env.recommendedSize ?? null
2446
2486
  }))
2447
2487
  }
2448
2488
  });
@@ -2464,6 +2504,7 @@ defineTool({
2464
2504
  " - branch (optional): branch to clone.",
2465
2505
  ' - databases (optional): companion services to attach \u2014 any of "postgres", "redis", "meilisearch".',
2466
2506
  ' - plan (optional): box size (default "micro").',
2507
+ " - agent_accounts (optional): bind specific saved agent logins by account id per provider. OMIT to auto-inherit the box owner's default logins (claude/codex/opencode), so `claude` is already authenticated on first boot \u2014 no manual login.",
2467
2508
  "",
2468
2509
  "Returns: { service, devUrl, deployId } \u2014 deploying. Once live: open the Terminal tab, run `claude`, start the dev server on $PORT, view at https://<devUrl>. Tear down with delete_dev_environment.",
2469
2510
  "",
@@ -2476,7 +2517,15 @@ defineTool({
2476
2517
  clone_url: z13.string().url().optional().describe('http(s) git clone URL (required when source_kind="url").'),
2477
2518
  branch: z13.string().min(1).max(255).optional().describe("Branch to clone."),
2478
2519
  databases: z13.array(z13.enum(["postgres", "redis", "meilisearch"])).optional().describe("Companion services to attach (fresh + empty)."),
2479
- plan: z13.enum(SERVICE_PLANS).optional().describe('Box size (default "micro").')
2520
+ plan: z13.enum(SERVICE_PLANS).optional().describe('Box size (default "micro").'),
2521
+ agent_accounts: z13.array(
2522
+ z13.object({
2523
+ provider: z13.enum(["claude", "codex", "opencode"]),
2524
+ account_id: z13.number().int().positive()
2525
+ })
2526
+ ).max(3).optional().describe(
2527
+ "Bind saved agent logins by account id per provider. Omit to inherit the box owner's default logins automatically."
2528
+ )
2480
2529
  },
2481
2530
  handler: async (args2, ctx) => {
2482
2531
  const teamId = await ctx.resolveTeamId();
@@ -2512,7 +2561,13 @@ defineTool({
2512
2561
  name: args2.name,
2513
2562
  source,
2514
2563
  ...args2.databases ? { databases: args2.databases } : {},
2515
- ...args2.plan ? { plan: args2.plan } : {}
2564
+ ...args2.plan ? { plan: args2.plan } : {},
2565
+ ...args2.agent_accounts && args2.agent_accounts.length > 0 ? {
2566
+ agentAccounts: args2.agent_accounts.map((a) => ({
2567
+ provider: a.provider,
2568
+ accountId: a.account_id
2569
+ }))
2570
+ } : {}
2516
2571
  };
2517
2572
  const result = await ctx.hoststack.services.createDevEnvironment(teamId, input);
2518
2573
  return respond({