@hoststack.dev/mcp 0.11.0 → 0.13.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 +127 -4
- package/dist/hoststack-mcp.js.map +1 -1
- package/dist/index.js +127 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1974,7 +1974,7 @@ defineTool({
|
|
|
1974
1974
|
|
|
1975
1975
|
// src/tools/projects.ts
|
|
1976
1976
|
import { z as z12 } from "zod";
|
|
1977
|
-
var
|
|
1977
|
+
var AVAILABLE_REGION_IDS = ["eu-central-1"];
|
|
1978
1978
|
defineTool({
|
|
1979
1979
|
name: "list_projects",
|
|
1980
1980
|
category: "projects",
|
|
@@ -2007,7 +2007,7 @@ defineTool({
|
|
|
2007
2007
|
"Inputs:",
|
|
2008
2008
|
" - name: human-readable project name (1\u201360 chars).",
|
|
2009
2009
|
" - description (optional): short blurb shown in the dashboard.",
|
|
2010
|
-
' - region (optional): "eu-central-1" (Falkenstein)
|
|
2010
|
+
' - region (optional): "eu-central-1" (Falkenstein). Currently the only region with available capacity; defaults to eu-central-1.',
|
|
2011
2011
|
"",
|
|
2012
2012
|
"Returns: { project: Project } \u2014 includes the new id and publicId.",
|
|
2013
2013
|
"",
|
|
@@ -2016,7 +2016,7 @@ defineTool({
|
|
|
2016
2016
|
input: {
|
|
2017
2017
|
name: z12.string().min(1).max(60).describe("Project name (1\u201360 chars)."),
|
|
2018
2018
|
description: z12.string().max(500).optional().describe("Short description (\u2264500 chars)."),
|
|
2019
|
-
region: z12.enum(
|
|
2019
|
+
region: z12.enum(AVAILABLE_REGION_IDS).optional().describe("Region: eu-central-1 (Falkenstein) \u2014 currently the only available region.")
|
|
2020
2020
|
},
|
|
2021
2021
|
handler: async (args, ctx) => {
|
|
2022
2022
|
const teamId = await ctx.resolveTeamId();
|
|
@@ -2267,6 +2267,7 @@ defineTool({
|
|
|
2267
2267
|
" - disk_gb (optional): /workspace volume size in GB (default 10, 1\u2013100).",
|
|
2268
2268
|
" - hoststack_api_key (optional): sets HOSTSTACK_API_KEY so the hoststack MCP works inside the container.",
|
|
2269
2269
|
" - poststack_api_key (optional): sets POSTSTACK_API_KEY so the poststack MCP works inside the container.",
|
|
2270
|
+
" - repo_url (optional): clone this git URL into /workspace on first boot (with optional branch).",
|
|
2270
2271
|
"",
|
|
2271
2272
|
"Returns: { service: Service, volumeAttached: boolean, deployId: number | null }. Open the Terminal tab on the service (dashboard or phone) once it is running; log in once with `claude /login` inside the container.",
|
|
2272
2273
|
"",
|
|
@@ -2278,7 +2279,11 @@ defineTool({
|
|
|
2278
2279
|
plan: z13.enum(SERVICE_PLANS).optional().describe('Service size (default "micro").'),
|
|
2279
2280
|
disk_gb: z13.number().int().min(1).max(100).optional().describe("/workspace volume size in GB (default 10)."),
|
|
2280
2281
|
hoststack_api_key: z13.string().optional().describe("Value for HOSTSTACK_API_KEY (enables the hoststack MCP in-container)."),
|
|
2281
|
-
poststack_api_key: z13.string().optional().describe("Value for POSTSTACK_API_KEY (enables the poststack MCP in-container).")
|
|
2282
|
+
poststack_api_key: z13.string().optional().describe("Value for POSTSTACK_API_KEY (enables the poststack MCP in-container)."),
|
|
2283
|
+
repo_url: z13.string().max(500).optional().describe(
|
|
2284
|
+
"Clone this git URL into /workspace on first boot (HTTPS, or SSH once a key is set)."
|
|
2285
|
+
),
|
|
2286
|
+
branch: z13.string().max(200).optional().describe("Branch to clone (with repo_url).")
|
|
2282
2287
|
},
|
|
2283
2288
|
handler: async (args, ctx) => {
|
|
2284
2289
|
const teamId = await ctx.resolveTeamId();
|
|
@@ -2311,6 +2316,19 @@ defineTool({
|
|
|
2311
2316
|
value: args.poststack_api_key,
|
|
2312
2317
|
isSecret: true
|
|
2313
2318
|
});
|
|
2319
|
+
if (args.repo_url) {
|
|
2320
|
+
envVars.push({
|
|
2321
|
+
key: "HOSTSTACK_DEVENV_REPO_URL",
|
|
2322
|
+
value: args.repo_url,
|
|
2323
|
+
isSecret: false
|
|
2324
|
+
});
|
|
2325
|
+
if (args.branch)
|
|
2326
|
+
envVars.push({
|
|
2327
|
+
key: "HOSTSTACK_DEVENV_BRANCH",
|
|
2328
|
+
value: args.branch,
|
|
2329
|
+
isSecret: false
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2314
2332
|
if (envVars.length > 0) {
|
|
2315
2333
|
await ctx.hoststack.envVars.bulkSet(teamId, service.id, { vars: envVars });
|
|
2316
2334
|
}
|
|
@@ -2406,6 +2424,111 @@ defineTool({
|
|
|
2406
2424
|
});
|
|
2407
2425
|
}
|
|
2408
2426
|
});
|
|
2427
|
+
defineTool({
|
|
2428
|
+
name: "list_dev_environments",
|
|
2429
|
+
category: "services",
|
|
2430
|
+
description: [
|
|
2431
|
+
`List the team's dev environments (the dashboard "Development" section), each annotated with the companion services attached to it.`,
|
|
2432
|
+
"",
|
|
2433
|
+
`When to use: "show my dev environments", before opening/tearing one down, to find a box's id.`,
|
|
2434
|
+
"",
|
|
2435
|
+
'Returns: { items: [{ ...service, devUrl, databases }] } where `databases` lists the companion engines wired into the box (e.g. ["postgres","redis"]).',
|
|
2436
|
+
"",
|
|
2437
|
+
"Example: list_dev_environments() \u2192 every dev box for the active team."
|
|
2438
|
+
].join("\n"),
|
|
2439
|
+
input: {},
|
|
2440
|
+
handler: async (_args, ctx) => {
|
|
2441
|
+
const teamId = await ctx.resolveTeamId();
|
|
2442
|
+
const { environments } = await ctx.hoststack.services.listDevEnvironments(teamId);
|
|
2443
|
+
return respond({
|
|
2444
|
+
summary: `${environments.length} dev environment${environments.length === 1 ? "" : "s"}.`,
|
|
2445
|
+
data: {
|
|
2446
|
+
items: environments.map((env) => ({
|
|
2447
|
+
...shapeService(env),
|
|
2448
|
+
devUrl: env.devUrl ?? null,
|
|
2449
|
+
databases: env.databases ?? []
|
|
2450
|
+
}))
|
|
2451
|
+
}
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
});
|
|
2455
|
+
defineTool({
|
|
2456
|
+
name: "create_standalone_dev_environment",
|
|
2457
|
+
category: "services",
|
|
2458
|
+
description: [
|
|
2459
|
+
"Create a STANDALONE dev environment in one call: a cloud box (Claude Code + Codex + OpenCode + MCPs) on a persistent /workspace, from a connected GitHub repo, an arbitrary clone URL, or blank \u2014 with optional companion Postgres / Redis / Meilisearch wired into its env (mirrors a local `make db-up`). The box lives in the team's hidden Development home, NOT under a project.",
|
|
2460
|
+
"",
|
|
2461
|
+
'When to use: "create a dev environment for <repo>", "spin me up a cloud dev box with a Postgres". Distinct from spin_up_dev_environment (which clones an EXISTING service) and create_dev_environment (a bare box in a chosen project).',
|
|
2462
|
+
"",
|
|
2463
|
+
"Inputs:",
|
|
2464
|
+
" - name: the dev box name.",
|
|
2465
|
+
' - source_kind: "github_repo" (clone a connected repo \u2014 needs github_repo_id), "url" (clone any http(s) git URL \u2014 needs clone_url), or "blank" (empty box).',
|
|
2466
|
+
" - github_repo_id (for github_repo): numeric id of a connected GitHub repo.",
|
|
2467
|
+
" - clone_url (for url): an http(s) git clone URL.",
|
|
2468
|
+
" - branch (optional): branch to clone.",
|
|
2469
|
+
' - databases (optional): companion services to attach \u2014 any of "postgres", "redis", "meilisearch".',
|
|
2470
|
+
' - plan (optional): box size (default "micro").',
|
|
2471
|
+
"",
|
|
2472
|
+
"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.",
|
|
2473
|
+
"",
|
|
2474
|
+
'Example: create_standalone_dev_environment({ name: "app-dev", source_kind: "github_repo", github_repo_id: 42, databases: ["postgres","redis"] })'
|
|
2475
|
+
].join("\n"),
|
|
2476
|
+
input: {
|
|
2477
|
+
name: z13.string().min(1).max(100).describe("Dev box name."),
|
|
2478
|
+
source_kind: z13.enum(["github_repo", "url", "blank"]).describe("Where the code comes from."),
|
|
2479
|
+
github_repo_id: z13.number().int().positive().optional().describe('Connected GitHub repo id (required when source_kind="github_repo").'),
|
|
2480
|
+
clone_url: z13.string().url().optional().describe('http(s) git clone URL (required when source_kind="url").'),
|
|
2481
|
+
branch: z13.string().min(1).max(255).optional().describe("Branch to clone."),
|
|
2482
|
+
databases: z13.array(z13.enum(["postgres", "redis", "meilisearch"])).optional().describe("Companion services to attach (fresh + empty)."),
|
|
2483
|
+
plan: z13.enum(SERVICE_PLANS).optional().describe('Box size (default "micro").')
|
|
2484
|
+
},
|
|
2485
|
+
handler: async (args, ctx) => {
|
|
2486
|
+
const teamId = await ctx.resolveTeamId();
|
|
2487
|
+
let source;
|
|
2488
|
+
if (args.source_kind === "github_repo") {
|
|
2489
|
+
if (!args.github_repo_id) {
|
|
2490
|
+
return respond({
|
|
2491
|
+
summary: 'github_repo_id is required when source_kind is "github_repo".',
|
|
2492
|
+
data: { ok: false }
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2495
|
+
source = {
|
|
2496
|
+
kind: "github_repo",
|
|
2497
|
+
githubRepoId: args.github_repo_id,
|
|
2498
|
+
...args.branch ? { branch: args.branch } : {}
|
|
2499
|
+
};
|
|
2500
|
+
} else if (args.source_kind === "url") {
|
|
2501
|
+
if (!args.clone_url) {
|
|
2502
|
+
return respond({
|
|
2503
|
+
summary: 'clone_url is required when source_kind is "url".',
|
|
2504
|
+
data: { ok: false }
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
source = {
|
|
2508
|
+
kind: "url",
|
|
2509
|
+
cloneUrl: args.clone_url,
|
|
2510
|
+
...args.branch ? { branch: args.branch } : {}
|
|
2511
|
+
};
|
|
2512
|
+
} else {
|
|
2513
|
+
source = { kind: "blank" };
|
|
2514
|
+
}
|
|
2515
|
+
const input = {
|
|
2516
|
+
name: args.name,
|
|
2517
|
+
source,
|
|
2518
|
+
...args.databases ? { databases: args.databases } : {},
|
|
2519
|
+
...args.plan ? { plan: args.plan } : {}
|
|
2520
|
+
};
|
|
2521
|
+
const result = await ctx.hoststack.services.createDevEnvironment(teamId, input);
|
|
2522
|
+
return respond({
|
|
2523
|
+
summary: `Created 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}.`,
|
|
2524
|
+
data: {
|
|
2525
|
+
service: shapeService(result.service),
|
|
2526
|
+
devUrl: result.devUrl,
|
|
2527
|
+
deployId: result.deployId
|
|
2528
|
+
}
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2531
|
+
});
|
|
2409
2532
|
defineTool({
|
|
2410
2533
|
name: "get_service",
|
|
2411
2534
|
category: "services",
|