@hoststack.dev/mcp 0.20.0 → 0.21.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 -4
- package/dist/hoststack-mcp.js.map +1 -1
- package/dist/index.js +24 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import { HostStack } from "@hoststack.dev/sdk";
|
|
4
4
|
|
|
5
5
|
// src/version.ts
|
|
6
|
-
var MCP_VERSION = true ? "0.
|
|
6
|
+
var MCP_VERSION = true ? "0.21.0" : "0.0.0-dev";
|
|
7
7
|
var USER_AGENT = `hoststack-mcp/${MCP_VERSION}`;
|
|
8
8
|
|
|
9
9
|
// src/api-client.ts
|
|
@@ -3459,6 +3459,8 @@ defineTool({
|
|
|
3459
3459
|
' - task_id: "task_\u2026" publicId or numeric id.',
|
|
3460
3460
|
' - status: "done" or "idea". Only these two; `queued`/`running`/`failed`/`cancelled` belong to the runner and are rejected.',
|
|
3461
3461
|
" - title / body / service_id: optional edits.",
|
|
3462
|
+
' - provider: which agent runs it \u2014 "claude", "codex" or "opencode". null clears the pin and lets the box decide.',
|
|
3463
|
+
' - permission_mode: how that agent is allowed to act \u2014 "default" (ask before acting), "acceptEdits" (edit files without asking) or "bypassPermissions" (no prompts at all). Only set bypassPermissions when the person asked for it: it is the box-wide yolo setting scoped to one task.',
|
|
3462
3464
|
"",
|
|
3463
3465
|
"Only mark a task done when it is actually resolved - the backlog is what someone reads to decide what still needs doing.",
|
|
3464
3466
|
"",
|
|
@@ -3471,7 +3473,11 @@ defineTool({
|
|
|
3471
3473
|
status: z17.enum(["idea", "done"]).optional().describe("The only two a person may set. The runner owns the rest of the lifecycle."),
|
|
3472
3474
|
title: z17.string().min(1).max(200).optional().describe("New title."),
|
|
3473
3475
|
body: z17.string().max(2e4).optional().describe("New prompt body."),
|
|
3474
|
-
service_id: z17.union([z17.number().int().positive(), z17.string()]).nullable().optional().describe("Pin to a dev box, or null to unpin it back to a loose idea.")
|
|
3476
|
+
service_id: z17.union([z17.number().int().positive(), z17.string()]).nullable().optional().describe("Pin to a dev box, or null to unpin it back to a loose idea."),
|
|
3477
|
+
provider: z17.enum(["claude", "codex", "opencode"]).nullable().optional().describe("Which agent runs this task, or null to leave it to the box."),
|
|
3478
|
+
permission_mode: z17.enum(["acceptEdits", "bypassPermissions", "default"]).optional().describe(
|
|
3479
|
+
"How the agent may act. bypassPermissions asks for nothing \u2014 set it only on request."
|
|
3480
|
+
)
|
|
3475
3481
|
},
|
|
3476
3482
|
handler: async (args, ctx) => {
|
|
3477
3483
|
const teamId = await ctx.resolveTeamId();
|
|
@@ -3480,7 +3486,10 @@ defineTool({
|
|
|
3480
3486
|
...args.status ? { status: args.status } : {},
|
|
3481
3487
|
...args.title ? { title: args.title } : {},
|
|
3482
3488
|
...args.body !== void 0 ? { body: args.body } : {},
|
|
3483
|
-
...serviceId !== void 0 ? { serviceId } : {}
|
|
3489
|
+
...serviceId !== void 0 ? { serviceId } : {},
|
|
3490
|
+
// null is meaningful on provider (unpin), so compare to undefined.
|
|
3491
|
+
...args.provider !== void 0 ? { provider: args.provider } : {},
|
|
3492
|
+
...args.permission_mode !== void 0 ? { permissionMode: args.permission_mode } : {}
|
|
3484
3493
|
});
|
|
3485
3494
|
const data = shape(response.task);
|
|
3486
3495
|
return respond({
|
|
@@ -4675,6 +4684,8 @@ defineTool({
|
|
|
4675
4684
|
" - instance_count (optional): integer 1\u201350 \u2014 pin both min and max instances to this value.",
|
|
4676
4685
|
" - min_instances, max_instances (optional): integers \u2014 autoscale bounds. Use instead of instance_count when you want a range.",
|
|
4677
4686
|
" - scale_cpu_threshold, scale_memory_threshold (optional): integer 10\u2013100 \u2014 autoscale trigger percentage.",
|
|
4687
|
+
" - scale_requests_per_sec_threshold (optional): integer 1\u201310000 \u2014 autoscale on request rate instead of (or alongside) CPU and memory. Pass null to stop scaling on request rate.",
|
|
4688
|
+
" - build_timeout_seconds (optional): integer 60\u20131800 \u2014 how long a build may run before it is killed. Raise it for a service whose build legitimately takes longer than the default; pass null to go back to the default.",
|
|
4678
4689
|
` - log_filter_rules (optional): list of { pattern, action } rules applied at read time \u2014 to get_service_logs (tail AND count) and to the dashboard's live stream alike. Pattern matches the message by case-insensitive substring, literally (a % or _ is not a wildcard); action is "drop" (filter out) or "downgrade" (flip stderr \u2192 stdout so it stops looking like an error). Stored lines are never altered, so removing a rule re-exposes everything it was hiding. Pass [] to clear all rules. Capped at 50 rules.`,
|
|
4679
4690
|
"",
|
|
4680
4691
|
"Returns: { service?: Service, config?: ServiceConfig } \u2014 whichever rows were touched.",
|
|
@@ -4715,6 +4726,8 @@ defineTool({
|
|
|
4715
4726
|
max_instances: z19.number().int().min(1).max(50).optional().describe("Autoscale upper bound. Use with min_instances for a range."),
|
|
4716
4727
|
scale_cpu_threshold: z19.number().int().min(10).max(100).optional().describe("Autoscale CPU trigger percentage (10\u2013100)."),
|
|
4717
4728
|
scale_memory_threshold: z19.number().int().min(10).max(100).optional().describe("Autoscale memory trigger percentage (10\u2013100)."),
|
|
4729
|
+
scale_requests_per_sec_threshold: z19.number().int().min(1).max(1e4).nullable().optional().describe("Autoscale request-rate trigger (1\u201310000 req/s). null stops using it."),
|
|
4730
|
+
build_timeout_seconds: z19.number().int().min(60).max(1800).nullable().optional().describe("Kill a build that runs longer than this (60\u20131800s). null = default."),
|
|
4718
4731
|
log_filter_rules: z19.array(
|
|
4719
4732
|
z19.object({
|
|
4720
4733
|
pattern: z19.string().min(1).max(200),
|
|
@@ -4769,6 +4782,10 @@ defineTool({
|
|
|
4769
4782
|
configUpdate["scaleCpuThreshold"] = args.scale_cpu_threshold;
|
|
4770
4783
|
if (args.scale_memory_threshold !== void 0)
|
|
4771
4784
|
configUpdate["scaleMemoryThreshold"] = args.scale_memory_threshold;
|
|
4785
|
+
if (args.scale_requests_per_sec_threshold !== void 0)
|
|
4786
|
+
configUpdate["scaleRequestsPerSecThreshold"] = args.scale_requests_per_sec_threshold;
|
|
4787
|
+
if (args.build_timeout_seconds !== void 0)
|
|
4788
|
+
configUpdate["buildTimeoutSeconds"] = args.build_timeout_seconds;
|
|
4772
4789
|
if (args.log_filter_rules !== void 0) {
|
|
4773
4790
|
configUpdate["logFilterRules"] = args.log_filter_rules;
|
|
4774
4791
|
}
|
|
@@ -5219,6 +5236,7 @@ defineTool({
|
|
|
5219
5236
|
" - volume_id: publicId of the volume to update.",
|
|
5220
5237
|
" - mount_path (optional): new in-container mount path.",
|
|
5221
5238
|
" - size_gb (optional): new size in GB (must be \u2265 current).",
|
|
5239
|
+
" - backup_enabled (optional): whether this volume is backed up. Turning it off stops future backups; it does not delete the ones already taken.",
|
|
5222
5240
|
"",
|
|
5223
5241
|
"Returns: { volume: Volume } \u2014 the updated record.",
|
|
5224
5242
|
"",
|
|
@@ -5228,13 +5246,15 @@ defineTool({
|
|
|
5228
5246
|
service_id: z21.string().describe("Service publicId."),
|
|
5229
5247
|
volume_id: z21.string().describe("Volume publicId (e.g. vol_\u2026)."),
|
|
5230
5248
|
mount_path: z21.string().startsWith("/").max(500).optional().describe("New mount path."),
|
|
5231
|
-
size_gb: z21.number().int().min(MIN_VOLUME_SIZE_GB).max(100).optional().describe(`New size in GB (minimum ${MIN_VOLUME_SIZE_GB}, grow-only).`)
|
|
5249
|
+
size_gb: z21.number().int().min(MIN_VOLUME_SIZE_GB).max(100).optional().describe(`New size in GB (minimum ${MIN_VOLUME_SIZE_GB}, grow-only).`),
|
|
5250
|
+
backup_enabled: z21.boolean().optional().describe("Whether to keep backing this volume up. Past backups are kept either way.")
|
|
5232
5251
|
},
|
|
5233
5252
|
handler: async (args, ctx) => {
|
|
5234
5253
|
const teamId = await ctx.resolveTeamId();
|
|
5235
5254
|
const input = {};
|
|
5236
5255
|
if (args.mount_path !== void 0) input.mountPath = args.mount_path;
|
|
5237
5256
|
if (args.size_gb !== void 0) input.sizeGb = args.size_gb;
|
|
5257
|
+
if (args.backup_enabled !== void 0) input.backupEnabled = args.backup_enabled;
|
|
5238
5258
|
if (Object.keys(input).length === 0) {
|
|
5239
5259
|
return respond({ summary: "No fields to update.", data: {} });
|
|
5240
5260
|
}
|