@hoststack.dev/mcp 0.1.1 → 0.1.2

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/index.d.ts CHANGED
@@ -64,7 +64,7 @@ type ToolCallSink = (event: ToolCallEvent) => void | Promise<void>;
64
64
  interface CreateServerOptions {
65
65
  /** HostStack API key (hs_live_… or hs_test_…). Required. */
66
66
  apiKey: string;
67
- /** Base URL for the HostStack API. Defaults to https://api.hoststack.dev */
67
+ /** Base URL for the HostStack API. Defaults to https://hoststack.dev */
68
68
  baseUrl?: string;
69
69
  /**
70
70
  * Server identity advertised in the MCP `initialize` response. Defaults
@@ -82,7 +82,7 @@ interface CreateServerOptions {
82
82
  onToolCall?: ToolCallSink;
83
83
  }
84
84
  declare const PACKAGE_NAME = "hoststack";
85
- declare const PACKAGE_VERSION = "0.1.1";
85
+ declare const PACKAGE_VERSION = "0.1.2";
86
86
  /**
87
87
  * Build a fully-wired MCP server. Used by both the stdio CLI entry-point and
88
88
  * the HTTP transport mounted by the API server. A new server (and its
package/dist/index.js CHANGED
@@ -1375,9 +1375,9 @@ defineTool({
1375
1375
 
1376
1376
  // src/server-factory.ts
1377
1377
  var PACKAGE_NAME = "hoststack";
1378
- var PACKAGE_VERSION = "0.1.1";
1378
+ var PACKAGE_VERSION = "0.1.2";
1379
1379
  function createMcpServer(options) {
1380
- const baseUrl = (options.baseUrl ?? "https://api.hoststack.dev").replace(/\/$/, "");
1380
+ const baseUrl = (options.baseUrl ?? "https://hoststack.dev").replace(/\/$/, "");
1381
1381
  const hoststack = new HostStack({ apiKey: options.apiKey, baseUrl });
1382
1382
  const api = new ApiClient(options.apiKey, baseUrl);
1383
1383
  const server = new McpServer({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server-factory.ts","../src/api-client.ts","../src/prompts/registry.ts","../src/resources/registry.ts","../src/registry.ts","../src/prompts/deploy-prompts.ts","../src/lib/shape.ts","../src/resources/hoststack-resources.ts","../src/tools/activity-log.ts","../src/lib/respond.ts","../src/tools/cron.ts","../src/tools/databases.ts","../src/tools/deploys.ts","../src/tools/domains.ts","../src/tools/env-vars.ts","../src/tools/meta.ts","../src/tools/projects.ts","../src/tools/services.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { HostStack } from '@hoststack.dev/sdk';\n\nimport { ApiClient } from './api-client.js';\nimport { attachPrompts } from './prompts/registry.js';\nimport { attachResources } from './resources/registry.js';\nimport { attachTools, type ToolCallSink, type ToolContext } from './registry.js';\n\nexport type { ToolCallEvent, ToolCallSink } from './registry.js';\n\n// Importing each tool/prompt/resource module runs its top-level define*()\n// calls and populates the shared registries. ESM caches modules, so each\n// registry is built exactly once per process.\nimport './prompts/deploy-prompts.js';\nimport './resources/hoststack-resources.js';\nimport './tools/activity-log.js';\nimport './tools/cron.js';\nimport './tools/databases.js';\nimport './tools/deploys.js';\nimport './tools/domains.js';\nimport './tools/env-vars.js';\nimport './tools/meta.js';\nimport './tools/projects.js';\nimport './tools/services.js';\n\nexport interface CreateServerOptions {\n\t/** HostStack API key (hs_live_… or hs_test_…). Required. */\n\tapiKey: string;\n\t/** Base URL for the HostStack API. Defaults to https://api.hoststack.dev */\n\tbaseUrl?: string;\n\t/**\n\t * Server identity advertised in the MCP `initialize` response. Defaults\n\t * to `{ name: \"hoststack\", version: PACKAGE_VERSION }`.\n\t */\n\tserverInfo?: { name: string; version: string };\n\t/**\n\t * Optional telemetry sink invoked once per tool call (success or failure).\n\t * Runs on the microtask queue; sink errors are swallowed so tool execution\n\t * never blocks on telemetry.\n\t */\n\tonToolCall?: ToolCallSink;\n}\n\nexport const PACKAGE_NAME = 'hoststack';\nexport const PACKAGE_VERSION = '0.1.1';\n\ninterface MeResponse {\n\tuser: { id: number };\n\tteam?: { id: number };\n}\n\n/**\n * Build a fully-wired MCP server. Used by both the stdio CLI entry-point and\n * the HTTP transport mounted by the API server. A new server (and its\n * underlying SDK + ApiClient) is created per call, so the HTTP transport can\n * scope each connection to a single API key without cross-contamination.\n */\nexport function createMcpServer(options: CreateServerOptions): McpServer {\n\tconst baseUrl = (options.baseUrl ?? 'https://api.hoststack.dev').replace(/\\/$/, '');\n\tconst hoststack = new HostStack({ apiKey: options.apiKey, baseUrl });\n\tconst api = new ApiClient(options.apiKey, baseUrl);\n\n\tconst server = new McpServer({\n\t\tname: options.serverInfo?.name ?? PACKAGE_NAME,\n\t\tversion: options.serverInfo?.version ?? PACKAGE_VERSION,\n\t});\n\n\t// Cache the team lookup. The first tool call pays one /auth/me round-trip;\n\t// every subsequent call reuses the cached promise. We store the in-flight\n\t// promise (not the resolved value) so concurrent first-calls don't fan out\n\t// into duplicate /auth/me requests.\n\tlet teamIdPromise: Promise<number> | null = null;\n\tconst resolveTeamId = (): Promise<number> => {\n\t\tif (!teamIdPromise) {\n\t\t\tteamIdPromise = api.get<MeResponse>('/api/auth/me').then((me) => {\n\t\t\t\tif (!me.team?.id) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'No team bound to API key. Generate a team-scoped key in the dashboard.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn me.team.id;\n\t\t\t});\n\t\t\t// If the lookup fails, clear the cache so a retry can succeed once\n\t\t\t// the user fixes their key. Without this, every subsequent tool\n\t\t\t// call would re-throw the same cached rejection.\n\t\t\tteamIdPromise.catch(() => {\n\t\t\t\tteamIdPromise = null;\n\t\t\t});\n\t\t}\n\t\treturn teamIdPromise;\n\t};\n\n\tconst ctx: ToolContext = { hoststack, api, resolveTeamId };\n\tattachTools(server, ctx, options.onToolCall);\n\tattachPrompts(server, ctx);\n\tattachResources(server, ctx);\n\n\treturn server;\n}\n","/**\n * Lightweight API client for HostStack endpoints not yet covered by the SDK\n * (logs snapshots, activity log, runtime metrics, /me lookup). Uses the same\n * auth and base URL as the SDK instance.\n */\nexport class ApiClient {\n\tconstructor(\n\t\tprivate readonly apiKey: string,\n\t\tprivate readonly baseUrl: string,\n\t) {}\n\n\tprivate get headers(): Record<string, string> {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tif (params) {\n\t\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\t\tif (value !== undefined) url.searchParams.set(key, String(value));\n\t\t\t}\n\t\t}\n\t\tconst res = await fetch(url.toString(), { headers: this.headers });\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\tconst init: RequestInit = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: this.headers,\n\t\t};\n\t\tif (body !== undefined) init.body = JSON.stringify(body);\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, init);\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync patch<T>(path: string, body: unknown): Promise<T> {\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'PATCH',\n\t\t\theaders: this.headers,\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync delete<T>(path: string): Promise<T> {\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'DELETE',\n\t\t\theaders: this.headers,\n\t\t});\n\t\treturn this.handle<T>(res);\n\t}\n\n\tprivate async handle<T>(res: Response): Promise<T> {\n\t\tif (!res.ok) {\n\t\t\tconst error = (await res.json().catch(() => ({ error: res.statusText }))) as {\n\t\t\t\terror?: string;\n\t\t\t};\n\t\t\tthrow new Error(error.error ?? `API error: ${res.status}`);\n\t\t}\n\t\tif (res.status === 204) {\n\t\t\treturn undefined as T;\n\t\t}\n\t\treturn res.json() as Promise<T>;\n\t}\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\nimport type { ZodRawShape, z } from 'zod';\n\nimport type { ApiClient } from '../api-client.js';\n\nexport interface PromptContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface InternalPromptDefinition {\n\tname: string;\n\tdescription: string;\n\targs: ZodRawShape;\n\thandler: (\n\t\targs: Record<string, string | undefined>,\n\t\tctx: PromptContext,\n\t) => Promise<GetPromptResult>;\n}\n\nexport type PromptDefinition = Readonly<InternalPromptDefinition>;\n\nconst prompts: InternalPromptDefinition[] = [];\n\n/**\n * Register a single prompt. The generic over `TArgs` lets the handler receive\n * precisely-typed args while the registry stores the widened shape — same\n * trick as `defineTool` to keep the compiler's instantiation budget in check.\n */\nexport function definePrompt<TArgs extends ZodRawShape>(def: {\n\tname: string;\n\tdescription: string;\n\targs: TArgs;\n\thandler: (args: z.infer<z.ZodObject<TArgs>>, ctx: PromptContext) => Promise<GetPromptResult>;\n}): void {\n\tprompts.push({\n\t\tname: def.name,\n\t\tdescription: def.description,\n\t\targs: def.args,\n\t\thandler: def.handler as InternalPromptDefinition['handler'],\n\t});\n}\n\nexport function listPromptDefinitions(): ReadonlyArray<PromptDefinition> {\n\treturn prompts;\n}\n\n/** Iterate the registry and wire each prompt into the MCP server. */\nexport function attachPrompts(server: McpServer, ctx: PromptContext): void {\n\ttype PromptMethod = (\n\t\tname: string,\n\t\tdescription: string,\n\t\targsSchema: ZodRawShape,\n\t\tcb: (args: Record<string, string | undefined>) => Promise<GetPromptResult>,\n\t) => unknown;\n\n\tconst register = server.prompt.bind(server) as unknown as PromptMethod;\n\n\tfor (const def of prompts) {\n\t\tregister(def.name, def.description, def.args, (args) => def.handler(args, ctx));\n\t}\n}\n\n/**\n * Helper to build a single user-role text message — the most common shape for\n * these prompts (we're guiding the agent, not modeling assistant responses).\n */\nexport function userMessage(text: string): GetPromptResult['messages'][number] {\n\treturn { role: 'user', content: { type: 'text', text } };\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\n\nimport type { ApiClient } from '../api-client.js';\n\ninterface ResourceContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface StaticResourceDef {\n\tkind: 'static';\n\tname: string;\n\turi: string;\n\tdescription: string;\n\tmimeType?: string;\n\tread: (uri: URL, ctx: ResourceContext) => Promise<ReadResourceResult>;\n}\n\nexport type ResourceDefinition = Readonly<StaticResourceDef>;\n\nconst resources: StaticResourceDef[] = [];\n\nexport function defineResource(def: StaticResourceDef): void {\n\tresources.push(def);\n}\n\nexport function listResourceDefinitions(): ReadonlyArray<ResourceDefinition> {\n\treturn resources;\n}\n\nexport function attachResources(server: McpServer, ctx: ResourceContext): void {\n\tfor (const def of resources) {\n\t\tserver.resource(\n\t\t\tdef.name,\n\t\t\tdef.uri,\n\t\t\t{\n\t\t\t\tdescription: def.description,\n\t\t\t\t...(def.mimeType ? { mimeType: def.mimeType } : {}),\n\t\t\t},\n\t\t\t(uri) => def.read(uri, ctx),\n\t\t);\n\t}\n}\n\n/**\n * Pack a JSON value into the resource read-result envelope. The MCP spec\n * requires `text` for application/json resources — we serialise here so each\n * resource handler stays a one-liner.\n */\nexport function jsonResource(uri: URL, data: unknown): ReadResourceResult {\n\treturn {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\turi: uri.toString(),\n\t\t\t\tmimeType: 'application/json',\n\t\t\t\ttext: JSON.stringify(data, null, 2),\n\t\t\t},\n\t\t],\n\t};\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\nimport type { ZodRawShape, z } from 'zod';\n\nimport type { ApiClient } from './api-client.js';\n\nexport type ToolCategory =\n\t| 'projects'\n\t| 'services'\n\t| 'deploys'\n\t| 'databases'\n\t| 'domains'\n\t| 'env-vars'\n\t| 'cron'\n\t| 'logs'\n\t| 'activity-log'\n\t| 'meta';\n\nexport interface ToolContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\t/**\n\t * Lazy resolver for the team ID bound to the API key. The agent never has\n\t * to pass `teamId` to a tool — every SDK route is team-scoped, so the MCP\n\t * looks it up once via `/api/auth/me` and caches it for the rest of the\n\t * server's lifetime. Throws if the API key is invalid or unbound.\n\t */\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface InternalToolDefinition {\n\tname: string;\n\tcategory: ToolCategory;\n\tdescription: string;\n\tinput: ZodRawShape;\n\thandler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<CallToolResult>;\n}\n\nexport type ToolDefinition = Readonly<InternalToolDefinition>;\n\nconst tools: InternalToolDefinition[] = [];\n\n/**\n * Register a single tool definition. The generic over `TInput` lets the\n * handler receive precisely-typed arguments while the registry stores the\n * widened shape.\n */\nexport function defineTool<TInput extends ZodRawShape>(def: {\n\tname: string;\n\tcategory: ToolCategory;\n\tdescription: string;\n\tinput: TInput;\n\thandler: (args: z.infer<z.ZodObject<TInput>>, ctx: ToolContext) => Promise<CallToolResult>;\n}): void {\n\ttools.push({\n\t\tname: def.name,\n\t\tcategory: def.category,\n\t\tdescription: def.description,\n\t\tinput: def.input,\n\t\thandler: def.handler as InternalToolDefinition['handler'],\n\t});\n}\n\n/** Snapshot the currently-registered tool definitions (for tests / docs). */\nexport function listToolDefinitions(): ReadonlyArray<ToolDefinition> {\n\treturn tools;\n}\n\n/**\n * Telemetry event emitted once per tool invocation. The MCP package never\n * persists these — it just hands them to the optional `onToolCall` sink so\n * the host (HTTP transport, CLI, tests) can decide where they go.\n *\n * Privacy: `inputHash` is a hash over the JSON-stringified args; we never\n * expose the args themselves so PII from tool inputs (env-var values, domain\n * names) never reaches a sink.\n */\nexport interface ToolCallEvent {\n\ttool: string;\n\tdurationMs: number;\n\tok: boolean;\n\terrorCode: string | null;\n\tinputHash: string | null;\n\tstartedAt: Date;\n}\n\nexport type ToolCallSink = (event: ToolCallEvent) => void | Promise<void>;\n\n/** Iterate the registry and wire each tool into the MCP server. */\nexport function attachTools(server: McpServer, ctx: ToolContext, sink?: ToolCallSink): void {\n\ttype ToolMethod = (\n\t\tname: string,\n\t\tdescription: string,\n\t\tschema: ZodRawShape,\n\t\tcb: (args: Record<string, unknown>) => Promise<CallToolResult>,\n\t) => unknown;\n\n\tconst register = server.tool.bind(server) as unknown as ToolMethod;\n\n\tfor (const def of tools) {\n\t\tregister(def.name, def.description, def.input, async (args) => {\n\t\t\tconst startedAt = new Date();\n\t\t\tconst start = performance.now();\n\t\t\tlet ok = true;\n\t\t\tlet errorCode: string | null = null;\n\t\t\ttry {\n\t\t\t\tconst result = await def.handler(args, ctx);\n\t\t\t\tif (result.isError) {\n\t\t\t\t\tok = false;\n\t\t\t\t\terrorCode = 'tool_error';\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tok = false;\n\t\t\t\terrorCode =\n\t\t\t\t\terr instanceof Error ? (err.name || 'Error').slice(0, 64) : 'unknown_error';\n\t\t\t\tthrow err;\n\t\t\t} finally {\n\t\t\t\tif (sink) {\n\t\t\t\t\tconst durationMs = Math.round(performance.now() - start);\n\t\t\t\t\tconst event: ToolCallEvent = {\n\t\t\t\t\t\ttool: def.name,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tok,\n\t\t\t\t\t\terrorCode,\n\t\t\t\t\t\tinputHash: hashArgs(args),\n\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t};\n\t\t\t\t\tPromise.resolve()\n\t\t\t\t\t\t.then(() => sink(event))\n\t\t\t\t\t\t.catch(() => undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n\nfunction hashArgs(args: Record<string, unknown>): string | null {\n\ttry {\n\t\tconst json = JSON.stringify(args);\n\t\tconst bunGlobal = (globalThis as { Bun?: { hash?: (data: string) => bigint } }).Bun;\n\t\tif (bunGlobal?.hash) {\n\t\t\treturn bunGlobal.hash(json).toString(16);\n\t\t}\n\t\treturn `len:${json.length}`;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { z } from 'zod';\n\nimport { definePrompt, userMessage } from './registry.js';\n\ndefinePrompt({\n\tname: 'diagnose_failed_deploy',\n\tdescription:\n\t\t\"Walk the agent through diagnosing a failed deploy: pull the latest deploys for the named service, find the most recent failure, fetch its build/deploy logs, and propose a fix. Stops at suggestion — does not retrigger automatically.\",\n\targs: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async ({ service_id }) => {\n\t\tconst text = `Goal: diagnose the most recent failed deploy on service ${service_id} and propose a fix.\n\nPlan (use these tools in order):\n1. \\`list_deploys({ service_id: \"${service_id}\" })\\` — pull recent deploys, newest first. Identify the most recent deploy with status \\`failed\\` (or \\`cancelled\\` if the user wants to investigate that too). Capture its publicId, branch, and commitSha.\n2. \\`get_deploy_logs({ service_id: \"${service_id}\", deploy_id: \"<dpl_…>\" })\\` — read the full build output. Scan for: stack traces, \"ERROR\" / \"error:\" lines, exit codes, missing env vars, OOM-killed signals, network failures pulling dependencies.\n3. \\`get_service({ service_id: \"${service_id}\" })\\` — confirm the service's runtime, plan, and whether autoDeploy is on. Plan tier matters because OOMs at small tiers point at \\`maxMemoryMb\\`.\n4. (Optional) \\`list_env_vars({ service_id: \"${service_id}\" })\\` — only if the build error mentions a missing variable. Don't fetch otherwise; values are masked anyway.\n\nThen write a short diagnosis for the user with three sections:\n- **Root cause** — one sentence pointing at the actual failure line.\n- **Evidence** — 3–6 line excerpt from the logs that proves the diagnosis.\n- **Suggested fix** — concrete next steps, including which tool to call (e.g. \"set MISSING_KEY with set_env_var, then trigger_deploy\"). Do NOT call trigger_deploy automatically; the user decides.\n\nIf the deploy logs are empty or only contain queued/pending markers, surface that — the build never started, which is its own class of bug (likely a builder-pool or quota issue).`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n\ndefinePrompt({\n\tname: 'deploy_status_check',\n\tdescription:\n\t\t\"Quick orientation prompt: who am I, what's running, and is anything currently deploying? Useful at the start of a session.\",\n\targs: {},\n\thandler: async () => {\n\t\tconst text = `Goal: produce a 30-second status check on this HostStack team.\n\nPlan:\n1. \\`get_me()\\` — confirm which user + team the API key belongs to.\n2. \\`list_services()\\` — every service with current status (running, suspended, building, deploying, failed). Note any service in a non-running state.\n3. For each service whose status is \\`building\\` or \\`deploying\\`, call \\`list_deploys({ service_id })\\` and surface the latest deploy's commitMessage + author.\n4. \\`list_activity_log({ per_page: 10 })\\` — last 10 audit events to spot recent changes (deploys triggered, env vars edited, services restarted).\n\nWrite a status report shaped like:\n\n> **Team**: <name>\n> **Services**: <n> total — <breakdown by status>\n> **In flight**: <list of building/deploying services with commit info, or \"none\">\n> **Recent activity**: <3-5 most relevant events from the audit log, newest first>\n\nKeep it tight (under 200 words). The user can drill in with follow-up tools.`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n\ndefinePrompt({\n\tname: 'rotate_secret',\n\tdescription:\n\t\t\"Guide the agent through rotating an env-var secret on a service. Lists current vars to confirm the target key exists, asks the user for the new value, sets it, and offers to trigger a deploy.\",\n\targs: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().describe('Env-var key to rotate (e.g. DATABASE_URL).'),\n\t},\n\thandler: async ({ service_id, key }) => {\n\t\tconst text = `Goal: rotate the secret \\`${key}\\` on service ${service_id}.\n\nPlan:\n1. \\`list_env_vars({ service_id: \"${service_id}\" })\\` — confirm \\`${key}\\` exists. Note its \\`isSecret\\` flag (it should be true; if not, flag this — you're about to mark it secret on rotation, which is a behaviour change).\n2. **Ask the user for the new value before calling any write tool.** The agent must NOT invent or generate the secret; it has to come from the user's clipboard / vault. Phrase the ask explicitly: \"Paste the new value for ${key} (it will be encrypted at rest and masked everywhere except the running container).\"\n3. Once the user provides the value:\n - \\`set_env_var({ service_id: \"${service_id}\", key: \"${key}\", value: \"<new value>\", is_secret: true })\\` — upserts by key.\n4. After the write succeeds, ask the user whether to redeploy (so the new value lands in the running container). If yes:\n - \\`trigger_deploy({ service_id: \"${service_id}\" })\\` — kicks off a build with the rotated secret.\n - \\`get_deploy({ service_id: \"${service_id}\", deploy_id: \"<dpl_…>\" })\\` — poll until status is \\`live\\` or \\`failed\\`. On failure, hand off to \\`diagnose_failed_deploy\\`.\n\nSafety rails:\n- Never echo the new value back in your reply; the user should verify it from their own source of truth, not from your context window.\n- If the user says \"generate a new one\", suggest \\`openssl rand -hex 32\\` (or similar) for them to run locally and paste in. Do NOT generate it for them — secrets that pass through an LLM context are no longer secrets.\n- If \\`set_env_var\\` returned \\`action: \"created\"\\` instead of \\`\"updated\"\\`, the key didn't exist before. Pause and confirm with the user — they may have typo'd the key name.`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n","/**\n * Per-resource shape pickers. Each function takes a raw API/SDK response and\n * returns the agent-friendly subset: drops internal foreign keys (teamId,\n * userId, ...) and null-valued columns, leaves ISO-8601 timestamps as-is.\n *\n * Pickers must be permissive about input shape — different SDK methods may\n * return slightly different fields (e.g. list vs get) and the API may grow\n * fields over time. We never throw on missing fields.\n */\n\nconst INTERNAL_FIELDS = new Set([\n\t'teamId',\n\t'team_id',\n\t'userId',\n\t'user_id',\n\t'accountId',\n\t'account_id',\n\t'tenantId',\n\t'tenant_id',\n\t'createdById',\n\t'updatedById',\n]);\n\ntype Obj = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Obj {\n\treturn value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction dropNullsAndInternals(obj: Obj): Obj {\n\tconst out: Obj = {};\n\tfor (const [key, value] of Object.entries(obj)) {\n\t\tif (INTERNAL_FIELDS.has(key)) continue;\n\t\tif (value === null || value === undefined) continue;\n\t\tout[key] = value;\n\t}\n\treturn out;\n}\n\n/** Generic shape — drop internals, drop nulls, keep everything else. */\nexport function shape(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(shape);\n\tif (isObject(value)) return dropNullsAndInternals(value);\n\treturn value;\n}\n\nfunction shapeAll<T>(arr: unknown, shaper: (item: unknown) => T): T[] {\n\tif (!Array.isArray(arr)) return [];\n\treturn arr.map(shaper);\n}\n\n/**\n * Unwrap a HostStack list response. The API returns shapes like\n * `{ projects: [...] }`, `{ services: [...] }`, etc. — the key varies by\n * resource. Pass the key explicitly so the wrapper stays type-loose.\n */\nexport function shapeList<T>(\n\tresponse: unknown,\n\tkey: string,\n\tshaper: (item: unknown) => T,\n): { items: T[] } {\n\tif (!isObject(response)) return { items: [] };\n\treturn { items: shapeAll(response[key], shaper) };\n}\n\n// ──────────────────────────────────────────────────────────────────────\n// Per-resource pickers — typed convenience wrappers around shape().\n// All return a plain Obj (never null), keeping the registry handlers simple.\n// ──────────────────────────────────────────────────────────────────────\n\nexport function shapeProject(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeService(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDeploy(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDatabase(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDomain(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeEnvVar(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeCronExecution(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeActivity(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeUser(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeTeam(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n","import { shapeProject, shapeService, shapeTeam, shapeUser } from '../lib/shape.js';\nimport { defineResource, jsonResource } from './registry.js';\n\ninterface MeResponse {\n\tuser: unknown;\n\tteam?: unknown;\n}\n\ndefineResource({\n\tkind: 'static',\n\tname: 'team',\n\turi: 'hoststack://team',\n\tdescription:\n\t\t'Authenticated team identity + a quick orientation snapshot. Includes the team record, the user behind the API key, and counts of projects and services so an agent can decide whether to fan out into list_projects / list_services without an extra round-trip.',\n\tmimeType: 'application/json',\n\tread: async (uri, { hoststack, api, resolveTeamId }) => {\n\t\tconst teamId = await resolveTeamId();\n\n\t\t// Resource handlers must not throw on transient downstream failures —\n\t\t// clients call resources/read for orientation and a network blip\n\t\t// shouldn't poison the entire session. Tolerate partial failure and\n\t\t// surface what we can.\n\t\tconst [me, projectsResult, servicesResult] = await Promise.all([\n\t\t\tapi.get<MeResponse>('/api/auth/me').catch(() => null),\n\t\t\thoststack.projects.list(teamId).catch(() => ({ projects: [] as unknown[] })),\n\t\t\thoststack.services.list(teamId).catch(() => ({ services: [] as unknown[] })),\n\t\t]);\n\n\t\tconst projects = (projectsResult.projects as unknown[]).slice(0, 10).map(shapeProject);\n\t\tconst services = (servicesResult.services as unknown[]).slice(0, 10).map(shapeService);\n\n\t\treturn jsonResource(uri, {\n\t\t\tuser: me?.user ? shapeUser(me.user) : null,\n\t\t\tteam: me?.team ? shapeTeam(me.team) : null,\n\t\t\tproject_count: (projectsResult.projects as unknown[]).length,\n\t\t\tservice_count: (servicesResult.services as unknown[]).length,\n\t\t\t// First 10 of each so the resource stays small while still useful\n\t\t\t// for orientation. Use list_projects / list_services for the full set.\n\t\t\tprojects_preview: projects,\n\t\t\tservices_preview: services,\n\t\t});\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shape, shapeActivity } from '../lib/shape.js';\n\ninterface ActivityLogResponse {\n\tdata?: unknown[];\n\tmeta?: unknown;\n}\n\ndefineTool({\n\tname: 'list_activity_log',\n\tcategory: 'activity-log',\n\tdescription: [\n\t\t'List the team activity audit log: who did what, when. Backed by /api/activity-log/:teamId.',\n\t\t'',\n\t\t\"When to use: investigate why a service was changed unexpectedly (\\\"who deleted that env var?\\\"), correlate a deploy with a user, or pull recent admin events for a status update.\",\n\t\t'',\n\t\t'Inputs (all optional):',\n\t\t' - page: 1-based page index (default 1).',\n\t\t' - per_page: items per page (default 25, hard cap 100).',\n\t\t' - action: filter to a specific action (e.g. \"service.created\", \"deploy.triggered\").',\n\t\t' - resource_type: filter by resource type (e.g. \"service\", \"deploy\", \"domain\").',\n\t\t' - user_id: filter by acting user numeric ID.',\n\t\t'',\n\t\t'Returns: { items: ActivityLogEntry[], meta? } — each entry has id, action, resourceType, resourceId, actorEmail, ipAddress, createdAt, and a context payload.',\n\t\t'',\n\t\t'Example: list_activity_log({ resource_type: \"deploy\", per_page: 10 }) → { items: [{ action: \"deploy.triggered\", actorEmail: \"ada@…\", … }], meta: { total: 47, page: 1 } }',\n\t].join('\\n'),\n\tinput: {\n\t\tpage: z.number().int().positive().optional().describe('Page index, 1-based.'),\n\t\tper_page: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(100)\n\t\t\t.optional()\n\t\t\t.describe('Items per page, hard cap 100.'),\n\t\taction: z.string().optional().describe('Action filter, e.g. \"service.created\".'),\n\t\tresource_type: z.string().optional().describe('Resource type filter.'),\n\t\tuser_id: z.number().int().positive().optional().describe('Numeric acting-user filter.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst params: Record<string, string | number | undefined> = {};\n\t\tif (args.page !== undefined) params['page'] = String(args.page);\n\t\tif (args.per_page !== undefined) params['perPage'] = String(args.per_page);\n\t\tif (args.action !== undefined) params['action'] = args.action;\n\t\tif (args.resource_type !== undefined) params['resourceType'] = args.resource_type;\n\t\tif (args.user_id !== undefined) params['userId'] = String(args.user_id);\n\n\t\tconst response = await ctx.api.get<ActivityLogResponse>(\n\t\t\t`/api/activity-log/${teamId}`,\n\t\t\tparams,\n\t\t);\n\t\tconst items = Array.isArray(response.data) ? response.data.map(shapeActivity) : [];\n\t\tconst data: { items: unknown[]; meta?: unknown } = { items };\n\t\tif (response.meta !== undefined) data.meta = shape(response.meta);\n\n\t\treturn respond({\n\t\t\tsummary:\n\t\t\t\titems.length === 0\n\t\t\t\t\t? 'No activity log entries match the given filters.'\n\t\t\t\t\t: `Returned ${items.length} activity log entr${items.length === 1 ? 'y' : 'ies'}.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n","import type { CallToolResult, ContentBlock } from '@modelcontextprotocol/sdk/types.js';\n\ninterface RespondInput {\n\tsummary: string;\n\tdata?: unknown;\n}\n\nexport const SUMMARY_MAX_LEN = 500;\n\n/**\n * Build an MCP tool response with a 1–3 line plain-text summary, a fenced\n * JSON block for human readability, and a structuredContent object that\n * agents can parse without re-tokenising the JSON text.\n */\nexport function respond({ summary, data }: RespondInput): CallToolResult {\n\tconst trimmed = summary.trim();\n\tif (trimmed.length === 0) {\n\t\tthrow new Error('respond(): summary must be non-empty');\n\t}\n\tif (trimmed.length > SUMMARY_MAX_LEN) {\n\t\tthrow new Error(`respond(): summary too long (${trimmed.length} > ${SUMMARY_MAX_LEN})`);\n\t}\n\n\tconst blocks: ContentBlock[] = [{ type: 'text', text: trimmed }];\n\n\tif (data !== undefined) {\n\t\tblocks.push({\n\t\t\ttype: 'text',\n\t\t\ttext: '```json\\n' + JSON.stringify(data, null, 2) + '\\n```',\n\t\t});\n\t}\n\n\tconst result: CallToolResult = { content: blocks };\n\tif (data !== undefined) {\n\t\tresult.structuredContent = toStructuredContent(data);\n\t}\n\treturn result;\n}\n\nexport function respondError(message: string, data?: unknown): CallToolResult {\n\tconst blocks: ContentBlock[] = [{ type: 'text', text: `Error: ${message}` }];\n\tif (data !== undefined) {\n\t\tblocks.push({\n\t\t\ttype: 'text',\n\t\t\ttext: '```json\\n' + JSON.stringify(data, null, 2) + '\\n```',\n\t\t});\n\t}\n\tconst result: CallToolResult = { content: blocks, isError: true };\n\tif (data !== undefined) {\n\t\tresult.structuredContent = toStructuredContent(data);\n\t}\n\treturn result;\n}\n\nfunction toStructuredContent(data: unknown): Record<string, unknown> {\n\tif (data !== null && typeof data === 'object' && !Array.isArray(data)) {\n\t\treturn data as Record<string, unknown>;\n\t}\n\treturn { result: data };\n}\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeCronExecution, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_cron_executions',\n\tcategory: 'cron',\n\tdescription: [\n\t\t'List recent execution records for a cron service (newest first).',\n\t\t'',\n\t\t'When to use: investigating whether a scheduled job ran on time, finding the most recent failure, or auditing cron run-times. Only works on services of type \"cron\"; for web services this returns an error.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the cron service.',\n\t\t' - limit (optional): how many executions to fetch (default 50, max enforced server-side).',\n\t\t'',\n\t\t'Returns: { items: CronExecution[] } — id, publicId, status (succeeded|failed|running|queued), startedAt, finishedAt, exitCode, triggeredBy.',\n\t\t'',\n\t\t'Example: list_cron_executions({ service_id: \"svc_cron\" }) → { items: [{ status: \"succeeded\", exitCode: 0, … }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Cron service publicId.'),\n\t\tlimit: z.number().int().positive().max(200).optional().describe('Max executions to return (default 50).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst opts = args.limit !== undefined ? { limit: args.limit } : undefined;\n\t\tconst response = await ctx.hoststack.cron.list(teamId, args.service_id, opts);\n\t\tconst data = shapeList(response, 'executions', shapeCronExecution);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No cron executions yet for ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} cron execution${data.items.length === 1 ? '' : 's'} for ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_cron_execution',\n\tcategory: 'cron',\n\tdescription: [\n\t\t'Fetch a single cron execution record. Includes status, exit code, and timing.',\n\t\t'',\n\t\t'When to use: drilling into a specific run after list_cron_executions surfaced a failure, or correlating an execution timestamp with logs.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the cron service.',\n\t\t' - execution_id: publicId of the execution record.',\n\t\t'',\n\t\t'Returns: { execution: CronExecution }.',\n\t\t'',\n\t\t'Example: get_cron_execution({ service_id: \"svc_cron\", execution_id: \"exe_xyz\" }) → { execution: { status: \"failed\", exitCode: 1, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Cron service publicId.'),\n\t\texecution_id: z.string().describe('Execution publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.cron.get(teamId, args.service_id, args.execution_id);\n\t\tconst data = { execution: shapeCronExecution(response.execution) };\n\t\tconst status =\n\t\t\tdata.execution && 'status' in data.execution\n\t\t\t\t? (data.execution as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Execution ${args.execution_id} ${status}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDatabase, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_databases',\n\tcategory: 'databases',\n\tdescription: [\n\t\t'List managed databases (Postgres, Redis, MySQL, MariaDB, MongoDB, Meilisearch, NATS) inside a project.',\n\t\t'',\n\t\t'When to use: an agent needs to know what data stores exist in a project before connecting a service or running a migration. Pair with list_projects to discover project IDs.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - project_id: numeric project ID (from list_projects).',\n\t\t'',\n\t\t'Returns: { items: Database[] } — id, publicId, name, type, status, version, projectId, createdAt.',\n\t\t'',\n\t\t'Example: list_databases({ project_id: 12 }) → { items: [{ publicId: \"db_…\", type: \"postgres\", status: \"running\", … }] }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.number().int().positive().describe('Numeric project ID (from list_projects).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.databases.list(teamId, args.project_id);\n\t\tconst data = shapeList(response, 'databases', shapeDatabase);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No databases in project ${args.project_id}.`\n\t\t\t\t: `Found ${data.items.length} database${data.items.length === 1 ? '' : 's'} in project ${args.project_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_database',\n\tcategory: 'databases',\n\tdescription: [\n\t\t'Fetch a single managed database by ID. Includes status, type, version, and project link.',\n\t\t'',\n\t\t'When to use: confirming the version of a database before generating connection strings, or checking the status of a recently created database. To retrieve the actual connection credentials, use the dashboard — credentials are intentionally not exposed via this MCP tool.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - database_id: publicId of the database (e.g. \"db_…\").',\n\t\t'',\n\t\t'Returns: { database: Database }.',\n\t\t'',\n\t\t'Example: get_database({ database_id: \"db_xyz\" }) → { database: { type: \"postgres\", version: \"16\", status: \"running\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tdatabase_id: z.string().describe('Database publicId (e.g. db_xyz).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.databases.get(teamId, args.database_id);\n\t\tconst data = { database: shapeDatabase(response.database) };\n\t\tconst type =\n\t\t\tdata.database && 'type' in data.database\n\t\t\t\t? (data.database as { type: string }).type\n\t\t\t\t: 'unknown';\n\t\tconst status =\n\t\t\tdata.database && 'status' in data.database\n\t\t\t\t? (data.database as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Database ${args.database_id} (${type}) is ${status}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDeploy, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_deploys',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'List deploys for a service in reverse-chronological order (newest first).',\n\t\t'',\n\t\t'When to use: investigating a recent deploy outcome, finding the last successful deploy ID, comparing run-times, or just checking deploy history before triggering a new one.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service (e.g. \"svc_abc123\"). Use list_services to find it.',\n\t\t'',\n\t\t'Returns: { items: Deploy[] } — each deploy includes id, publicId, status (pending|building|deploying|live|failed|cancelled), commitSha, commitMessage, branch, triggeredBy, startedAt, finishedAt, durationMs.',\n\t\t'',\n\t\t'Example: list_deploys({ service_id: \"svc_abc\" }) → { items: [{ publicId: \"dpl_…\", status: \"live\", commitMessage: \"Fix login\", … }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.list(teamId, args.service_id);\n\t\tconst data = shapeList(response, 'deploys', shapeDeploy);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No deploys yet for service ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} deploy${data.items.length === 1 ? '' : 's'} for service ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Fetch a single deploy by ID, including its current status, commit metadata, and timestamps.',\n\t\t'',\n\t\t\"When to use: drilling into the details of a specific deploy after list_deploys, polling a build's status, or grabbing the commit SHA so you can correlate logs with code.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy (e.g. \"dpl_…\").',\n\t\t'',\n\t\t'Returns: { deploy: Deploy } — full deploy record (status, commitSha, commitMessage, branch, durationMs, finishedAt, etc).',\n\t\t'',\n\t\t'Example: get_deploy({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { deploy: { status: \"live\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.get(teamId, args.service_id, args.deploy_id);\n\t\tconst data = { deploy: shapeDeploy(response.deploy) };\n\t\tconst status =\n\t\t\tdata.deploy && typeof data.deploy === 'object' && 'status' in data.deploy\n\t\t\t\t? (data.deploy as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Deploy ${args.deploy_id} is ${status}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'trigger_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Kick off a new deploy from the latest commit on the service branch. Optionally clear the build cache for a clean rebuild.',\n\t\t'',\n\t\t'When to use: the user explicitly asks to deploy (\"ship it\", \"redeploy\", \"kick off a new build\"). For services with auto-deploy enabled, a fresh git push already triggers a deploy automatically — only call this for manual triggers, cache-clearing, or after a config change.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - clear_cache (optional): boolean — discard the cached build layers. Default false.',\n\t\t'',\n\t\t'Returns: { deploy: Deploy } — the new deploy record. Status will start as \"pending\" then transition through \"building\" → \"deploying\" → \"live\" or \"failed\".',\n\t\t'',\n\t\t'Example: trigger_deploy({ service_id: \"svc_abc\" }) → { deploy: { publicId: \"dpl_…\", status: \"pending\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tclear_cache: z.boolean().optional().describe('Clear the build cache (default false).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { clearCache?: boolean } = {};\n\t\tif (args.clear_cache !== undefined) input.clearCache = args.clear_cache;\n\t\tconst response = await ctx.hoststack.deploys.trigger(teamId, args.service_id, input);\n\t\tconst data = { deploy: shapeDeploy(response.deploy) };\n\t\tconst publicId =\n\t\t\tdata.deploy && 'publicId' in data.deploy\n\t\t\t\t? (data.deploy as { publicId: string }).publicId\n\t\t\t\t: 'unknown';\n\t\treturn respond({\n\t\t\tsummary: `Triggered deploy ${publicId} on service ${args.service_id}.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'cancel_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Cancel a running deploy. Stops the build/deploy pipeline mid-flight; the previously live revision keeps serving traffic.',\n\t\t'',\n\t\t'When to use: the user notices a bad commit was pushed and wants to abort before it lands, or a build is hanging. Has no effect on already-finished deploys.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy to cancel.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: cancel_deploy({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.deploys.cancel(teamId, args.service_id, args.deploy_id);\n\t\treturn respond({\n\t\t\tsummary: `Cancelled deploy ${args.deploy_id} on service ${args.service_id}.`,\n\t\t\tdata: { ok: true },\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'get_deploy_logs',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Fetch the build/deploy logs for a single deploy. Returns the entire log buffer the agent can the search for errors.',\n\t\t'',\n\t\t\"When to use: a deploy failed and you need to read the build output to diagnose. Pair with get_deploy to find a failed deploy_id, then call this. For runtime (post-deploy) logs of the running container, use get_service_logs instead.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy.',\n\t\t'',\n\t\t'Returns: { logs: string } — full build output as a single string. May be truncated by the API if the deploy is still in progress.',\n\t\t'',\n\t\t'Example: get_deploy_logs({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { logs: \"Building…\\\\nStep 1/8…\\\\n…\" }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.getLogs(teamId, args.service_id, args.deploy_id);\n\t\tconst logs = typeof response.logs === 'string' ? response.logs : '';\n\t\tconst lines = logs ? logs.split('\\n').length : 0;\n\t\treturn respond({\n\t\t\tsummary: `Fetched ${lines} log line${lines === 1 ? '' : 's'} for deploy ${args.deploy_id}.`,\n\t\t\tdata: { logs },\n\t\t});\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDomain, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_domains',\n\tcategory: 'domains',\n\tdescription: [\n\t\t\"List every custom domain attached to the team's services.\",\n\t\t'',\n\t\t'When to use: enumerate live domains, audit DNS verification status, or find which service a hostname resolves to before troubleshooting routing.',\n\t\t'',\n\t\t'Returns: { items: Domain[] } — id, publicId, hostname, serviceId, verified, dnsTargets, sslStatus, createdAt.',\n\t\t'',\n\t\t'Example: list_domains() → { items: [{ hostname: \"api.example.com\", verified: true, sslStatus: \"active\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.domains.list(teamId);\n\t\tconst data = shapeList(response, 'domains', shapeDomain);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No custom domains configured.'\n\t\t\t\t: `Found ${data.items.length} custom domain${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'add_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Attach a custom hostname to the team — optionally pinned to a specific service. After adding, point your DNS at the targets returned and call verify_domain.',\n\t\t'',\n\t\t\"When to use: the user wants to put a custom domain in front of a HostStack service (e.g. point api.example.com at svc_abc). The hostname must be unique across the team.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - hostname: the domain to add (e.g. \"api.example.com\").',\n\t\t' - service_id (optional): publicId of the service to bind to. If omitted, the domain is added unbound and you can attach it later with update_domain.',\n\t\t'',\n\t\t'Returns: { domain: Domain } — includes dnsTargets you must configure (CNAME / A records).',\n\t\t'',\n\t\t'Example: add_domain({ hostname: \"api.example.com\", service_id: \"svc_abc\" }) → { domain: { hostname: \"api.example.com\", dnsTargets: [...], verified: false, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\thostname: z\n\t\t\t.string()\n\t\t\t.min(3)\n\t\t\t.max(253)\n\t\t\t.describe('Fully-qualified hostname (e.g. api.example.com).'),\n\t\tservice_id: z.string().optional().describe('Optional service publicId to bind to.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { domain: string; serviceId?: string } = { domain: args.hostname };\n\t\tif (args.service_id !== undefined) input.serviceId = args.service_id;\n\t\tconst response = await ctx.hoststack.domains.add(teamId, input);\n\t\tconst data = { domain: shapeDomain(response.domain) };\n\t\treturn respond({\n\t\t\tsummary: `Added domain ${args.hostname}. Configure DNS, then call verify_domain.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'verify_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Trigger DNS verification for a previously-added domain. HostStack checks that the dnsTargets returned by add_domain are configured at the registrar.',\n\t\t'',\n\t\t'When to use: the user has set up DNS records and is ready to flip the domain live. Returns success when verification passes; the domain stays in pending state if DNS is still propagating.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - domain_id: publicId of the domain (from list_domains or add_domain).',\n\t\t'',\n\t\t'Returns: { ok: true }. Re-call list_domains to inspect the updated verified flag and SSL status.',\n\t\t'',\n\t\t'Example: verify_domain({ domain_id: \"dom_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tdomain_id: z.string().describe('Domain publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.domains.verify(teamId, args.domain_id);\n\t\treturn respond({ summary: `Triggered DNS verification for ${args.domain_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'remove_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Detach a custom hostname from the team. DESTRUCTIVE: the domain stops routing immediately and any pinned service must fall back to its default hostname.',\n\t\t'',\n\t\t\"When to use: the user wants to retire a custom domain. Confirm with the user first — the change is immediate and cannot be undone except by re-adding the domain and re-verifying DNS.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - domain_id: publicId of the domain to remove.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: remove_domain({ domain_id: \"dom_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tdomain_id: z.string().describe('Domain publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.domains.remove(teamId, args.domain_id);\n\t\treturn respond({ summary: `Removed domain ${args.domain_id}.`, data: { ok: true } });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond, respondError } from '../lib/respond.js';\nimport { shapeEnvVar, shapeList } from '../lib/shape.js';\n\ninterface ExistingEnvVar {\n\tid: number;\n\tpublicId?: string;\n\tkey: string;\n\tisSecret: boolean;\n}\n\ndefineTool({\n\tname: 'list_env_vars',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'List environment variables for a service. Secret values are masked server-side (\"••••••\"); only non-secret values come through in the clear.',\n\t\t'',\n\t\t'When to use: auditing what configuration a service has, finding the key for a value the user mentions by name, or confirming a variable was set after a write. Never assume the value field is plaintext for secret rows — it is masked.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { items: EnvVar[] } — id, publicId, key, value (masked if isSecret), isSecret, target, linkedDatabaseId, createdAt.',\n\t\t'',\n\t\t'Example: list_env_vars({ service_id: \"svc_abc\" }) → { items: [{ key: \"DATABASE_URL\", value: \"••••••\", isSecret: true }, { key: \"PORT\", value: \"3000\", isSecret: false }] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst data = shapeList(response, 'envVars', shapeEnvVar);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No env vars set on service ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} env var${data.items.length === 1 ? '' : 's'} on service ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'set_env_var',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Upsert a single environment variable on a service: creates the key if missing, updates the value if it already exists. Match is by key (case-sensitive).',\n\t\t'',\n\t\t'When to use: rotate a secret, add a new config knob, or change a value the user dictated. The MCP layer looks up the existing var by key first; you do not need to know the env-var ID.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - key: env-var name (e.g. \"DATABASE_URL\").',\n\t\t' - value: new value (will be encrypted at rest if is_secret=true).',\n\t\t' - is_secret (optional): true marks the value as secret (masked on read). Default true for safety; pass false for boring config like PORT or NODE_ENV.',\n\t\t'',\n\t\t'Returns: { envVar: EnvVar, action: \"created\" | \"updated\" }.',\n\t\t'',\n\t\t'Example: set_env_var({ service_id: \"svc_abc\", key: \"DATABASE_URL\", value: \"postgres://…\", is_secret: true }) → { envVar: { key: \"DATABASE_URL\", value: \"••••••\", … }, action: \"updated\" }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().min(1).max(128).describe('Env-var key.'),\n\t\tvalue: z.string().describe('New value.'),\n\t\tis_secret: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe('Mark as secret (encrypted, masked on read). Default true.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst isSecret = args.is_secret ?? true;\n\t\tconst existing = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst match = (existing.envVars as ExistingEnvVar[]).find((v) => v.key === args.key);\n\n\t\tif (match) {\n\t\t\tconst response = await ctx.hoststack.envVars.update(teamId, args.service_id, String(match.id), {\n\t\t\t\tvalue: args.value,\n\t\t\t\tisSecret,\n\t\t\t});\n\t\t\tconst data = {\n\t\t\t\tenvVar: shapeEnvVar(response.envVar),\n\t\t\t\taction: 'updated' as const,\n\t\t\t};\n\t\t\treturn respond({ summary: `Updated ${args.key} on service ${args.service_id}.`, data });\n\t\t}\n\n\t\tconst response = await ctx.hoststack.envVars.create(teamId, args.service_id, {\n\t\t\tkey: args.key,\n\t\t\tvalue: args.value,\n\t\t\tisSecret,\n\t\t});\n\t\tconst data = {\n\t\t\tenvVar: shapeEnvVar(response.envVar),\n\t\t\taction: 'created' as const,\n\t\t};\n\t\treturn respond({ summary: `Created ${args.key} on service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'delete_env_var',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Remove an environment variable from a service by key (case-sensitive).',\n\t\t'',\n\t\t'When to use: cleaning up unused config, or rotating away from a leaked secret. The MCP looks up the env-var ID from the key automatically.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - key: env-var name to delete.',\n\t\t'',\n\t\t'Returns: { ok: true } on success. Returns an error if the key was not found.',\n\t\t'',\n\t\t'Example: delete_env_var({ service_id: \"svc_abc\", key: \"OLD_FLAG\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().min(1).max(128).describe('Env-var key to delete.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst existing = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst match = (existing.envVars as ExistingEnvVar[]).find((v) => v.key === args.key);\n\t\tif (!match) {\n\t\t\treturn respondError(\n\t\t\t\t`Env var \"${args.key}\" not found on service ${args.service_id}.`,\n\t\t\t\t{ key: args.key, service_id: args.service_id },\n\t\t\t);\n\t\t}\n\t\tawait ctx.hoststack.envVars.delete(teamId, args.service_id, String(match.id));\n\t\treturn respond({\n\t\t\tsummary: `Deleted ${args.key} from service ${args.service_id}.`,\n\t\t\tdata: { ok: true },\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'bulk_set_env_vars',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Replace the entire env-var set on a service with the given list. Equivalent to deleting all current vars and creating the supplied ones — use with care.',\n\t\t'',\n\t\t\"When to use: importing a .env file, mirroring config from a sibling service, or doing a clean reset. For incremental changes, use set_env_var per key — bulk_set is destructive for any key not in the supplied list.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - env_vars: array of { key, value, is_secret? }. is_secret defaults to true per row.',\n\t\t'',\n\t\t'Returns: { ok: true }. Re-list with list_env_vars to confirm the new state.',\n\t\t'',\n\t\t'Example: bulk_set_env_vars({ service_id: \"svc_abc\", env_vars: [{ key: \"PORT\", value: \"3000\", is_secret: false }, { key: \"DATABASE_URL\", value: \"…\", is_secret: true }] }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tenv_vars: z\n\t\t\t.array(\n\t\t\t\tz.object({\n\t\t\t\t\tkey: z.string().min(1).max(128),\n\t\t\t\t\tvalue: z.string(),\n\t\t\t\t\tis_secret: z.boolean().optional(),\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.max(500)\n\t\t\t.describe('Array of env-var rows. Hard cap 500.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst payload = {\n\t\t\tenvVars: args.env_vars.map((v) => {\n\t\t\t\tconst row: { key: string; value: string; isSecret?: boolean } = {\n\t\t\t\t\tkey: v.key,\n\t\t\t\t\tvalue: v.value,\n\t\t\t\t};\n\t\t\t\tif (v.is_secret !== undefined) row.isSecret = v.is_secret;\n\t\t\t\treturn row;\n\t\t\t}),\n\t\t};\n\t\tawait ctx.hoststack.envVars.bulkSet(teamId, args.service_id, payload);\n\t\treturn respond({\n\t\t\tsummary: `Replaced env-var set on service ${args.service_id} with ${args.env_vars.length} entr${args.env_vars.length === 1 ? 'y' : 'ies'}.`,\n\t\t\tdata: { ok: true, count: args.env_vars.length },\n\t\t});\n\t},\n});\n","import { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeTeam, shapeUser } from '../lib/shape.js';\n\ninterface MeResponse {\n\tuser: unknown;\n\tteam?: unknown;\n}\n\ndefineTool({\n\tname: 'get_me',\n\tcategory: 'meta',\n\tdescription: [\n\t\t\"Return the user and team identity bound to the current API key. Useful at the start of a conversation to confirm which account the agent is operating on, especially when a user has multiple HostStack environments.\",\n\t\t'',\n\t\t'When to use: orient yourself at the start of a session, confirm which team the API key targets, or surface the email/team-name in a reply to the user.',\n\t\t'',\n\t\t'Returns: { user: { id, email, name, ... }, team?: { id, publicId, name, plan, ... } }.',\n\t\t'',\n\t\t'Example: get_me() → { user: { id: 1, email: \"ada@…\", … }, team: { id: 7, name: \"acme\", plan: \"pro\" } }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst me = await ctx.api.get<MeResponse>('/api/auth/me');\n\t\tconst data: { user: ReturnType<typeof shapeUser>; team?: ReturnType<typeof shapeTeam> } = {\n\t\t\tuser: shapeUser(me.user),\n\t\t};\n\t\tif (me.team) data.team = shapeTeam(me.team);\n\t\tconst teamLabel =\n\t\t\tme.team && typeof me.team === 'object' && 'name' in me.team\n\t\t\t\t? ` on team ${(me.team as { name: string }).name}`\n\t\t\t\t: '';\n\t\tconst userEmail =\n\t\t\tme.user && typeof me.user === 'object' && 'email' in me.user\n\t\t\t\t? (me.user as { email: string }).email\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Authenticated as ${userEmail}${teamLabel}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeList, shapeProject } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_projects',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'List every project in the active HostStack team.',\n\t\t'',\n\t\t'When to use: the agent needs an overview of what projects exist before drilling into services, deploys, or databases. Use this as the first step when the user mentions a project by name and you need to resolve its ID.',\n\t\t'',\n\t\t'Returns: { items: Project[] } — each project includes id, publicId, name, description, createdAt.',\n\t\t'',\n\t\t'Example: list_projects() → { items: [{ id: 12, publicId: \"prj_…\", name: \"billing-api\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.projects.list(teamId);\n\t\tconst data = shapeList(response, 'projects', shapeProject);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No projects yet — create one in the dashboard or via create_project.'\n\t\t\t\t: `Found ${data.items.length} project${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'create_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Create a new project (logical grouping of services + databases).',\n\t\t'',\n\t\t\"When to use: the user wants to set up a new app or environment in HostStack. Projects are a free organisational layer — they don't cost anything until you add services or databases inside them.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - name: human-readable project name (1–60 chars).',\n\t\t' - description (optional): short blurb shown in the dashboard.',\n\t\t' - region (optional): \"fsn1\" (Falkenstein) | \"nbg1\" (Nuremberg) | \"hel1\" (Helsinki). Default depends on team plan.',\n\t\t'',\n\t\t'Returns: { project: Project } — includes the new id and publicId.',\n\t\t'',\n\t\t'Example: create_project({ name: \"billing-api\", description: \"Stripe webhooks\", region: \"fsn1\" }) → { project: { id: 12, publicId: \"prj_…\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tname: z.string().min(1).max(60).describe('Project name (1–60 chars).'),\n\t\tdescription: z.string().max(500).optional().describe('Short description (≤500 chars).'),\n\t\tregion: z\n\t\t\t.enum(['fsn1', 'nbg1', 'hel1'])\n\t\t\t.optional()\n\t\t\t.describe('Hetzner region: fsn1 | nbg1 | hel1.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { name: string; description?: string; region?: string } = { name: args.name };\n\t\tif (args.description !== undefined) input.description = args.description;\n\t\tif (args.region !== undefined) input.region = args.region;\n\t\tconst response = await ctx.hoststack.projects.create(teamId, input);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\tconst publicId =\n\t\t\tdata.project && 'publicId' in data.project\n\t\t\t\t? (data.project as { publicId: string }).publicId\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Created project \"${args.name}\" (${publicId}).`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Rename a project or update its description.',\n\t\t'',\n\t\t'When to use: the user wants to fix a typo in a project name, attach a clearer description, or align the dashboard label with their internal naming.',\n\t\t'',\n\t\t'Inputs (all optional, at least one required):',\n\t\t' - project_id: publicId of the project (required).',\n\t\t' - name: new name (1–60 chars).',\n\t\t' - description: new description (≤500 chars).',\n\t\t'',\n\t\t'Returns: { project: Project } — the updated record.',\n\t\t'',\n\t\t'Example: update_project({ project_id: \"prj_abc\", name: \"billing-prod\" }) → { project: { name: \"billing-prod\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.string().describe('Project publicId.'),\n\t\tname: z.string().min(1).max(60).optional().describe('New name (1–60 chars).'),\n\t\tdescription: z.string().max(500).optional().describe('New description (≤500 chars).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tif (args.name === undefined && args.description === undefined) {\n\t\t\treturn respond({\n\t\t\t\tsummary: 'No fields to update — pass `name` and/or `description`.',\n\t\t\t\tdata: {},\n\t\t\t});\n\t\t}\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { name?: string; description?: string } = {};\n\t\tif (args.name !== undefined) input.name = args.name;\n\t\tif (args.description !== undefined) input.description = args.description;\n\t\tconst response = await ctx.hoststack.projects.update(teamId, args.project_id, input);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\treturn respond({ summary: `Updated project ${args.project_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Fetch a single project by ID. Includes name, description, and timestamps.',\n\t\t'',\n\t\t'When to use: confirming a project exists before creating resources inside it, or pulling the canonical name/description for a reply to the user.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - project_id: publicId of the project (e.g. \"prj_abc123\").',\n\t\t'',\n\t\t'Returns: { project: Project }.',\n\t\t'',\n\t\t'Example: get_project({ project_id: \"prj_abc\" }) → { project: { id: 12, name: \"billing\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.string().describe('Project publicId (e.g. prj_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.projects.get(teamId, args.project_id);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\tconst name =\n\t\t\tdata.project && 'name' in data.project\n\t\t\t\t? (data.project as { name: string }).name\n\t\t\t\t: args.project_id;\n\t\treturn respond({ summary: `Project \"${name}\".`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shape, shapeList, shapeService } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_services',\n\tcategory: 'services',\n\tdescription: [\n\t\t'List every service (web, worker, cron, private) in the active HostStack team.',\n\t\t'',\n\t\t'When to use: the agent needs to find a service by name, check what is deployed, or pick a target for a follow-up tool (logs, deploys, env vars). This is the canonical way to resolve a publicId from a human-friendly name.',\n\t\t'',\n\t\t'Returns: { items: Service[] } — each service includes id, publicId, name, type, status, projectId, repoUrl, branch, runtime, createdAt.',\n\t\t'',\n\t\t'Example: list_services() → { items: [{ id: 31, publicId: \"svc_…\", name: \"api\", type: \"web\", status: \"running\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.list(teamId);\n\t\tconst data = shapeList(response, 'services', shapeService);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No services yet — create one with create_service or via the dashboard.'\n\t\t\t\t: `Found ${data.items.length} service${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Fetch a single service by ID, including its current status and configuration summary.',\n\t\t'',\n\t\t'When to use: drilling into a service after list_services, checking deploy/runtime status, or grabbing the repo+branch before triggering a deploy.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service (e.g. \"svc_abc123\").',\n\t\t'',\n\t\t'Returns: { service: Service } — type, status, runtime, repoUrl, branch, autoDeploy, region, plan, createdAt, updatedAt.',\n\t\t'',\n\t\t'Example: get_service({ service_id: \"svc_abc\" }) → { service: { type: \"web\", status: \"running\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.get(teamId, args.service_id);\n\t\tconst data = { service: shapeService(response.service) };\n\t\tconst status =\n\t\t\tdata.service && 'status' in data.service\n\t\t\t\t? (data.service as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Service ${args.service_id} is ${status}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service_metrics',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Fetch the latest CPU, memory, network, and request-rate metrics for a service.',\n\t\t'',\n\t\t'When to use: a service is reportedly slow, you suspect resource pressure, or you want a quick health snapshot before scaling. Returns a single point-in-time sample, not a time series.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { metrics: { cpu, memory, network, requests } } — values are normalised utilisation/throughput numbers.',\n\t\t'',\n\t\t'Example: get_service_metrics({ service_id: \"svc_abc\" }) → { metrics: { cpu: 0.42, memory: 0.71, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.getMetrics(teamId, args.service_id);\n\t\tconst data = { metrics: shape(response.metrics) };\n\t\treturn respond({ summary: `Metrics snapshot for service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Rename a service. Only the human-readable name changes — the publicId is permanent.',\n\t\t'',\n\t\t'When to use: the user wants to relabel a service in the dashboard. For deeper config edits (build command, branch, scale, plan), use update_service_config.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - name: new name (1–60 chars).',\n\t\t'',\n\t\t'Returns: { service: Service }.',\n\t\t'',\n\t\t'Example: update_service({ service_id: \"svc_abc\", name: \"api-prod\" }) → { service: { name: \"api-prod\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tname: z.string().min(1).max(60).describe('New service name (1–60 chars).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.update(teamId, args.service_id, {\n\t\t\tname: args.name,\n\t\t});\n\t\tconst data = { service: shapeService(response.service) };\n\t\treturn respond({ summary: `Renamed service ${args.service_id} to \"${args.name}\".`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_service_config',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Update build/runtime configuration for a service: build command, start command, branch, root directory, dockerfile path, auto-deploy flag, instance count, plan tier. All fields optional — pass only what you want to change.',\n\t\t'',\n\t\t\"When to use: the user wants to tweak how a service builds or runs without redeploying manually. Updating any field marked dispatch-eligible (branch, build/start command, plan, root, dockerfile) typically triggers a follow-up deploy automatically; instance count scales without redeploying.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - build_command, start_command (optional): shell commands.',\n\t\t' - branch (optional): git branch to track.',\n\t\t' - root_directory, dockerfile_path (optional): build context overrides.',\n\t\t' - auto_deploy (optional): boolean — auto-deploy on git push.',\n\t\t' - instance_count (optional): integer ≥1 — manual scale.',\n\t\t' - plan (optional): plan tier slug (e.g. \"starter\", \"standard\", \"pro\").',\n\t\t'',\n\t\t'Returns: { config: ServiceConfig } — the updated config record.',\n\t\t'',\n\t\t'Example: update_service_config({ service_id: \"svc_abc\", instance_count: 3 }) → { config: { instanceCount: 3, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tbuild_command: z.string().optional().describe('Build shell command.'),\n\t\tstart_command: z.string().optional().describe('Start shell command.'),\n\t\tbranch: z.string().optional().describe('Git branch to track.'),\n\t\troot_directory: z.string().optional().describe('Build context root.'),\n\t\tdockerfile_path: z.string().optional().describe('Path to Dockerfile relative to root.'),\n\t\tauto_deploy: z.boolean().optional().describe('Auto-deploy on push.'),\n\t\tinstance_count: z.number().int().positive().optional().describe('Manual scale (≥1).'),\n\t\tplan: z.string().optional().describe('Plan tier slug.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: Record<string, unknown> = {};\n\t\tif (args.build_command !== undefined) input['buildCommand'] = args.build_command;\n\t\tif (args.start_command !== undefined) input['startCommand'] = args.start_command;\n\t\tif (args.branch !== undefined) input['branch'] = args.branch;\n\t\tif (args.root_directory !== undefined) input['rootDirectory'] = args.root_directory;\n\t\tif (args.dockerfile_path !== undefined) input['dockerfilePath'] = args.dockerfile_path;\n\t\tif (args.auto_deploy !== undefined) input['autoDeploy'] = args.auto_deploy;\n\t\tif (args.instance_count !== undefined) input['instanceCount'] = args.instance_count;\n\t\tif (args.plan !== undefined) input['plan'] = args.plan;\n\t\tif (Object.keys(input).length === 0) {\n\t\t\treturn respond({ summary: 'No fields to update.', data: {} });\n\t\t}\n\t\tconst response = await ctx.hoststack.services.updateConfig(teamId, args.service_id, input);\n\t\tconst data = { config: shape(response.config) };\n\t\tconst fields = Object.keys(input).join(', ');\n\t\treturn respond({ summary: `Updated ${fields} on service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'suspend_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Suspend a service: stop all running instances and pause auto-deploys. The service stays configured and can be resumed later with resume_service.',\n\t\t'',\n\t\t'When to use: the user wants to temporarily stop traffic and billing without deleting the service (for example: dev environment overnight, debugging).',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: suspend_service({ service_id: \"svc_dev\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.services.suspend(teamId, args.service_id);\n\t\treturn respond({ summary: `Suspended service ${args.service_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'resume_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Resume a previously suspended service: start instances back up and re-enable auto-deploys.',\n\t\t'',\n\t\t'When to use: the user wants to bring a suspended service back online. Pair with suspend_service.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: resume_service({ service_id: \"svc_dev\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.services.resume(teamId, args.service_id);\n\t\treturn respond({ summary: `Resumed service ${args.service_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service_logs',\n\tcategory: 'logs',\n\tdescription: [\n\t\t\"Fetch a snapshot of the running container's recent runtime logs (stdout/stderr). For *deploy* logs (build output), use get_deploy_logs instead.\",\n\t\t'',\n\t\t'When to use: a service is misbehaving in production and you need to read what it is currently logging. The tool returns a snapshot — there is no streaming over MCP. Re-call to get newer entries.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - lines (optional): tail size (default 200, max 1000).',\n\t\t' - since (optional): ISO-8601 timestamp; only return entries newer than this.',\n\t\t' - stream (optional): \"stdout\" | \"stderr\". Omit to combine.',\n\t\t'',\n\t\t'Returns: { logs: LogEntry[] | string } — each entry has { timestamp, level?, stream?, message }. Older HostStack agents return a single string blob.',\n\t\t'',\n\t\t'Example: get_service_logs({ service_id: \"svc_abc\", lines: 100 }) → { logs: [{ timestamp: \"2026-04-25T…\", message: \"GET /health 200\" }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tlines: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(1000)\n\t\t\t.optional()\n\t\t\t.describe('Tail size; default 200, hard cap 1000.'),\n\t\tsince: z.string().datetime().optional().describe('ISO-8601 timestamp lower bound.'),\n\t\tstream: z.enum(['stdout', 'stderr']).optional().describe('Restrict to one stream.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst opts: { lines?: number; since?: string; stream?: 'stdout' | 'stderr' } = {\n\t\t\tlines: args.lines ?? 200,\n\t\t};\n\t\tif (args.since) opts.since = args.since;\n\t\tif (args.stream) opts.stream = args.stream;\n\t\tconst response = await ctx.hoststack.services.getRuntimeLogs(teamId, args.service_id, opts);\n\t\tconst count = Array.isArray(response.logs)\n\t\t\t? response.logs.length\n\t\t\t: typeof response.logs === 'string'\n\t\t\t\t? response.logs.split('\\n').length\n\t\t\t\t: 0;\n\t\treturn respond({\n\t\t\tsummary: `Fetched ${count} log line${count === 1 ? '' : 's'} for service ${args.service_id}.`,\n\t\t\tdata: { logs: response.logs },\n\t\t});\n\t},\n});\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","z","response","data","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/server-factory.ts","../src/api-client.ts","../src/prompts/registry.ts","../src/resources/registry.ts","../src/registry.ts","../src/prompts/deploy-prompts.ts","../src/lib/shape.ts","../src/resources/hoststack-resources.ts","../src/tools/activity-log.ts","../src/lib/respond.ts","../src/tools/cron.ts","../src/tools/databases.ts","../src/tools/deploys.ts","../src/tools/domains.ts","../src/tools/env-vars.ts","../src/tools/meta.ts","../src/tools/projects.ts","../src/tools/services.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { HostStack } from '@hoststack.dev/sdk';\n\nimport { ApiClient } from './api-client.js';\nimport { attachPrompts } from './prompts/registry.js';\nimport { attachResources } from './resources/registry.js';\nimport { attachTools, type ToolCallSink, type ToolContext } from './registry.js';\n\nexport type { ToolCallEvent, ToolCallSink } from './registry.js';\n\n// Importing each tool/prompt/resource module runs its top-level define*()\n// calls and populates the shared registries. ESM caches modules, so each\n// registry is built exactly once per process.\nimport './prompts/deploy-prompts.js';\nimport './resources/hoststack-resources.js';\nimport './tools/activity-log.js';\nimport './tools/cron.js';\nimport './tools/databases.js';\nimport './tools/deploys.js';\nimport './tools/domains.js';\nimport './tools/env-vars.js';\nimport './tools/meta.js';\nimport './tools/projects.js';\nimport './tools/services.js';\n\nexport interface CreateServerOptions {\n\t/** HostStack API key (hs_live_… or hs_test_…). Required. */\n\tapiKey: string;\n\t/** Base URL for the HostStack API. Defaults to https://hoststack.dev */\n\tbaseUrl?: string;\n\t/**\n\t * Server identity advertised in the MCP `initialize` response. Defaults\n\t * to `{ name: \"hoststack\", version: PACKAGE_VERSION }`.\n\t */\n\tserverInfo?: { name: string; version: string };\n\t/**\n\t * Optional telemetry sink invoked once per tool call (success or failure).\n\t * Runs on the microtask queue; sink errors are swallowed so tool execution\n\t * never blocks on telemetry.\n\t */\n\tonToolCall?: ToolCallSink;\n}\n\nexport const PACKAGE_NAME = 'hoststack';\nexport const PACKAGE_VERSION = '0.1.2';\n\ninterface MeResponse {\n\tuser: { id: number };\n\tteam?: { id: number };\n}\n\n/**\n * Build a fully-wired MCP server. Used by both the stdio CLI entry-point and\n * the HTTP transport mounted by the API server. A new server (and its\n * underlying SDK + ApiClient) is created per call, so the HTTP transport can\n * scope each connection to a single API key without cross-contamination.\n */\nexport function createMcpServer(options: CreateServerOptions): McpServer {\n\tconst baseUrl = (options.baseUrl ?? 'https://hoststack.dev').replace(/\\/$/, '');\n\tconst hoststack = new HostStack({ apiKey: options.apiKey, baseUrl });\n\tconst api = new ApiClient(options.apiKey, baseUrl);\n\n\tconst server = new McpServer({\n\t\tname: options.serverInfo?.name ?? PACKAGE_NAME,\n\t\tversion: options.serverInfo?.version ?? PACKAGE_VERSION,\n\t});\n\n\t// Cache the team lookup. The first tool call pays one /auth/me round-trip;\n\t// every subsequent call reuses the cached promise. We store the in-flight\n\t// promise (not the resolved value) so concurrent first-calls don't fan out\n\t// into duplicate /auth/me requests.\n\tlet teamIdPromise: Promise<number> | null = null;\n\tconst resolveTeamId = (): Promise<number> => {\n\t\tif (!teamIdPromise) {\n\t\t\tteamIdPromise = api.get<MeResponse>('/api/auth/me').then((me) => {\n\t\t\t\tif (!me.team?.id) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'No team bound to API key. Generate a team-scoped key in the dashboard.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn me.team.id;\n\t\t\t});\n\t\t\t// If the lookup fails, clear the cache so a retry can succeed once\n\t\t\t// the user fixes their key. Without this, every subsequent tool\n\t\t\t// call would re-throw the same cached rejection.\n\t\t\tteamIdPromise.catch(() => {\n\t\t\t\tteamIdPromise = null;\n\t\t\t});\n\t\t}\n\t\treturn teamIdPromise;\n\t};\n\n\tconst ctx: ToolContext = { hoststack, api, resolveTeamId };\n\tattachTools(server, ctx, options.onToolCall);\n\tattachPrompts(server, ctx);\n\tattachResources(server, ctx);\n\n\treturn server;\n}\n","/**\n * Lightweight API client for HostStack endpoints not yet covered by the SDK\n * (logs snapshots, activity log, runtime metrics, /me lookup). Uses the same\n * auth and base URL as the SDK instance.\n */\nexport class ApiClient {\n\tconstructor(\n\t\tprivate readonly apiKey: string,\n\t\tprivate readonly baseUrl: string,\n\t) {}\n\n\tprivate get headers(): Record<string, string> {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tif (params) {\n\t\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\t\tif (value !== undefined) url.searchParams.set(key, String(value));\n\t\t\t}\n\t\t}\n\t\tconst res = await fetch(url.toString(), { headers: this.headers });\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\tconst init: RequestInit = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: this.headers,\n\t\t};\n\t\tif (body !== undefined) init.body = JSON.stringify(body);\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, init);\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync patch<T>(path: string, body: unknown): Promise<T> {\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'PATCH',\n\t\t\theaders: this.headers,\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t\treturn this.handle<T>(res);\n\t}\n\n\tasync delete<T>(path: string): Promise<T> {\n\t\tconst res = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'DELETE',\n\t\t\theaders: this.headers,\n\t\t});\n\t\treturn this.handle<T>(res);\n\t}\n\n\tprivate async handle<T>(res: Response): Promise<T> {\n\t\tif (!res.ok) {\n\t\t\tconst error = (await res.json().catch(() => ({ error: res.statusText }))) as {\n\t\t\t\terror?: string;\n\t\t\t};\n\t\t\tthrow new Error(error.error ?? `API error: ${res.status}`);\n\t\t}\n\t\tif (res.status === 204) {\n\t\t\treturn undefined as T;\n\t\t}\n\t\treturn res.json() as Promise<T>;\n\t}\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\nimport type { ZodRawShape, z } from 'zod';\n\nimport type { ApiClient } from '../api-client.js';\n\nexport interface PromptContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface InternalPromptDefinition {\n\tname: string;\n\tdescription: string;\n\targs: ZodRawShape;\n\thandler: (\n\t\targs: Record<string, string | undefined>,\n\t\tctx: PromptContext,\n\t) => Promise<GetPromptResult>;\n}\n\nexport type PromptDefinition = Readonly<InternalPromptDefinition>;\n\nconst prompts: InternalPromptDefinition[] = [];\n\n/**\n * Register a single prompt. The generic over `TArgs` lets the handler receive\n * precisely-typed args while the registry stores the widened shape — same\n * trick as `defineTool` to keep the compiler's instantiation budget in check.\n */\nexport function definePrompt<TArgs extends ZodRawShape>(def: {\n\tname: string;\n\tdescription: string;\n\targs: TArgs;\n\thandler: (args: z.infer<z.ZodObject<TArgs>>, ctx: PromptContext) => Promise<GetPromptResult>;\n}): void {\n\tprompts.push({\n\t\tname: def.name,\n\t\tdescription: def.description,\n\t\targs: def.args,\n\t\thandler: def.handler as InternalPromptDefinition['handler'],\n\t});\n}\n\nexport function listPromptDefinitions(): ReadonlyArray<PromptDefinition> {\n\treturn prompts;\n}\n\n/** Iterate the registry and wire each prompt into the MCP server. */\nexport function attachPrompts(server: McpServer, ctx: PromptContext): void {\n\ttype PromptMethod = (\n\t\tname: string,\n\t\tdescription: string,\n\t\targsSchema: ZodRawShape,\n\t\tcb: (args: Record<string, string | undefined>) => Promise<GetPromptResult>,\n\t) => unknown;\n\n\tconst register = server.prompt.bind(server) as unknown as PromptMethod;\n\n\tfor (const def of prompts) {\n\t\tregister(def.name, def.description, def.args, (args) => def.handler(args, ctx));\n\t}\n}\n\n/**\n * Helper to build a single user-role text message — the most common shape for\n * these prompts (we're guiding the agent, not modeling assistant responses).\n */\nexport function userMessage(text: string): GetPromptResult['messages'][number] {\n\treturn { role: 'user', content: { type: 'text', text } };\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\n\nimport type { ApiClient } from '../api-client.js';\n\ninterface ResourceContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface StaticResourceDef {\n\tkind: 'static';\n\tname: string;\n\turi: string;\n\tdescription: string;\n\tmimeType?: string;\n\tread: (uri: URL, ctx: ResourceContext) => Promise<ReadResourceResult>;\n}\n\nexport type ResourceDefinition = Readonly<StaticResourceDef>;\n\nconst resources: StaticResourceDef[] = [];\n\nexport function defineResource(def: StaticResourceDef): void {\n\tresources.push(def);\n}\n\nexport function listResourceDefinitions(): ReadonlyArray<ResourceDefinition> {\n\treturn resources;\n}\n\nexport function attachResources(server: McpServer, ctx: ResourceContext): void {\n\tfor (const def of resources) {\n\t\tserver.resource(\n\t\t\tdef.name,\n\t\t\tdef.uri,\n\t\t\t{\n\t\t\t\tdescription: def.description,\n\t\t\t\t...(def.mimeType ? { mimeType: def.mimeType } : {}),\n\t\t\t},\n\t\t\t(uri) => def.read(uri, ctx),\n\t\t);\n\t}\n}\n\n/**\n * Pack a JSON value into the resource read-result envelope. The MCP spec\n * requires `text` for application/json resources — we serialise here so each\n * resource handler stays a one-liner.\n */\nexport function jsonResource(uri: URL, data: unknown): ReadResourceResult {\n\treturn {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\turi: uri.toString(),\n\t\t\t\tmimeType: 'application/json',\n\t\t\t\ttext: JSON.stringify(data, null, 2),\n\t\t\t},\n\t\t],\n\t};\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { HostStack } from '@hoststack.dev/sdk';\nimport type { ZodRawShape, z } from 'zod';\n\nimport type { ApiClient } from './api-client.js';\n\nexport type ToolCategory =\n\t| 'projects'\n\t| 'services'\n\t| 'deploys'\n\t| 'databases'\n\t| 'domains'\n\t| 'env-vars'\n\t| 'cron'\n\t| 'logs'\n\t| 'activity-log'\n\t| 'meta';\n\nexport interface ToolContext {\n\thoststack: HostStack;\n\tapi: ApiClient;\n\t/**\n\t * Lazy resolver for the team ID bound to the API key. The agent never has\n\t * to pass `teamId` to a tool — every SDK route is team-scoped, so the MCP\n\t * looks it up once via `/api/auth/me` and caches it for the rest of the\n\t * server's lifetime. Throws if the API key is invalid or unbound.\n\t */\n\tresolveTeamId(): Promise<number>;\n}\n\ninterface InternalToolDefinition {\n\tname: string;\n\tcategory: ToolCategory;\n\tdescription: string;\n\tinput: ZodRawShape;\n\thandler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<CallToolResult>;\n}\n\nexport type ToolDefinition = Readonly<InternalToolDefinition>;\n\nconst tools: InternalToolDefinition[] = [];\n\n/**\n * Register a single tool definition. The generic over `TInput` lets the\n * handler receive precisely-typed arguments while the registry stores the\n * widened shape.\n */\nexport function defineTool<TInput extends ZodRawShape>(def: {\n\tname: string;\n\tcategory: ToolCategory;\n\tdescription: string;\n\tinput: TInput;\n\thandler: (args: z.infer<z.ZodObject<TInput>>, ctx: ToolContext) => Promise<CallToolResult>;\n}): void {\n\ttools.push({\n\t\tname: def.name,\n\t\tcategory: def.category,\n\t\tdescription: def.description,\n\t\tinput: def.input,\n\t\thandler: def.handler as InternalToolDefinition['handler'],\n\t});\n}\n\n/** Snapshot the currently-registered tool definitions (for tests / docs). */\nexport function listToolDefinitions(): ReadonlyArray<ToolDefinition> {\n\treturn tools;\n}\n\n/**\n * Telemetry event emitted once per tool invocation. The MCP package never\n * persists these — it just hands them to the optional `onToolCall` sink so\n * the host (HTTP transport, CLI, tests) can decide where they go.\n *\n * Privacy: `inputHash` is a hash over the JSON-stringified args; we never\n * expose the args themselves so PII from tool inputs (env-var values, domain\n * names) never reaches a sink.\n */\nexport interface ToolCallEvent {\n\ttool: string;\n\tdurationMs: number;\n\tok: boolean;\n\terrorCode: string | null;\n\tinputHash: string | null;\n\tstartedAt: Date;\n}\n\nexport type ToolCallSink = (event: ToolCallEvent) => void | Promise<void>;\n\n/** Iterate the registry and wire each tool into the MCP server. */\nexport function attachTools(server: McpServer, ctx: ToolContext, sink?: ToolCallSink): void {\n\ttype ToolMethod = (\n\t\tname: string,\n\t\tdescription: string,\n\t\tschema: ZodRawShape,\n\t\tcb: (args: Record<string, unknown>) => Promise<CallToolResult>,\n\t) => unknown;\n\n\tconst register = server.tool.bind(server) as unknown as ToolMethod;\n\n\tfor (const def of tools) {\n\t\tregister(def.name, def.description, def.input, async (args) => {\n\t\t\tconst startedAt = new Date();\n\t\t\tconst start = performance.now();\n\t\t\tlet ok = true;\n\t\t\tlet errorCode: string | null = null;\n\t\t\ttry {\n\t\t\t\tconst result = await def.handler(args, ctx);\n\t\t\t\tif (result.isError) {\n\t\t\t\t\tok = false;\n\t\t\t\t\terrorCode = 'tool_error';\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tok = false;\n\t\t\t\terrorCode =\n\t\t\t\t\terr instanceof Error ? (err.name || 'Error').slice(0, 64) : 'unknown_error';\n\t\t\t\tthrow err;\n\t\t\t} finally {\n\t\t\t\tif (sink) {\n\t\t\t\t\tconst durationMs = Math.round(performance.now() - start);\n\t\t\t\t\tconst event: ToolCallEvent = {\n\t\t\t\t\t\ttool: def.name,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tok,\n\t\t\t\t\t\terrorCode,\n\t\t\t\t\t\tinputHash: hashArgs(args),\n\t\t\t\t\t\tstartedAt,\n\t\t\t\t\t};\n\t\t\t\t\tPromise.resolve()\n\t\t\t\t\t\t.then(() => sink(event))\n\t\t\t\t\t\t.catch(() => undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n\nfunction hashArgs(args: Record<string, unknown>): string | null {\n\ttry {\n\t\tconst json = JSON.stringify(args);\n\t\tconst bunGlobal = (globalThis as { Bun?: { hash?: (data: string) => bigint } }).Bun;\n\t\tif (bunGlobal?.hash) {\n\t\t\treturn bunGlobal.hash(json).toString(16);\n\t\t}\n\t\treturn `len:${json.length}`;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { z } from 'zod';\n\nimport { definePrompt, userMessage } from './registry.js';\n\ndefinePrompt({\n\tname: 'diagnose_failed_deploy',\n\tdescription:\n\t\t\"Walk the agent through diagnosing a failed deploy: pull the latest deploys for the named service, find the most recent failure, fetch its build/deploy logs, and propose a fix. Stops at suggestion — does not retrigger automatically.\",\n\targs: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async ({ service_id }) => {\n\t\tconst text = `Goal: diagnose the most recent failed deploy on service ${service_id} and propose a fix.\n\nPlan (use these tools in order):\n1. \\`list_deploys({ service_id: \"${service_id}\" })\\` — pull recent deploys, newest first. Identify the most recent deploy with status \\`failed\\` (or \\`cancelled\\` if the user wants to investigate that too). Capture its publicId, branch, and commitSha.\n2. \\`get_deploy_logs({ service_id: \"${service_id}\", deploy_id: \"<dpl_…>\" })\\` — read the full build output. Scan for: stack traces, \"ERROR\" / \"error:\" lines, exit codes, missing env vars, OOM-killed signals, network failures pulling dependencies.\n3. \\`get_service({ service_id: \"${service_id}\" })\\` — confirm the service's runtime, plan, and whether autoDeploy is on. Plan tier matters because OOMs at small tiers point at \\`maxMemoryMb\\`.\n4. (Optional) \\`list_env_vars({ service_id: \"${service_id}\" })\\` — only if the build error mentions a missing variable. Don't fetch otherwise; values are masked anyway.\n\nThen write a short diagnosis for the user with three sections:\n- **Root cause** — one sentence pointing at the actual failure line.\n- **Evidence** — 3–6 line excerpt from the logs that proves the diagnosis.\n- **Suggested fix** — concrete next steps, including which tool to call (e.g. \"set MISSING_KEY with set_env_var, then trigger_deploy\"). Do NOT call trigger_deploy automatically; the user decides.\n\nIf the deploy logs are empty or only contain queued/pending markers, surface that — the build never started, which is its own class of bug (likely a builder-pool or quota issue).`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n\ndefinePrompt({\n\tname: 'deploy_status_check',\n\tdescription:\n\t\t\"Quick orientation prompt: who am I, what's running, and is anything currently deploying? Useful at the start of a session.\",\n\targs: {},\n\thandler: async () => {\n\t\tconst text = `Goal: produce a 30-second status check on this HostStack team.\n\nPlan:\n1. \\`get_me()\\` — confirm which user + team the API key belongs to.\n2. \\`list_services()\\` — every service with current status (running, suspended, building, deploying, failed). Note any service in a non-running state.\n3. For each service whose status is \\`building\\` or \\`deploying\\`, call \\`list_deploys({ service_id })\\` and surface the latest deploy's commitMessage + author.\n4. \\`list_activity_log({ per_page: 10 })\\` — last 10 audit events to spot recent changes (deploys triggered, env vars edited, services restarted).\n\nWrite a status report shaped like:\n\n> **Team**: <name>\n> **Services**: <n> total — <breakdown by status>\n> **In flight**: <list of building/deploying services with commit info, or \"none\">\n> **Recent activity**: <3-5 most relevant events from the audit log, newest first>\n\nKeep it tight (under 200 words). The user can drill in with follow-up tools.`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n\ndefinePrompt({\n\tname: 'rotate_secret',\n\tdescription:\n\t\t\"Guide the agent through rotating an env-var secret on a service. Lists current vars to confirm the target key exists, asks the user for the new value, sets it, and offers to trigger a deploy.\",\n\targs: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().describe('Env-var key to rotate (e.g. DATABASE_URL).'),\n\t},\n\thandler: async ({ service_id, key }) => {\n\t\tconst text = `Goal: rotate the secret \\`${key}\\` on service ${service_id}.\n\nPlan:\n1. \\`list_env_vars({ service_id: \"${service_id}\" })\\` — confirm \\`${key}\\` exists. Note its \\`isSecret\\` flag (it should be true; if not, flag this — you're about to mark it secret on rotation, which is a behaviour change).\n2. **Ask the user for the new value before calling any write tool.** The agent must NOT invent or generate the secret; it has to come from the user's clipboard / vault. Phrase the ask explicitly: \"Paste the new value for ${key} (it will be encrypted at rest and masked everywhere except the running container).\"\n3. Once the user provides the value:\n - \\`set_env_var({ service_id: \"${service_id}\", key: \"${key}\", value: \"<new value>\", is_secret: true })\\` — upserts by key.\n4. After the write succeeds, ask the user whether to redeploy (so the new value lands in the running container). If yes:\n - \\`trigger_deploy({ service_id: \"${service_id}\" })\\` — kicks off a build with the rotated secret.\n - \\`get_deploy({ service_id: \"${service_id}\", deploy_id: \"<dpl_…>\" })\\` — poll until status is \\`live\\` or \\`failed\\`. On failure, hand off to \\`diagnose_failed_deploy\\`.\n\nSafety rails:\n- Never echo the new value back in your reply; the user should verify it from their own source of truth, not from your context window.\n- If the user says \"generate a new one\", suggest \\`openssl rand -hex 32\\` (or similar) for them to run locally and paste in. Do NOT generate it for them — secrets that pass through an LLM context are no longer secrets.\n- If \\`set_env_var\\` returned \\`action: \"created\"\\` instead of \\`\"updated\"\\`, the key didn't exist before. Pause and confirm with the user — they may have typo'd the key name.`;\n\n\t\treturn { messages: [userMessage(text)] };\n\t},\n});\n","/**\n * Per-resource shape pickers. Each function takes a raw API/SDK response and\n * returns the agent-friendly subset: drops internal foreign keys (teamId,\n * userId, ...) and null-valued columns, leaves ISO-8601 timestamps as-is.\n *\n * Pickers must be permissive about input shape — different SDK methods may\n * return slightly different fields (e.g. list vs get) and the API may grow\n * fields over time. We never throw on missing fields.\n */\n\nconst INTERNAL_FIELDS = new Set([\n\t'teamId',\n\t'team_id',\n\t'userId',\n\t'user_id',\n\t'accountId',\n\t'account_id',\n\t'tenantId',\n\t'tenant_id',\n\t'createdById',\n\t'updatedById',\n]);\n\ntype Obj = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Obj {\n\treturn value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction dropNullsAndInternals(obj: Obj): Obj {\n\tconst out: Obj = {};\n\tfor (const [key, value] of Object.entries(obj)) {\n\t\tif (INTERNAL_FIELDS.has(key)) continue;\n\t\tif (value === null || value === undefined) continue;\n\t\tout[key] = value;\n\t}\n\treturn out;\n}\n\n/** Generic shape — drop internals, drop nulls, keep everything else. */\nexport function shape(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(shape);\n\tif (isObject(value)) return dropNullsAndInternals(value);\n\treturn value;\n}\n\nfunction shapeAll<T>(arr: unknown, shaper: (item: unknown) => T): T[] {\n\tif (!Array.isArray(arr)) return [];\n\treturn arr.map(shaper);\n}\n\n/**\n * Unwrap a HostStack list response. The API returns shapes like\n * `{ projects: [...] }`, `{ services: [...] }`, etc. — the key varies by\n * resource. Pass the key explicitly so the wrapper stays type-loose.\n */\nexport function shapeList<T>(\n\tresponse: unknown,\n\tkey: string,\n\tshaper: (item: unknown) => T,\n): { items: T[] } {\n\tif (!isObject(response)) return { items: [] };\n\treturn { items: shapeAll(response[key], shaper) };\n}\n\n// ──────────────────────────────────────────────────────────────────────\n// Per-resource pickers — typed convenience wrappers around shape().\n// All return a plain Obj (never null), keeping the registry handlers simple.\n// ──────────────────────────────────────────────────────────────────────\n\nexport function shapeProject(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeService(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDeploy(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDatabase(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeDomain(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeEnvVar(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeCronExecution(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeActivity(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeUser(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n\nexport function shapeTeam(value: unknown): Obj {\n\treturn isObject(value) ? dropNullsAndInternals(value) : {};\n}\n","import { shapeProject, shapeService, shapeTeam, shapeUser } from '../lib/shape.js';\nimport { defineResource, jsonResource } from './registry.js';\n\ninterface MeResponse {\n\tuser: unknown;\n\tteam?: unknown;\n}\n\ndefineResource({\n\tkind: 'static',\n\tname: 'team',\n\turi: 'hoststack://team',\n\tdescription:\n\t\t'Authenticated team identity + a quick orientation snapshot. Includes the team record, the user behind the API key, and counts of projects and services so an agent can decide whether to fan out into list_projects / list_services without an extra round-trip.',\n\tmimeType: 'application/json',\n\tread: async (uri, { hoststack, api, resolveTeamId }) => {\n\t\tconst teamId = await resolveTeamId();\n\n\t\t// Resource handlers must not throw on transient downstream failures —\n\t\t// clients call resources/read for orientation and a network blip\n\t\t// shouldn't poison the entire session. Tolerate partial failure and\n\t\t// surface what we can.\n\t\tconst [me, projectsResult, servicesResult] = await Promise.all([\n\t\t\tapi.get<MeResponse>('/api/auth/me').catch(() => null),\n\t\t\thoststack.projects.list(teamId).catch(() => ({ projects: [] as unknown[] })),\n\t\t\thoststack.services.list(teamId).catch(() => ({ services: [] as unknown[] })),\n\t\t]);\n\n\t\tconst projects = (projectsResult.projects as unknown[]).slice(0, 10).map(shapeProject);\n\t\tconst services = (servicesResult.services as unknown[]).slice(0, 10).map(shapeService);\n\n\t\treturn jsonResource(uri, {\n\t\t\tuser: me?.user ? shapeUser(me.user) : null,\n\t\t\tteam: me?.team ? shapeTeam(me.team) : null,\n\t\t\tproject_count: (projectsResult.projects as unknown[]).length,\n\t\t\tservice_count: (servicesResult.services as unknown[]).length,\n\t\t\t// First 10 of each so the resource stays small while still useful\n\t\t\t// for orientation. Use list_projects / list_services for the full set.\n\t\t\tprojects_preview: projects,\n\t\t\tservices_preview: services,\n\t\t});\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shape, shapeActivity } from '../lib/shape.js';\n\ninterface ActivityLogResponse {\n\tdata?: unknown[];\n\tmeta?: unknown;\n}\n\ndefineTool({\n\tname: 'list_activity_log',\n\tcategory: 'activity-log',\n\tdescription: [\n\t\t'List the team activity audit log: who did what, when. Backed by /api/activity-log/:teamId.',\n\t\t'',\n\t\t\"When to use: investigate why a service was changed unexpectedly (\\\"who deleted that env var?\\\"), correlate a deploy with a user, or pull recent admin events for a status update.\",\n\t\t'',\n\t\t'Inputs (all optional):',\n\t\t' - page: 1-based page index (default 1).',\n\t\t' - per_page: items per page (default 25, hard cap 100).',\n\t\t' - action: filter to a specific action (e.g. \"service.created\", \"deploy.triggered\").',\n\t\t' - resource_type: filter by resource type (e.g. \"service\", \"deploy\", \"domain\").',\n\t\t' - user_id: filter by acting user numeric ID.',\n\t\t'',\n\t\t'Returns: { items: ActivityLogEntry[], meta? } — each entry has id, action, resourceType, resourceId, actorEmail, ipAddress, createdAt, and a context payload.',\n\t\t'',\n\t\t'Example: list_activity_log({ resource_type: \"deploy\", per_page: 10 }) → { items: [{ action: \"deploy.triggered\", actorEmail: \"ada@…\", … }], meta: { total: 47, page: 1 } }',\n\t].join('\\n'),\n\tinput: {\n\t\tpage: z.number().int().positive().optional().describe('Page index, 1-based.'),\n\t\tper_page: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(100)\n\t\t\t.optional()\n\t\t\t.describe('Items per page, hard cap 100.'),\n\t\taction: z.string().optional().describe('Action filter, e.g. \"service.created\".'),\n\t\tresource_type: z.string().optional().describe('Resource type filter.'),\n\t\tuser_id: z.number().int().positive().optional().describe('Numeric acting-user filter.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst params: Record<string, string | number | undefined> = {};\n\t\tif (args.page !== undefined) params['page'] = String(args.page);\n\t\tif (args.per_page !== undefined) params['perPage'] = String(args.per_page);\n\t\tif (args.action !== undefined) params['action'] = args.action;\n\t\tif (args.resource_type !== undefined) params['resourceType'] = args.resource_type;\n\t\tif (args.user_id !== undefined) params['userId'] = String(args.user_id);\n\n\t\tconst response = await ctx.api.get<ActivityLogResponse>(\n\t\t\t`/api/activity-log/${teamId}`,\n\t\t\tparams,\n\t\t);\n\t\tconst items = Array.isArray(response.data) ? response.data.map(shapeActivity) : [];\n\t\tconst data: { items: unknown[]; meta?: unknown } = { items };\n\t\tif (response.meta !== undefined) data.meta = shape(response.meta);\n\n\t\treturn respond({\n\t\t\tsummary:\n\t\t\t\titems.length === 0\n\t\t\t\t\t? 'No activity log entries match the given filters.'\n\t\t\t\t\t: `Returned ${items.length} activity log entr${items.length === 1 ? 'y' : 'ies'}.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n","import type { CallToolResult, ContentBlock } from '@modelcontextprotocol/sdk/types.js';\n\ninterface RespondInput {\n\tsummary: string;\n\tdata?: unknown;\n}\n\nexport const SUMMARY_MAX_LEN = 500;\n\n/**\n * Build an MCP tool response with a 1–3 line plain-text summary, a fenced\n * JSON block for human readability, and a structuredContent object that\n * agents can parse without re-tokenising the JSON text.\n */\nexport function respond({ summary, data }: RespondInput): CallToolResult {\n\tconst trimmed = summary.trim();\n\tif (trimmed.length === 0) {\n\t\tthrow new Error('respond(): summary must be non-empty');\n\t}\n\tif (trimmed.length > SUMMARY_MAX_LEN) {\n\t\tthrow new Error(`respond(): summary too long (${trimmed.length} > ${SUMMARY_MAX_LEN})`);\n\t}\n\n\tconst blocks: ContentBlock[] = [{ type: 'text', text: trimmed }];\n\n\tif (data !== undefined) {\n\t\tblocks.push({\n\t\t\ttype: 'text',\n\t\t\ttext: '```json\\n' + JSON.stringify(data, null, 2) + '\\n```',\n\t\t});\n\t}\n\n\tconst result: CallToolResult = { content: blocks };\n\tif (data !== undefined) {\n\t\tresult.structuredContent = toStructuredContent(data);\n\t}\n\treturn result;\n}\n\nexport function respondError(message: string, data?: unknown): CallToolResult {\n\tconst blocks: ContentBlock[] = [{ type: 'text', text: `Error: ${message}` }];\n\tif (data !== undefined) {\n\t\tblocks.push({\n\t\t\ttype: 'text',\n\t\t\ttext: '```json\\n' + JSON.stringify(data, null, 2) + '\\n```',\n\t\t});\n\t}\n\tconst result: CallToolResult = { content: blocks, isError: true };\n\tif (data !== undefined) {\n\t\tresult.structuredContent = toStructuredContent(data);\n\t}\n\treturn result;\n}\n\nfunction toStructuredContent(data: unknown): Record<string, unknown> {\n\tif (data !== null && typeof data === 'object' && !Array.isArray(data)) {\n\t\treturn data as Record<string, unknown>;\n\t}\n\treturn { result: data };\n}\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeCronExecution, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_cron_executions',\n\tcategory: 'cron',\n\tdescription: [\n\t\t'List recent execution records for a cron service (newest first).',\n\t\t'',\n\t\t'When to use: investigating whether a scheduled job ran on time, finding the most recent failure, or auditing cron run-times. Only works on services of type \"cron\"; for web services this returns an error.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the cron service.',\n\t\t' - limit (optional): how many executions to fetch (default 50, max enforced server-side).',\n\t\t'',\n\t\t'Returns: { items: CronExecution[] } — id, publicId, status (succeeded|failed|running|queued), startedAt, finishedAt, exitCode, triggeredBy.',\n\t\t'',\n\t\t'Example: list_cron_executions({ service_id: \"svc_cron\" }) → { items: [{ status: \"succeeded\", exitCode: 0, … }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Cron service publicId.'),\n\t\tlimit: z.number().int().positive().max(200).optional().describe('Max executions to return (default 50).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst opts = args.limit !== undefined ? { limit: args.limit } : undefined;\n\t\tconst response = await ctx.hoststack.cron.list(teamId, args.service_id, opts);\n\t\tconst data = shapeList(response, 'executions', shapeCronExecution);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No cron executions yet for ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} cron execution${data.items.length === 1 ? '' : 's'} for ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_cron_execution',\n\tcategory: 'cron',\n\tdescription: [\n\t\t'Fetch a single cron execution record. Includes status, exit code, and timing.',\n\t\t'',\n\t\t'When to use: drilling into a specific run after list_cron_executions surfaced a failure, or correlating an execution timestamp with logs.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the cron service.',\n\t\t' - execution_id: publicId of the execution record.',\n\t\t'',\n\t\t'Returns: { execution: CronExecution }.',\n\t\t'',\n\t\t'Example: get_cron_execution({ service_id: \"svc_cron\", execution_id: \"exe_xyz\" }) → { execution: { status: \"failed\", exitCode: 1, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Cron service publicId.'),\n\t\texecution_id: z.string().describe('Execution publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.cron.get(teamId, args.service_id, args.execution_id);\n\t\tconst data = { execution: shapeCronExecution(response.execution) };\n\t\tconst status =\n\t\t\tdata.execution && 'status' in data.execution\n\t\t\t\t? (data.execution as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Execution ${args.execution_id} ${status}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDatabase, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_databases',\n\tcategory: 'databases',\n\tdescription: [\n\t\t'List managed databases (Postgres, Redis, MySQL, MariaDB, MongoDB, Meilisearch, NATS) inside a project.',\n\t\t'',\n\t\t'When to use: an agent needs to know what data stores exist in a project before connecting a service or running a migration. Pair with list_projects to discover project IDs.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - project_id: numeric project ID (from list_projects).',\n\t\t'',\n\t\t'Returns: { items: Database[] } — id, publicId, name, type, status, version, projectId, createdAt.',\n\t\t'',\n\t\t'Example: list_databases({ project_id: 12 }) → { items: [{ publicId: \"db_…\", type: \"postgres\", status: \"running\", … }] }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.number().int().positive().describe('Numeric project ID (from list_projects).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.databases.list(teamId, args.project_id);\n\t\tconst data = shapeList(response, 'databases', shapeDatabase);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No databases in project ${args.project_id}.`\n\t\t\t\t: `Found ${data.items.length} database${data.items.length === 1 ? '' : 's'} in project ${args.project_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_database',\n\tcategory: 'databases',\n\tdescription: [\n\t\t'Fetch a single managed database by ID. Includes status, type, version, and project link.',\n\t\t'',\n\t\t'When to use: confirming the version of a database before generating connection strings, or checking the status of a recently created database. To retrieve the actual connection credentials, use the dashboard — credentials are intentionally not exposed via this MCP tool.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - database_id: publicId of the database (e.g. \"db_…\").',\n\t\t'',\n\t\t'Returns: { database: Database }.',\n\t\t'',\n\t\t'Example: get_database({ database_id: \"db_xyz\" }) → { database: { type: \"postgres\", version: \"16\", status: \"running\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tdatabase_id: z.string().describe('Database publicId (e.g. db_xyz).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.databases.get(teamId, args.database_id);\n\t\tconst data = { database: shapeDatabase(response.database) };\n\t\tconst type =\n\t\t\tdata.database && 'type' in data.database\n\t\t\t\t? (data.database as { type: string }).type\n\t\t\t\t: 'unknown';\n\t\tconst status =\n\t\t\tdata.database && 'status' in data.database\n\t\t\t\t? (data.database as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Database ${args.database_id} (${type}) is ${status}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDeploy, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_deploys',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'List deploys for a service in reverse-chronological order (newest first).',\n\t\t'',\n\t\t'When to use: investigating a recent deploy outcome, finding the last successful deploy ID, comparing run-times, or just checking deploy history before triggering a new one.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service (e.g. \"svc_abc123\"). Use list_services to find it.',\n\t\t'',\n\t\t'Returns: { items: Deploy[] } — each deploy includes id, publicId, status (pending|building|deploying|live|failed|cancelled), commitSha, commitMessage, branch, triggeredBy, startedAt, finishedAt, durationMs.',\n\t\t'',\n\t\t'Example: list_deploys({ service_id: \"svc_abc\" }) → { items: [{ publicId: \"dpl_…\", status: \"live\", commitMessage: \"Fix login\", … }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.list(teamId, args.service_id);\n\t\tconst data = shapeList(response, 'deploys', shapeDeploy);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No deploys yet for service ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} deploy${data.items.length === 1 ? '' : 's'} for service ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Fetch a single deploy by ID, including its current status, commit metadata, and timestamps.',\n\t\t'',\n\t\t\"When to use: drilling into the details of a specific deploy after list_deploys, polling a build's status, or grabbing the commit SHA so you can correlate logs with code.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy (e.g. \"dpl_…\").',\n\t\t'',\n\t\t'Returns: { deploy: Deploy } — full deploy record (status, commitSha, commitMessage, branch, durationMs, finishedAt, etc).',\n\t\t'',\n\t\t'Example: get_deploy({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { deploy: { status: \"live\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.get(teamId, args.service_id, args.deploy_id);\n\t\tconst data = { deploy: shapeDeploy(response.deploy) };\n\t\tconst status =\n\t\t\tdata.deploy && typeof data.deploy === 'object' && 'status' in data.deploy\n\t\t\t\t? (data.deploy as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Deploy ${args.deploy_id} is ${status}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'trigger_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Kick off a new deploy from the latest commit on the service branch. Optionally clear the build cache for a clean rebuild.',\n\t\t'',\n\t\t'When to use: the user explicitly asks to deploy (\"ship it\", \"redeploy\", \"kick off a new build\"). For services with auto-deploy enabled, a fresh git push already triggers a deploy automatically — only call this for manual triggers, cache-clearing, or after a config change.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - clear_cache (optional): boolean — discard the cached build layers. Default false.',\n\t\t'',\n\t\t'Returns: { deploy: Deploy } — the new deploy record. Status will start as \"pending\" then transition through \"building\" → \"deploying\" → \"live\" or \"failed\".',\n\t\t'',\n\t\t'Example: trigger_deploy({ service_id: \"svc_abc\" }) → { deploy: { publicId: \"dpl_…\", status: \"pending\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tclear_cache: z.boolean().optional().describe('Clear the build cache (default false).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { clearCache?: boolean } = {};\n\t\tif (args.clear_cache !== undefined) input.clearCache = args.clear_cache;\n\t\tconst response = await ctx.hoststack.deploys.trigger(teamId, args.service_id, input);\n\t\tconst data = { deploy: shapeDeploy(response.deploy) };\n\t\tconst publicId =\n\t\t\tdata.deploy && 'publicId' in data.deploy\n\t\t\t\t? (data.deploy as { publicId: string }).publicId\n\t\t\t\t: 'unknown';\n\t\treturn respond({\n\t\t\tsummary: `Triggered deploy ${publicId} on service ${args.service_id}.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'cancel_deploy',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Cancel a running deploy. Stops the build/deploy pipeline mid-flight; the previously live revision keeps serving traffic.',\n\t\t'',\n\t\t'When to use: the user notices a bad commit was pushed and wants to abort before it lands, or a build is hanging. Has no effect on already-finished deploys.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy to cancel.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: cancel_deploy({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.deploys.cancel(teamId, args.service_id, args.deploy_id);\n\t\treturn respond({\n\t\t\tsummary: `Cancelled deploy ${args.deploy_id} on service ${args.service_id}.`,\n\t\t\tdata: { ok: true },\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'get_deploy_logs',\n\tcategory: 'deploys',\n\tdescription: [\n\t\t'Fetch the build/deploy logs for a single deploy. Returns the entire log buffer the agent can the search for errors.',\n\t\t'',\n\t\t\"When to use: a deploy failed and you need to read the build output to diagnose. Pair with get_deploy to find a failed deploy_id, then call this. For runtime (post-deploy) logs of the running container, use get_service_logs instead.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - deploy_id: publicId of the deploy.',\n\t\t'',\n\t\t'Returns: { logs: string } — full build output as a single string. May be truncated by the API if the deploy is still in progress.',\n\t\t'',\n\t\t'Example: get_deploy_logs({ service_id: \"svc_abc\", deploy_id: \"dpl_xyz\" }) → { logs: \"Building…\\\\nStep 1/8…\\\\n…\" }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tdeploy_id: z.string().describe('Deploy publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.deploys.getLogs(teamId, args.service_id, args.deploy_id);\n\t\tconst logs = typeof response.logs === 'string' ? response.logs : '';\n\t\tconst lines = logs ? logs.split('\\n').length : 0;\n\t\treturn respond({\n\t\t\tsummary: `Fetched ${lines} log line${lines === 1 ? '' : 's'} for deploy ${args.deploy_id}.`,\n\t\t\tdata: { logs },\n\t\t});\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeDomain, shapeList } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_domains',\n\tcategory: 'domains',\n\tdescription: [\n\t\t\"List every custom domain attached to the team's services.\",\n\t\t'',\n\t\t'When to use: enumerate live domains, audit DNS verification status, or find which service a hostname resolves to before troubleshooting routing.',\n\t\t'',\n\t\t'Returns: { items: Domain[] } — id, publicId, hostname, serviceId, verified, dnsTargets, sslStatus, createdAt.',\n\t\t'',\n\t\t'Example: list_domains() → { items: [{ hostname: \"api.example.com\", verified: true, sslStatus: \"active\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.domains.list(teamId);\n\t\tconst data = shapeList(response, 'domains', shapeDomain);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No custom domains configured.'\n\t\t\t\t: `Found ${data.items.length} custom domain${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'add_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Attach a custom hostname to the team — optionally pinned to a specific service. After adding, point your DNS at the targets returned and call verify_domain.',\n\t\t'',\n\t\t\"When to use: the user wants to put a custom domain in front of a HostStack service (e.g. point api.example.com at svc_abc). The hostname must be unique across the team.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - hostname: the domain to add (e.g. \"api.example.com\").',\n\t\t' - service_id (optional): publicId of the service to bind to. If omitted, the domain is added unbound and you can attach it later with update_domain.',\n\t\t'',\n\t\t'Returns: { domain: Domain } — includes dnsTargets you must configure (CNAME / A records).',\n\t\t'',\n\t\t'Example: add_domain({ hostname: \"api.example.com\", service_id: \"svc_abc\" }) → { domain: { hostname: \"api.example.com\", dnsTargets: [...], verified: false, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\thostname: z\n\t\t\t.string()\n\t\t\t.min(3)\n\t\t\t.max(253)\n\t\t\t.describe('Fully-qualified hostname (e.g. api.example.com).'),\n\t\tservice_id: z.string().optional().describe('Optional service publicId to bind to.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { domain: string; serviceId?: string } = { domain: args.hostname };\n\t\tif (args.service_id !== undefined) input.serviceId = args.service_id;\n\t\tconst response = await ctx.hoststack.domains.add(teamId, input);\n\t\tconst data = { domain: shapeDomain(response.domain) };\n\t\treturn respond({\n\t\t\tsummary: `Added domain ${args.hostname}. Configure DNS, then call verify_domain.`,\n\t\t\tdata,\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'verify_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Trigger DNS verification for a previously-added domain. HostStack checks that the dnsTargets returned by add_domain are configured at the registrar.',\n\t\t'',\n\t\t'When to use: the user has set up DNS records and is ready to flip the domain live. Returns success when verification passes; the domain stays in pending state if DNS is still propagating.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - domain_id: publicId of the domain (from list_domains or add_domain).',\n\t\t'',\n\t\t'Returns: { ok: true }. Re-call list_domains to inspect the updated verified flag and SSL status.',\n\t\t'',\n\t\t'Example: verify_domain({ domain_id: \"dom_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tdomain_id: z.string().describe('Domain publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.domains.verify(teamId, args.domain_id);\n\t\treturn respond({ summary: `Triggered DNS verification for ${args.domain_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'remove_domain',\n\tcategory: 'domains',\n\tdescription: [\n\t\t'Detach a custom hostname from the team. DESTRUCTIVE: the domain stops routing immediately and any pinned service must fall back to its default hostname.',\n\t\t'',\n\t\t\"When to use: the user wants to retire a custom domain. Confirm with the user first — the change is immediate and cannot be undone except by re-adding the domain and re-verifying DNS.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - domain_id: publicId of the domain to remove.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: remove_domain({ domain_id: \"dom_xyz\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tdomain_id: z.string().describe('Domain publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.domains.remove(teamId, args.domain_id);\n\t\treturn respond({ summary: `Removed domain ${args.domain_id}.`, data: { ok: true } });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond, respondError } from '../lib/respond.js';\nimport { shapeEnvVar, shapeList } from '../lib/shape.js';\n\ninterface ExistingEnvVar {\n\tid: number;\n\tpublicId?: string;\n\tkey: string;\n\tisSecret: boolean;\n}\n\ndefineTool({\n\tname: 'list_env_vars',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'List environment variables for a service. Secret values are masked server-side (\"••••••\"); only non-secret values come through in the clear.',\n\t\t'',\n\t\t'When to use: auditing what configuration a service has, finding the key for a value the user mentions by name, or confirming a variable was set after a write. Never assume the value field is plaintext for secret rows — it is masked.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { items: EnvVar[] } — id, publicId, key, value (masked if isSecret), isSecret, target, linkedDatabaseId, createdAt.',\n\t\t'',\n\t\t'Example: list_env_vars({ service_id: \"svc_abc\" }) → { items: [{ key: \"DATABASE_URL\", value: \"••••••\", isSecret: true }, { key: \"PORT\", value: \"3000\", isSecret: false }] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst data = shapeList(response, 'envVars', shapeEnvVar);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? `No env vars set on service ${args.service_id}.`\n\t\t\t\t: `Found ${data.items.length} env var${data.items.length === 1 ? '' : 's'} on service ${args.service_id}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'set_env_var',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Upsert a single environment variable on a service: creates the key if missing, updates the value if it already exists. Match is by key (case-sensitive).',\n\t\t'',\n\t\t'When to use: rotate a secret, add a new config knob, or change a value the user dictated. The MCP layer looks up the existing var by key first; you do not need to know the env-var ID.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - key: env-var name (e.g. \"DATABASE_URL\").',\n\t\t' - value: new value (will be encrypted at rest if is_secret=true).',\n\t\t' - is_secret (optional): true marks the value as secret (masked on read). Default true for safety; pass false for boring config like PORT or NODE_ENV.',\n\t\t'',\n\t\t'Returns: { envVar: EnvVar, action: \"created\" | \"updated\" }.',\n\t\t'',\n\t\t'Example: set_env_var({ service_id: \"svc_abc\", key: \"DATABASE_URL\", value: \"postgres://…\", is_secret: true }) → { envVar: { key: \"DATABASE_URL\", value: \"••••••\", … }, action: \"updated\" }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().min(1).max(128).describe('Env-var key.'),\n\t\tvalue: z.string().describe('New value.'),\n\t\tis_secret: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe('Mark as secret (encrypted, masked on read). Default true.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst isSecret = args.is_secret ?? true;\n\t\tconst existing = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst match = (existing.envVars as ExistingEnvVar[]).find((v) => v.key === args.key);\n\n\t\tif (match) {\n\t\t\tconst response = await ctx.hoststack.envVars.update(teamId, args.service_id, String(match.id), {\n\t\t\t\tvalue: args.value,\n\t\t\t\tisSecret,\n\t\t\t});\n\t\t\tconst data = {\n\t\t\t\tenvVar: shapeEnvVar(response.envVar),\n\t\t\t\taction: 'updated' as const,\n\t\t\t};\n\t\t\treturn respond({ summary: `Updated ${args.key} on service ${args.service_id}.`, data });\n\t\t}\n\n\t\tconst response = await ctx.hoststack.envVars.create(teamId, args.service_id, {\n\t\t\tkey: args.key,\n\t\t\tvalue: args.value,\n\t\t\tisSecret,\n\t\t});\n\t\tconst data = {\n\t\t\tenvVar: shapeEnvVar(response.envVar),\n\t\t\taction: 'created' as const,\n\t\t};\n\t\treturn respond({ summary: `Created ${args.key} on service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'delete_env_var',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Remove an environment variable from a service by key (case-sensitive).',\n\t\t'',\n\t\t'When to use: cleaning up unused config, or rotating away from a leaked secret. The MCP looks up the env-var ID from the key automatically.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - key: env-var name to delete.',\n\t\t'',\n\t\t'Returns: { ok: true } on success. Returns an error if the key was not found.',\n\t\t'',\n\t\t'Example: delete_env_var({ service_id: \"svc_abc\", key: \"OLD_FLAG\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tkey: z.string().min(1).max(128).describe('Env-var key to delete.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst existing = await ctx.hoststack.envVars.list(teamId, args.service_id);\n\t\tconst match = (existing.envVars as ExistingEnvVar[]).find((v) => v.key === args.key);\n\t\tif (!match) {\n\t\t\treturn respondError(\n\t\t\t\t`Env var \"${args.key}\" not found on service ${args.service_id}.`,\n\t\t\t\t{ key: args.key, service_id: args.service_id },\n\t\t\t);\n\t\t}\n\t\tawait ctx.hoststack.envVars.delete(teamId, args.service_id, String(match.id));\n\t\treturn respond({\n\t\t\tsummary: `Deleted ${args.key} from service ${args.service_id}.`,\n\t\t\tdata: { ok: true },\n\t\t});\n\t},\n});\n\ndefineTool({\n\tname: 'bulk_set_env_vars',\n\tcategory: 'env-vars',\n\tdescription: [\n\t\t'Replace the entire env-var set on a service with the given list. Equivalent to deleting all current vars and creating the supplied ones — use with care.',\n\t\t'',\n\t\t\"When to use: importing a .env file, mirroring config from a sibling service, or doing a clean reset. For incremental changes, use set_env_var per key — bulk_set is destructive for any key not in the supplied list.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - env_vars: array of { key, value, is_secret? }. is_secret defaults to true per row.',\n\t\t'',\n\t\t'Returns: { ok: true }. Re-list with list_env_vars to confirm the new state.',\n\t\t'',\n\t\t'Example: bulk_set_env_vars({ service_id: \"svc_abc\", env_vars: [{ key: \"PORT\", value: \"3000\", is_secret: false }, { key: \"DATABASE_URL\", value: \"…\", is_secret: true }] }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tenv_vars: z\n\t\t\t.array(\n\t\t\t\tz.object({\n\t\t\t\t\tkey: z.string().min(1).max(128),\n\t\t\t\t\tvalue: z.string(),\n\t\t\t\t\tis_secret: z.boolean().optional(),\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.max(500)\n\t\t\t.describe('Array of env-var rows. Hard cap 500.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst payload = {\n\t\t\tenvVars: args.env_vars.map((v) => {\n\t\t\t\tconst row: { key: string; value: string; isSecret?: boolean } = {\n\t\t\t\t\tkey: v.key,\n\t\t\t\t\tvalue: v.value,\n\t\t\t\t};\n\t\t\t\tif (v.is_secret !== undefined) row.isSecret = v.is_secret;\n\t\t\t\treturn row;\n\t\t\t}),\n\t\t};\n\t\tawait ctx.hoststack.envVars.bulkSet(teamId, args.service_id, payload);\n\t\treturn respond({\n\t\t\tsummary: `Replaced env-var set on service ${args.service_id} with ${args.env_vars.length} entr${args.env_vars.length === 1 ? 'y' : 'ies'}.`,\n\t\t\tdata: { ok: true, count: args.env_vars.length },\n\t\t});\n\t},\n});\n","import { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeTeam, shapeUser } from '../lib/shape.js';\n\ninterface MeResponse {\n\tuser: unknown;\n\tteam?: unknown;\n}\n\ndefineTool({\n\tname: 'get_me',\n\tcategory: 'meta',\n\tdescription: [\n\t\t\"Return the user and team identity bound to the current API key. Useful at the start of a conversation to confirm which account the agent is operating on, especially when a user has multiple HostStack environments.\",\n\t\t'',\n\t\t'When to use: orient yourself at the start of a session, confirm which team the API key targets, or surface the email/team-name in a reply to the user.',\n\t\t'',\n\t\t'Returns: { user: { id, email, name, ... }, team?: { id, publicId, name, plan, ... } }.',\n\t\t'',\n\t\t'Example: get_me() → { user: { id: 1, email: \"ada@…\", … }, team: { id: 7, name: \"acme\", plan: \"pro\" } }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst me = await ctx.api.get<MeResponse>('/api/auth/me');\n\t\tconst data: { user: ReturnType<typeof shapeUser>; team?: ReturnType<typeof shapeTeam> } = {\n\t\t\tuser: shapeUser(me.user),\n\t\t};\n\t\tif (me.team) data.team = shapeTeam(me.team);\n\t\tconst teamLabel =\n\t\t\tme.team && typeof me.team === 'object' && 'name' in me.team\n\t\t\t\t? ` on team ${(me.team as { name: string }).name}`\n\t\t\t\t: '';\n\t\tconst userEmail =\n\t\t\tme.user && typeof me.user === 'object' && 'email' in me.user\n\t\t\t\t? (me.user as { email: string }).email\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Authenticated as ${userEmail}${teamLabel}.`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shapeList, shapeProject } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_projects',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'List every project in the active HostStack team.',\n\t\t'',\n\t\t'When to use: the agent needs an overview of what projects exist before drilling into services, deploys, or databases. Use this as the first step when the user mentions a project by name and you need to resolve its ID.',\n\t\t'',\n\t\t'Returns: { items: Project[] } — each project includes id, publicId, name, description, createdAt.',\n\t\t'',\n\t\t'Example: list_projects() → { items: [{ id: 12, publicId: \"prj_…\", name: \"billing-api\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.projects.list(teamId);\n\t\tconst data = shapeList(response, 'projects', shapeProject);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No projects yet — create one in the dashboard or via create_project.'\n\t\t\t\t: `Found ${data.items.length} project${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'create_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Create a new project (logical grouping of services + databases).',\n\t\t'',\n\t\t\"When to use: the user wants to set up a new app or environment in HostStack. Projects are a free organisational layer — they don't cost anything until you add services or databases inside them.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - name: human-readable project name (1–60 chars).',\n\t\t' - description (optional): short blurb shown in the dashboard.',\n\t\t' - region (optional): \"fsn1\" (Falkenstein) | \"nbg1\" (Nuremberg) | \"hel1\" (Helsinki). Default depends on team plan.',\n\t\t'',\n\t\t'Returns: { project: Project } — includes the new id and publicId.',\n\t\t'',\n\t\t'Example: create_project({ name: \"billing-api\", description: \"Stripe webhooks\", region: \"fsn1\" }) → { project: { id: 12, publicId: \"prj_…\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tname: z.string().min(1).max(60).describe('Project name (1–60 chars).'),\n\t\tdescription: z.string().max(500).optional().describe('Short description (≤500 chars).'),\n\t\tregion: z\n\t\t\t.enum(['fsn1', 'nbg1', 'hel1'])\n\t\t\t.optional()\n\t\t\t.describe('Hetzner region: fsn1 | nbg1 | hel1.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { name: string; description?: string; region?: string } = { name: args.name };\n\t\tif (args.description !== undefined) input.description = args.description;\n\t\tif (args.region !== undefined) input.region = args.region;\n\t\tconst response = await ctx.hoststack.projects.create(teamId, input);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\tconst publicId =\n\t\t\tdata.project && 'publicId' in data.project\n\t\t\t\t? (data.project as { publicId: string }).publicId\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Created project \"${args.name}\" (${publicId}).`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Rename a project or update its description.',\n\t\t'',\n\t\t'When to use: the user wants to fix a typo in a project name, attach a clearer description, or align the dashboard label with their internal naming.',\n\t\t'',\n\t\t'Inputs (all optional, at least one required):',\n\t\t' - project_id: publicId of the project (required).',\n\t\t' - name: new name (1–60 chars).',\n\t\t' - description: new description (≤500 chars).',\n\t\t'',\n\t\t'Returns: { project: Project } — the updated record.',\n\t\t'',\n\t\t'Example: update_project({ project_id: \"prj_abc\", name: \"billing-prod\" }) → { project: { name: \"billing-prod\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.string().describe('Project publicId.'),\n\t\tname: z.string().min(1).max(60).optional().describe('New name (1–60 chars).'),\n\t\tdescription: z.string().max(500).optional().describe('New description (≤500 chars).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tif (args.name === undefined && args.description === undefined) {\n\t\t\treturn respond({\n\t\t\t\tsummary: 'No fields to update — pass `name` and/or `description`.',\n\t\t\t\tdata: {},\n\t\t\t});\n\t\t}\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: { name?: string; description?: string } = {};\n\t\tif (args.name !== undefined) input.name = args.name;\n\t\tif (args.description !== undefined) input.description = args.description;\n\t\tconst response = await ctx.hoststack.projects.update(teamId, args.project_id, input);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\treturn respond({ summary: `Updated project ${args.project_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_project',\n\tcategory: 'projects',\n\tdescription: [\n\t\t'Fetch a single project by ID. Includes name, description, and timestamps.',\n\t\t'',\n\t\t'When to use: confirming a project exists before creating resources inside it, or pulling the canonical name/description for a reply to the user.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - project_id: publicId of the project (e.g. \"prj_abc123\").',\n\t\t'',\n\t\t'Returns: { project: Project }.',\n\t\t'',\n\t\t'Example: get_project({ project_id: \"prj_abc\" }) → { project: { id: 12, name: \"billing\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tproject_id: z.string().describe('Project publicId (e.g. prj_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.projects.get(teamId, args.project_id);\n\t\tconst data = { project: shapeProject(response.project) };\n\t\tconst name =\n\t\t\tdata.project && 'name' in data.project\n\t\t\t\t? (data.project as { name: string }).name\n\t\t\t\t: args.project_id;\n\t\treturn respond({ summary: `Project \"${name}\".`, data });\n\t},\n});\n","import { z } from 'zod';\n\nimport { defineTool } from '../registry.js';\nimport { respond } from '../lib/respond.js';\nimport { shape, shapeList, shapeService } from '../lib/shape.js';\n\ndefineTool({\n\tname: 'list_services',\n\tcategory: 'services',\n\tdescription: [\n\t\t'List every service (web, worker, cron, private) in the active HostStack team.',\n\t\t'',\n\t\t'When to use: the agent needs to find a service by name, check what is deployed, or pick a target for a follow-up tool (logs, deploys, env vars). This is the canonical way to resolve a publicId from a human-friendly name.',\n\t\t'',\n\t\t'Returns: { items: Service[] } — each service includes id, publicId, name, type, status, projectId, repoUrl, branch, runtime, createdAt.',\n\t\t'',\n\t\t'Example: list_services() → { items: [{ id: 31, publicId: \"svc_…\", name: \"api\", type: \"web\", status: \"running\", … }] }',\n\t].join('\\n'),\n\tinput: {},\n\thandler: async (_args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.list(teamId);\n\t\tconst data = shapeList(response, 'services', shapeService);\n\t\tconst summary =\n\t\t\tdata.items.length === 0\n\t\t\t\t? 'No services yet — create one with create_service or via the dashboard.'\n\t\t\t\t: `Found ${data.items.length} service${data.items.length === 1 ? '' : 's'}.`;\n\t\treturn respond({ summary, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Fetch a single service by ID, including its current status and configuration summary.',\n\t\t'',\n\t\t'When to use: drilling into a service after list_services, checking deploy/runtime status, or grabbing the repo+branch before triggering a deploy.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service (e.g. \"svc_abc123\").',\n\t\t'',\n\t\t'Returns: { service: Service } — type, status, runtime, repoUrl, branch, autoDeploy, region, plan, createdAt, updatedAt.',\n\t\t'',\n\t\t'Example: get_service({ service_id: \"svc_abc\" }) → { service: { type: \"web\", status: \"running\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId (e.g. svc_abc123).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.get(teamId, args.service_id);\n\t\tconst data = { service: shapeService(response.service) };\n\t\tconst status =\n\t\t\tdata.service && 'status' in data.service\n\t\t\t\t? (data.service as { status: string }).status\n\t\t\t\t: 'unknown';\n\t\treturn respond({ summary: `Service ${args.service_id} is ${status}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service_metrics',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Fetch the latest CPU, memory, network, and request-rate metrics for a service.',\n\t\t'',\n\t\t'When to use: a service is reportedly slow, you suspect resource pressure, or you want a quick health snapshot before scaling. Returns a single point-in-time sample, not a time series.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { metrics: { cpu, memory, network, requests } } — values are normalised utilisation/throughput numbers.',\n\t\t'',\n\t\t'Example: get_service_metrics({ service_id: \"svc_abc\" }) → { metrics: { cpu: 0.42, memory: 0.71, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.getMetrics(teamId, args.service_id);\n\t\tconst data = { metrics: shape(response.metrics) };\n\t\treturn respond({ summary: `Metrics snapshot for service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Rename a service. Only the human-readable name changes — the publicId is permanent.',\n\t\t'',\n\t\t'When to use: the user wants to relabel a service in the dashboard. For deeper config edits (build command, branch, scale, plan), use update_service_config.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - name: new name (1–60 chars).',\n\t\t'',\n\t\t'Returns: { service: Service }.',\n\t\t'',\n\t\t'Example: update_service({ service_id: \"svc_abc\", name: \"api-prod\" }) → { service: { name: \"api-prod\", … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tname: z.string().min(1).max(60).describe('New service name (1–60 chars).'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst response = await ctx.hoststack.services.update(teamId, args.service_id, {\n\t\t\tname: args.name,\n\t\t});\n\t\tconst data = { service: shapeService(response.service) };\n\t\treturn respond({ summary: `Renamed service ${args.service_id} to \"${args.name}\".`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'update_service_config',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Update build/runtime configuration for a service: build command, start command, branch, root directory, dockerfile path, auto-deploy flag, instance count, plan tier. All fields optional — pass only what you want to change.',\n\t\t'',\n\t\t\"When to use: the user wants to tweak how a service builds or runs without redeploying manually. Updating any field marked dispatch-eligible (branch, build/start command, plan, root, dockerfile) typically triggers a follow-up deploy automatically; instance count scales without redeploying.\",\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - build_command, start_command (optional): shell commands.',\n\t\t' - branch (optional): git branch to track.',\n\t\t' - root_directory, dockerfile_path (optional): build context overrides.',\n\t\t' - auto_deploy (optional): boolean — auto-deploy on git push.',\n\t\t' - instance_count (optional): integer ≥1 — manual scale.',\n\t\t' - plan (optional): plan tier slug (e.g. \"starter\", \"standard\", \"pro\").',\n\t\t'',\n\t\t'Returns: { config: ServiceConfig } — the updated config record.',\n\t\t'',\n\t\t'Example: update_service_config({ service_id: \"svc_abc\", instance_count: 3 }) → { config: { instanceCount: 3, … } }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tbuild_command: z.string().optional().describe('Build shell command.'),\n\t\tstart_command: z.string().optional().describe('Start shell command.'),\n\t\tbranch: z.string().optional().describe('Git branch to track.'),\n\t\troot_directory: z.string().optional().describe('Build context root.'),\n\t\tdockerfile_path: z.string().optional().describe('Path to Dockerfile relative to root.'),\n\t\tauto_deploy: z.boolean().optional().describe('Auto-deploy on push.'),\n\t\tinstance_count: z.number().int().positive().optional().describe('Manual scale (≥1).'),\n\t\tplan: z.string().optional().describe('Plan tier slug.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst input: Record<string, unknown> = {};\n\t\tif (args.build_command !== undefined) input['buildCommand'] = args.build_command;\n\t\tif (args.start_command !== undefined) input['startCommand'] = args.start_command;\n\t\tif (args.branch !== undefined) input['branch'] = args.branch;\n\t\tif (args.root_directory !== undefined) input['rootDirectory'] = args.root_directory;\n\t\tif (args.dockerfile_path !== undefined) input['dockerfilePath'] = args.dockerfile_path;\n\t\tif (args.auto_deploy !== undefined) input['autoDeploy'] = args.auto_deploy;\n\t\tif (args.instance_count !== undefined) input['instanceCount'] = args.instance_count;\n\t\tif (args.plan !== undefined) input['plan'] = args.plan;\n\t\tif (Object.keys(input).length === 0) {\n\t\t\treturn respond({ summary: 'No fields to update.', data: {} });\n\t\t}\n\t\tconst response = await ctx.hoststack.services.updateConfig(teamId, args.service_id, input);\n\t\tconst data = { config: shape(response.config) };\n\t\tconst fields = Object.keys(input).join(', ');\n\t\treturn respond({ summary: `Updated ${fields} on service ${args.service_id}.`, data });\n\t},\n});\n\ndefineTool({\n\tname: 'suspend_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Suspend a service: stop all running instances and pause auto-deploys. The service stays configured and can be resumed later with resume_service.',\n\t\t'',\n\t\t'When to use: the user wants to temporarily stop traffic and billing without deleting the service (for example: dev environment overnight, debugging).',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: suspend_service({ service_id: \"svc_dev\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.services.suspend(teamId, args.service_id);\n\t\treturn respond({ summary: `Suspended service ${args.service_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'resume_service',\n\tcategory: 'services',\n\tdescription: [\n\t\t'Resume a previously suspended service: start instances back up and re-enable auto-deploys.',\n\t\t'',\n\t\t'When to use: the user wants to bring a suspended service back online. Pair with suspend_service.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t'',\n\t\t'Returns: { ok: true }.',\n\t\t'',\n\t\t'Example: resume_service({ service_id: \"svc_dev\" }) → { ok: true }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tawait ctx.hoststack.services.resume(teamId, args.service_id);\n\t\treturn respond({ summary: `Resumed service ${args.service_id}.`, data: { ok: true } });\n\t},\n});\n\ndefineTool({\n\tname: 'get_service_logs',\n\tcategory: 'logs',\n\tdescription: [\n\t\t\"Fetch a snapshot of the running container's recent runtime logs (stdout/stderr). For *deploy* logs (build output), use get_deploy_logs instead.\",\n\t\t'',\n\t\t'When to use: a service is misbehaving in production and you need to read what it is currently logging. The tool returns a snapshot — there is no streaming over MCP. Re-call to get newer entries.',\n\t\t'',\n\t\t'Inputs:',\n\t\t' - service_id: publicId of the service.',\n\t\t' - lines (optional): tail size (default 200, max 1000).',\n\t\t' - since (optional): ISO-8601 timestamp; only return entries newer than this.',\n\t\t' - stream (optional): \"stdout\" | \"stderr\". Omit to combine.',\n\t\t'',\n\t\t'Returns: { logs: LogEntry[] | string } — each entry has { timestamp, level?, stream?, message }. Older HostStack agents return a single string blob.',\n\t\t'',\n\t\t'Example: get_service_logs({ service_id: \"svc_abc\", lines: 100 }) → { logs: [{ timestamp: \"2026-04-25T…\", message: \"GET /health 200\" }, …] }',\n\t].join('\\n'),\n\tinput: {\n\t\tservice_id: z.string().describe('Service publicId.'),\n\t\tlines: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(1000)\n\t\t\t.optional()\n\t\t\t.describe('Tail size; default 200, hard cap 1000.'),\n\t\tsince: z.string().datetime().optional().describe('ISO-8601 timestamp lower bound.'),\n\t\tstream: z.enum(['stdout', 'stderr']).optional().describe('Restrict to one stream.'),\n\t},\n\thandler: async (args, ctx) => {\n\t\tconst teamId = await ctx.resolveTeamId();\n\t\tconst opts: { lines?: number; since?: string; stream?: 'stdout' | 'stderr' } = {\n\t\t\tlines: args.lines ?? 200,\n\t\t};\n\t\tif (args.since) opts.since = args.since;\n\t\tif (args.stream) opts.stream = args.stream;\n\t\tconst response = await ctx.hoststack.services.getRuntimeLogs(teamId, args.service_id, opts);\n\t\tconst count = Array.isArray(response.logs)\n\t\t\t? response.logs.length\n\t\t\t: typeof response.logs === 'string'\n\t\t\t\t? response.logs.split('\\n').length\n\t\t\t\t: 0;\n\t\treturn respond({\n\t\t\tsummary: `Fetched ${count} log line${count === 1 ? '' : 's'} for service ${args.service_id}.`,\n\t\t\tdata: { logs: response.logs },\n\t\t});\n\t},\n});\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","z","response","data","z","z","z","z"]}
package/manifest.json CHANGED
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "transport": {
13
13
  "type": "streamable-http",
14
- "url": "https://api.hoststack.dev/api/mcp"
14
+ "url": "https://hoststack.dev/api/mcp"
15
15
  },
16
16
  "authentication": {
17
17
  "type": "bearer",