@hoststack.dev/mcp 0.27.0 → 0.28.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.
@@ -8,7 +8,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
8
  import { HostStack } from "@hoststack.dev/sdk";
9
9
 
10
10
  // src/version.ts
11
- var MCP_VERSION = true ? "0.27.0" : "0.0.0-dev";
11
+ var MCP_VERSION = true ? "0.28.0" : "0.0.0-dev";
12
12
  var USER_AGENT = `hoststack-mcp/${MCP_VERSION}`;
13
13
 
14
14
  // src/api-client.ts
@@ -4095,6 +4095,27 @@ var DEV_BOX_INSIDE = [
4095
4095
  " - Language runtimes: node, bun, python and php 8.3 are built in. go, java, ruby, rust, elixir and dotnet install on demand with `dev-runtime add <name>` (persisted to /workspace). Together that covers every runtime the platform itself deploys \u2014 a WordPress/Laravel/Rails stack runs in the box. elixir needs `dev-runtime add erlang` first: it is a BEAM distribution with no OTP of its own, and Ubuntu ships one too old to use, so mise builds a current one (takes a few minutes).",
4096
4096
  " - `hoststack-status` prints what is running, the box dev URL and agent login state at any time."
4097
4097
  ].join("\n");
4098
+ var RESOURCE_LINK_TYPES2 = [
4099
+ "database",
4100
+ "object_storage",
4101
+ "queue",
4102
+ "search",
4103
+ "email_domain"
4104
+ ];
4105
+ var LINK_ALIAS = {
4106
+ database: "DATABASE",
4107
+ object_storage: "S3",
4108
+ queue: "QUEUE",
4109
+ search: "SEARCH",
4110
+ email_domain: "EMAIL"
4111
+ };
4112
+ function defaultLinkAlias(type, used) {
4113
+ const base = LINK_ALIAS[type];
4114
+ if (!used.includes(base)) return base;
4115
+ let n = 2;
4116
+ while (used.includes(`${base}_${String(n)}`)) n++;
4117
+ return `${base}_${String(n)}`;
4118
+ }
4098
4119
  var SERVICE_TYPES = [
4099
4120
  "web_service",
4100
4121
  "private_service",
@@ -4213,8 +4234,10 @@ defineTool({
4213
4234
  " - environment_id (optional): bind to a specific environment; defaults to the project Production env.",
4214
4235
  " - auto_deploy (optional, default true): trigger the first deploy immediately when a source is present.",
4215
4236
  " - machine (optional): run it on one of the team's OWN enrolled machines (name or id, see list_machines) instead of HostStack compute. Pinned at creation and never moved afterwards, and the service is up only while that machine is.",
4237
+ " - env_vars (optional): [{ key, value, is_secret? }] written before the first deploy, so it boots with them. Beats set_env_var afterwards, which only reaches deploy #2.",
4238
+ " - links (optional): [{ resource_type, resource_id, alias? }] existing managed resources (create_database first) to connect before the first deploy. A database link injects DATABASE_URL / REDIS_URL / MONGO_URL plus <ALIAS>_URL etc. alias defaults to DATABASE, S3, QUEUE, SEARCH or EMAIL by type.",
4216
4239
  "",
4217
- "Returns: { service: Service, deployId: number | null }.",
4240
+ "Returns: { service: Service, deployId: number | null, linkErrors: [{ resourceType, resourceId, error }] } \u2014 a refused link is reported, not fatal.",
4218
4241
  "",
4219
4242
  'Example: create_service({ project_id: "prj_abc", name: "api", type: "web_service", github_repo: "acme/api" }) \u2192 { service: { publicId: "svc_\u2026", repoUrl: "https://github.com/acme/api" }, deployId: 1234 }',
4220
4243
  "Repo not listed by list_github_repos? Call sync_github_repos \u2014 a repository pushed since the last sync is invisible until then.",
@@ -4252,7 +4275,23 @@ defineTool({
4252
4275
  plan: z20.enum(SERVICE_PLANS).optional().describe('Service size (default "micro").'),
4253
4276
  environment_id: z20.union([z20.number().int().positive(), z20.string()]).optional().describe("Bind to a specific environment; defaults to Production."),
4254
4277
  auto_deploy: z20.boolean().optional().describe("Trigger the first deploy immediately (default true)."),
4255
- machine: machineInput
4278
+ machine: machineInput,
4279
+ env_vars: z20.array(
4280
+ z20.object({
4281
+ key: z20.string().min(1).max(256),
4282
+ value: z20.string().max(32768),
4283
+ is_secret: z20.boolean().optional()
4284
+ })
4285
+ ).max(1e3).optional().describe("Environment variables set before the first deploy."),
4286
+ links: z20.array(
4287
+ z20.object({
4288
+ resource_type: z20.enum(RESOURCE_LINK_TYPES2),
4289
+ resource_id: z20.number().int().positive(),
4290
+ alias: z20.string().min(1).max(48).optional()
4291
+ })
4292
+ ).max(20).optional().describe(
4293
+ "Existing managed resources to connect before the first deploy (e.g. a database from create_database)."
4294
+ )
4256
4295
  },
4257
4296
  handler: async (args2, ctx) => {
4258
4297
  const teamId = await ctx.resolveTeamId();
@@ -4289,10 +4328,26 @@ defineTool({
4289
4328
  if (args2.machine !== void 0) {
4290
4329
  input.machineId = await resolveMachineId(ctx, teamId, args2.machine);
4291
4330
  }
4331
+ if (args2.env_vars !== void 0) {
4332
+ input.envVars = args2.env_vars.map((v) => ({
4333
+ key: v.key,
4334
+ value: v.value,
4335
+ isSecret: v.is_secret ?? false
4336
+ }));
4337
+ }
4338
+ if (args2.links !== void 0) {
4339
+ const aliases = [];
4340
+ input.links = args2.links.map((l) => {
4341
+ const alias = l.alias ?? defaultLinkAlias(l.resource_type, aliases);
4342
+ aliases.push(alias);
4343
+ return { resourceType: l.resource_type, resourceId: l.resource_id, alias };
4344
+ });
4345
+ }
4292
4346
  const response = await ctx.hoststack.services.create(teamId, input);
4293
4347
  const data = {
4294
4348
  service: shapeService(response.service),
4295
- deployId: response.deployId ?? null
4349
+ deployId: response.deployId ?? null,
4350
+ linkErrors: response.linkErrors ?? []
4296
4351
  };
4297
4352
  const publicId = data.service && "publicId" in data.service ? data.service.publicId : "unknown";
4298
4353
  return respond({ summary: `Created service "${args2.name}" (${publicId}).`, data });