@studiometa/forge-mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -22
- package/dist/formatters.d.ts +11 -3
- package/dist/formatters.d.ts.map +1 -1
- package/dist/handlers/index.d.ts +5 -3
- package/dist/handlers/index.d.ts.map +1 -1
- package/dist/handlers/types.d.ts +5 -0
- package/dist/handlers/types.d.ts.map +1 -1
- package/dist/handlers/utils.d.ts +6 -3
- package/dist/handlers/utils.d.ts.map +1 -1
- package/dist/{http-BJUKoZdb.js → http-CfjqK_e4.js} +33 -9
- package/dist/http-CfjqK_e4.js.map +1 -0
- package/dist/http.d.ts +11 -3
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +2 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -126
- package/dist/server.d.ts +10 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +15 -6
- package/dist/server.js.map +1 -1
- package/dist/src-BdwavqrN.js +189 -0
- package/dist/src-BdwavqrN.js.map +1 -0
- package/dist/stdio.d.ts +17 -2
- package/dist/stdio.d.ts.map +1 -1
- package/dist/tools.d.ts +36 -11
- package/dist/tools.d.ts.map +1 -1
- package/dist/{version-Cw8OGt4r.js → version-DaD5zvGh.js} +350 -130
- package/dist/version-DaD5zvGh.js.map +1 -0
- package/package.json +1 -1
- package/skills/SKILL.md +68 -38
- package/dist/http-BJUKoZdb.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/version-Cw8OGt4r.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version-Cw8OGt4r.js","names":[],"sources":["../src/instructions.ts","../src/formatters.ts","../src/errors.ts","../src/handlers/utils.ts","../src/handlers/factory.ts","../src/handlers/backups.ts","../src/hints.ts","../src/handlers/certificates.ts","../src/handlers/commands.ts","../src/handlers/daemons.ts","../src/handlers/databases.ts","../src/handlers/database-users.ts","../src/handlers/deployments.ts","../src/handlers/env.ts","../src/handlers/firewall-rules.ts","../src/handlers/help.ts","../src/handlers/monitors.ts","../src/handlers/nginx-config.ts","../src/handlers/nginx-templates.ts","../src/handlers/recipes.ts","../src/handlers/redirect-rules.ts","../src/handlers/scheduled-jobs.ts","../src/handlers/schema.ts","../src/handlers/security-rules.ts","../src/handlers/servers.ts","../src/handlers/sites.ts","../src/handlers/ssh-keys.ts","../src/handlers/user.ts","../src/handlers/index.ts","../src/tools.ts","../src/version.ts"],"sourcesContent":["/**\n * MCP Server Instructions\n *\n * These instructions are sent to MCP clients during initialization\n * and used as context/hints for the LLM. Ensures the AI agent\n * knows how to properly use the Forge MCP server.\n *\n * The content is derived from skills/SKILL.md (without YAML frontmatter).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Load instructions from SKILL.md file.\n * Removes YAML frontmatter (content between --- markers).\n */\nfunction loadInstructions(): string {\n try {\n // In dist/, go up to package root, then to skills/\n const skillPath = join(__dirname, \"..\", \"skills\", \"SKILL.md\");\n const content = readFileSync(skillPath, \"utf-8\");\n\n // Remove YAML frontmatter (between --- markers at start of file)\n const withoutFrontmatter = content.replace(/^---\\n[\\s\\S]*?\\n---\\n+/, \"\");\n\n return withoutFrontmatter.trim();\n } catch {\n return 'Laravel Forge MCP Server - Use the forge tool with resource and action parameters. Call action=\"help\" for documentation.';\n }\n}\n\nexport const INSTRUCTIONS = loadInstructions();\n","/**\n * Response formatters for MCP tool output.\n *\n * This module contains per-resource formatter functions that convert\n * executor data payloads into human-readable text for MCP responses.\n *\n * Keeping formatting in the MCP layer ensures executors remain pure data\n * functions that can be reused by any adapter (CLI, SDK, etc.).\n */\n\nimport type {\n ForgeBackupConfig,\n ForgeCertificate,\n ForgeCommand,\n ForgeDaemon,\n ForgeDatabase,\n ForgeDatabaseUser,\n ForgeDeployment,\n ForgeFirewallRule,\n ForgeMonitor,\n ForgeNginxTemplate,\n ForgeRecipe,\n ForgeRedirectRule,\n ForgeScheduledJob,\n ForgeSecurityRule,\n ForgeServer,\n ForgeSite,\n ForgeSshKey,\n ForgeUser,\n} from \"@studiometa/forge-api\";\n\n// ── Servers ──────────────────────────────────────────\n\n/**\n * Format a list of servers.\n */\nexport function formatServerList(servers: ForgeServer[]): string {\n if (servers.length === 0) {\n return \"No servers found.\";\n }\n const lines = servers.map(\n (s) =>\n `• ${s.name} (ID: ${s.id}) — ${s.provider} ${s.region} — ${s.ip_address} — ${s.is_ready ? \"ready\" : \"provisioning\"}`,\n );\n return `${servers.length} server(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single server.\n */\nexport function formatServer(server: ForgeServer): string {\n return [\n `Server: ${server.name} (ID: ${server.id})`,\n `Provider: ${server.provider} (${server.region})`,\n `IP: ${server.ip_address}`,\n `PHP: ${server.php_version}`,\n `Ubuntu: ${server.ubuntu_version}`,\n `Status: ${server.is_ready ? \"ready\" : \"provisioning\"}`,\n `Created: ${server.created_at}`,\n ].join(\"\\n\");\n}\n\n// ── Sites ────────────────────────────────────────────\n\n/**\n * Format a list of sites.\n */\nexport function formatSiteList(sites: ForgeSite[], serverId?: string): string {\n if (sites.length === 0) {\n return serverId ? `No sites on server ${serverId}.` : \"No sites found.\";\n }\n const lines = sites.map((s) => `• ${s.name} (ID: ${s.id}) — ${s.project_type} — ${s.status}`);\n const header = serverId\n ? `${sites.length} site(s) on server ${serverId}:`\n : `${sites.length} site(s):`;\n return `${header}\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single site.\n */\nexport function formatSite(site: ForgeSite): string {\n return [\n `Site: ${site.name} (ID: ${site.id})`,\n `Type: ${site.project_type}`,\n `Directory: ${site.directory}`,\n `Repository: ${site.repository ?? \"none\"}`,\n `Branch: ${site.repository_branch ?? \"none\"}`,\n `Status: ${site.status}`,\n `Deploy status: ${site.deployment_status ?? \"none\"}`,\n `Quick deploy: ${site.quick_deploy ? \"enabled\" : \"disabled\"}`,\n `PHP: ${site.php_version}`,\n `Created: ${site.created_at}`,\n ].join(\"\\n\");\n}\n\n// ── Databases ────────────────────────────────────────\n\n/**\n * Format a list of databases.\n */\nexport function formatDatabaseList(databases: ForgeDatabase[]): string {\n if (databases.length === 0) {\n return \"No databases found.\";\n }\n const lines = databases.map((d) => `• ${d.name} (ID: ${d.id}) — ${d.status}`);\n return `${databases.length} database(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single database.\n */\nexport function formatDatabase(db: ForgeDatabase): string {\n return `Database: ${db.name} (ID: ${db.id})\\nStatus: ${db.status}\\nCreated: ${db.created_at}`;\n}\n\n// ── Database Users ────────────────────────────────────\n\n/**\n * Format a list of database users.\n */\nexport function formatDatabaseUserList(users: ForgeDatabaseUser[]): string {\n if (users.length === 0) {\n return \"No database users found.\";\n }\n const lines = users.map((u) => `• ${u.name} (ID: ${u.id}) — ${u.status}`);\n return `${users.length} database user(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single database user.\n */\nexport function formatDatabaseUser(user: ForgeDatabaseUser): string {\n return [\n `Database User: ${user.name} (ID: ${user.id})`,\n `Status: ${user.status}`,\n `Databases: ${user.databases.length > 0 ? user.databases.join(\", \") : \"none\"}`,\n `Created: ${user.created_at}`,\n ].join(\"\\n\");\n}\n\n// ── Deployments ──────────────────────────────────────\n\n/**\n * Format a list of deployments.\n */\nexport function formatDeploymentList(deployments: ForgeDeployment[]): string {\n if (deployments.length === 0) {\n return \"No deployments found.\";\n }\n const lines = deployments.map(\n (d) =>\n `• #${d.id} — ${d.status} — ${d.commit_hash?.slice(0, 7) ?? \"no commit\"} — ${d.started_at}`,\n );\n return `${deployments.length} deployment(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a deployment action result (deploy/update-script).\n */\nexport function formatDeployAction(siteId: string, serverId: string): string {\n return `Deployment triggered for site ${siteId} on server ${serverId}.`;\n}\n\n/**\n * Format deployment script content.\n */\nexport function formatDeploymentScript(script: string): string {\n return `Deployment script:\\n${script}`;\n}\n\n/**\n * Format deployment output.\n */\nexport function formatDeploymentOutput(deploymentId: string, output: string): string {\n return `Deployment ${deploymentId} output:\\n${output}`;\n}\n\n/**\n * Format a deployment script update confirmation.\n */\nexport function formatDeploymentScriptUpdated(siteId: string, serverId: string): string {\n return `Deployment script updated for site ${siteId} on server ${serverId}.`;\n}\n\n// ── Certificates ─────────────────────────────────────\n\n/**\n * Format a list of certificates.\n */\nexport function formatCertificateList(certificates: ForgeCertificate[]): string {\n if (certificates.length === 0) {\n return \"No certificates found.\";\n }\n const lines = certificates.map(\n (c) =>\n `• ${c.domain} (ID: ${c.id}) — ${c.type} — ${c.active ? \"active\" : \"inactive\"} — ${c.status}`,\n );\n return `${certificates.length} certificate(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single certificate.\n */\nexport function formatCertificate(cert: ForgeCertificate): string {\n return `Certificate: ${cert.domain} (ID: ${cert.id})\\nType: ${cert.type}\\nStatus: ${cert.status}\\nActive: ${cert.active}`;\n}\n\n// ── Daemons ──────────────────────────────────────────\n\n/**\n * Format a list of daemons.\n */\nexport function formatDaemonList(daemons: ForgeDaemon[]): string {\n if (daemons.length === 0) {\n return \"No daemons found.\";\n }\n const lines = daemons.map((d) => `• ${d.command} (ID: ${d.id}) — user: ${d.user} — ${d.status}`);\n return `${daemons.length} daemon(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single daemon.\n */\nexport function formatDaemon(daemon: ForgeDaemon): string {\n return `Daemon: ${daemon.command} (ID: ${daemon.id})\\nUser: ${daemon.user}\\nProcesses: ${daemon.processes}\\nStatus: ${daemon.status}`;\n}\n\n// ── Firewall Rules ───────────────────────────────────\n\n/**\n * Format a list of firewall rules.\n */\nexport function formatFirewallRuleList(rules: ForgeFirewallRule[]): string {\n if (rules.length === 0) {\n return \"No firewall rules found.\";\n }\n const lines = rules.map(\n (r) => `• ${r.name} (ID: ${r.id}) — port: ${r.port} — ${r.ip_address} — ${r.status}`,\n );\n return `${rules.length} firewall rule(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single firewall rule.\n */\nexport function formatFirewallRule(rule: ForgeFirewallRule): string {\n return `Firewall Rule: ${rule.name} (ID: ${rule.id})\\nPort: ${rule.port}\\nType: ${rule.type}\\nIP: ${rule.ip_address}\\nStatus: ${rule.status}`;\n}\n\n// ── Monitors ─────────────────────────────────────────\n\n/**\n * Format a list of monitors.\n */\nexport function formatMonitorList(monitors: ForgeMonitor[]): string {\n if (monitors.length === 0) {\n return \"No monitors found.\";\n }\n const lines = monitors.map(\n (m) => `• ${m.type} ${m.operator} ${m.threshold} (ID: ${m.id}) — ${m.state}`,\n );\n return `${monitors.length} monitor(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single monitor.\n */\nexport function formatMonitor(monitor: ForgeMonitor): string {\n return `Monitor: ${monitor.type} ${monitor.operator} ${monitor.threshold} (ID: ${monitor.id})\\nState: ${monitor.state}\\nMinutes: ${monitor.minutes}`;\n}\n\n// ── SSH Keys ─────────────────────────────────────────\n\n/**\n * Format a list of SSH keys.\n */\nexport function formatSshKeyList(keys: ForgeSshKey[]): string {\n if (keys.length === 0) {\n return \"No SSH keys found.\";\n }\n const lines = keys.map((k) => `• ${k.name} (ID: ${k.id}) — ${k.status}`);\n return `${keys.length} SSH key(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single SSH key.\n */\nexport function formatSshKey(key: ForgeSshKey): string {\n return `SSH Key: ${key.name} (ID: ${key.id})\\nStatus: ${key.status}\\nCreated: ${key.created_at}`;\n}\n\n// ── Scheduled Jobs ───────────────────────────────────\n\n/**\n * Format a list of scheduled jobs.\n */\nexport function formatScheduledJobList(jobs: ForgeScheduledJob[]): string {\n if (jobs.length === 0) {\n return \"No scheduled jobs found.\";\n }\n const lines = jobs.map(\n (j) => `• ${j.command} (ID: ${j.id}) — ${j.frequency} — ${j.status} — user: ${j.user}`,\n );\n return `${jobs.length} scheduled job(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single scheduled job.\n */\nexport function formatScheduledJob(job: ForgeScheduledJob): string {\n return [\n `Job: ${job.command} (ID: ${job.id})`,\n `User: ${job.user}`,\n `Frequency: ${job.frequency}`,\n `Cron: ${job.cron}`,\n `Status: ${job.status}`,\n `Created: ${job.created_at}`,\n ].join(\"\\n\");\n}\n\n// ── Security Rules ───────────────────────────────────\n\n/**\n * Format a list of security rules.\n */\nexport function formatSecurityRuleList(rules: ForgeSecurityRule[]): string {\n if (rules.length === 0) {\n return \"No security rules found.\";\n }\n const lines = rules.map((r) => `• ${r.name} (ID: ${r.id}) — path: ${r.path ?? \"/\"}`);\n return `${rules.length} security rule(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single security rule.\n */\nexport function formatSecurityRule(rule: ForgeSecurityRule): string {\n return `Security Rule: ${rule.name} (ID: ${rule.id})\\nPath: ${rule.path ?? \"/\"}`;\n}\n\n// ── Redirect Rules ───────────────────────────────────\n\n/**\n * Format a list of redirect rules.\n */\nexport function formatRedirectRuleList(rules: ForgeRedirectRule[]): string {\n if (rules.length === 0) {\n return \"No redirect rules found.\";\n }\n const lines = rules.map((r) => `• ${r.from} → ${r.to} (ID: ${r.id}) — ${r.type}`);\n return `${rules.length} redirect rule(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single redirect rule.\n */\nexport function formatRedirectRule(rule: ForgeRedirectRule): string {\n return `Redirect Rule: ${rule.from} → ${rule.to} (ID: ${rule.id})\\nType: ${rule.type}`;\n}\n\n// ── Nginx ────────────────────────────────────────────\n\n/**\n * Format nginx configuration content.\n */\nexport function formatNginxConfig(content: string): string {\n return `Nginx configuration:\\n${content}`;\n}\n\n// ── Nginx Templates ──────────────────────────────────\n\n/**\n * Format a list of nginx templates.\n */\nexport function formatNginxTemplateList(templates: ForgeNginxTemplate[]): string {\n if (templates.length === 0) {\n return \"No nginx templates found.\";\n }\n const lines = templates.map((t) => `• ${t.name} (ID: ${t.id})`);\n return `${templates.length} nginx template(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single nginx template.\n */\nexport function formatNginxTemplate(template: ForgeNginxTemplate): string {\n return `Nginx Template: ${template.name} (ID: ${template.id})\\n\\n${template.content}`;\n}\n\n// ── Backup Configs ───────────────────────────────────\n\n/**\n * Format a list of backup configurations.\n */\nexport function formatBackupConfigList(backups: ForgeBackupConfig[]): string {\n if (backups.length === 0) {\n return \"No backup configurations found.\";\n }\n const lines = backups.map(\n (b) =>\n `• ${b.provider_name} (ID: ${b.id}) — ${b.frequency} — ${b.status} — last: ${b.last_backup_time ?? \"never\"}`,\n );\n return `${backups.length} backup config(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single backup configuration.\n */\nexport function formatBackupConfig(backup: ForgeBackupConfig): string {\n return [\n `Backup Config: ${backup.provider_name} (ID: ${backup.id})`,\n `Frequency: ${backup.frequency}`,\n `Status: ${backup.status}`,\n `Retention: ${backup.retention} backups`,\n `Databases: ${backup.databases.map((d) => d.name).join(\", \") || \"none\"}`,\n `Last backup: ${backup.last_backup_time ?? \"never\"}`,\n ].join(\"\\n\");\n}\n\n// ── Recipes ──────────────────────────────────────────\n\n/**\n * Format a list of recipes.\n */\nexport function formatRecipeList(recipes: ForgeRecipe[]): string {\n if (recipes.length === 0) {\n return \"No recipes found.\";\n }\n const lines = recipes.map((r) => `• ${r.name} (ID: ${r.id}) — user: ${r.user}`);\n return `${recipes.length} recipe(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single recipe.\n */\nexport function formatRecipe(recipe: ForgeRecipe): string {\n return `Recipe: ${recipe.name} (ID: ${recipe.id})\\nUser: ${recipe.user}\\nScript:\\n${recipe.script}`;\n}\n\n// ── Commands ─────────────────────────────────────────\n\n/**\n * Format a list of commands.\n */\nexport function formatCommandList(commands: ForgeCommand[]): string {\n if (commands.length === 0) {\n return \"No commands found.\";\n }\n const lines = commands.map(\n (c) => `• #${c.id} — ${c.status} — ${c.user_name} — ${c.command.slice(0, 60)}`,\n );\n return `${commands.length} command(s):\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Format a single command.\n */\nexport function formatCommand(command: ForgeCommand): string {\n return [\n `Command #${command.id}`,\n `Command: ${command.command}`,\n `Status: ${command.status}`,\n `User: ${command.user_name}`,\n `Created: ${command.created_at}`,\n ].join(\"\\n\");\n}\n\n// ── Env ──────────────────────────────────────────────\n\n/**\n * Format environment variables content.\n */\nexport function formatEnv(content: string): string {\n return `Environment variables:\\n${content}`;\n}\n\n// ── User ─────────────────────────────────────────────\n\n/**\n * Format the authenticated user.\n */\nexport function formatUser(user: ForgeUser): string {\n return [\n `User: ${user.name} (ID: ${user.id})`,\n `Email: ${user.email}`,\n `GitHub: ${user.connected_to_github ? \"connected\" : \"not connected\"}`,\n `GitLab: ${user.connected_to_gitlab ? \"connected\" : \"not connected\"}`,\n `2FA: ${user.two_factor_enabled ? \"enabled\" : \"disabled\"}`,\n ].join(\"\\n\");\n}\n\n// ── Generic helpers ──────────────────────────────────\n\n/**\n * Format a deleted resource confirmation.\n */\nexport function formatDeleted(resource: string, id: string): string {\n return `${resource} ${id} deleted.`;\n}\n\n/**\n * Format a created resource confirmation (for simple cases).\n */\nexport function formatCreated(resource: string, name: string, id: number | string): string {\n return `${resource} created: ${name} (ID: ${id})`;\n}\n","/**\n * Custom error classes for MCP server\n *\n * These provide structured error handling with LLM-friendly messages\n * that include guidance on how to resolve issues.\n */\n\n/**\n * Error thrown when user input validation fails.\n * These errors should be returned to the user directly.\n *\n * Includes optional hints for how to resolve the issue.\n */\nexport class UserInputError extends Error {\n public readonly hints?: string[];\n\n constructor(message: string, hints?: string[]) {\n super(message);\n this.name = \"UserInputError\";\n this.hints = hints;\n }\n\n /**\n * Format error message with hints for LLM consumption\n */\n toFormattedMessage(): string {\n let msg = `**Input Error:** ${this.message}`;\n if (this.hints && this.hints.length > 0) {\n msg += \"\\n\\n**Hints:**\\n\" + this.hints.map((h) => `- ${h}`).join(\"\\n\");\n }\n return msg;\n }\n}\n\n/**\n * Error messages with guidance for common validation failures\n */\nexport const ErrorMessages = {\n // Required field errors\n missingId: (action: string) =>\n new UserInputError(`id is required for ${action} action`, [\n `Use action=\"list\" first to find the resource ID`,\n `Then use action=\"${action}\" with the id parameter`,\n ]),\n\n missingRequiredFields: (resource: string, fields: string[]) =>\n new UserInputError(\n `${fields.join(\", \")} ${fields.length === 1 ? \"is\" : \"are\"} required for creating ${resource}`,\n [\n `Provide all required fields: ${fields.join(\", \")}`,\n `Use action=\"help\" for detailed documentation on ${resource}`,\n ],\n ),\n\n // Invalid action errors\n invalidAction: (action: string, resource: string, validActions: string[]) =>\n new UserInputError(`Invalid action \"${action}\" for ${resource}`, [\n `Valid actions are: ${validActions.join(\", \")}`,\n `Use action=\"help\" with resource=\"${resource}\" for detailed documentation`,\n ]),\n\n // Unknown resource errors\n unknownResource: (resource: string, validResources: string[]) =>\n new UserInputError(`Unknown resource: ${resource}`, [\n `Valid resources are: ${validResources.join(\", \")}`,\n `Use action=\"help\" without a resource for an overview of all resources`,\n ]),\n\n // Update-specific errors\n noUpdateFieldsSpecified: (allowedFields: string[]) =>\n new UserInputError(\n `No updates specified. Provide at least one of: ${allowedFields.join(\", \")}`,\n [\"Specify at least one field to update\", `Updatable fields are: ${allowedFields.join(\", \")}`],\n ),\n\n // API errors\n apiError: (statusCode: number, message: string) => {\n const hints: string[] = [];\n\n if (statusCode === 401) {\n hints.push(\"Check that your API token is valid and not expired\");\n } else if (statusCode === 403) {\n hints.push(\"You may not have permission to access this resource\");\n hints.push(\"Check your API token permissions\");\n } else if (statusCode === 404) {\n hints.push(\"The resource may not exist or you may not have access\");\n hints.push(\"Verify the resource ID is correct\");\n hints.push('Use action=\"list\" to find valid resource IDs');\n } else if (statusCode === 422) {\n hints.push(\"The request data may be invalid\");\n hints.push(\"Check the field values and types\");\n hints.push('Use action=\"help\" for field documentation');\n } else if (statusCode >= 500) {\n hints.push(\"This is a server error - try again later\");\n }\n\n return new UserInputError(`API error (${statusCode}): ${message}`, hints);\n },\n} as const;\n\n/**\n * Check if an error is a UserInputError\n */\nexport function isUserInputError(error: unknown): error is UserInputError {\n return error instanceof UserInputError;\n}\n","import type { ToolResult } from \"./types.ts\";\n\nimport { UserInputError } from \"../errors.ts\";\n\n/**\n * Create a successful JSON result.\n * Accepts a string or an object (which will be JSON-serialized).\n */\nexport function jsonResult(data: string | Record<string, unknown> | unknown): ToolResult {\n const text = typeof data === \"string\" ? data : JSON.stringify(data, null, 2);\n return {\n content: [{ type: \"text\", text }],\n };\n}\n\n/**\n * Validate an ID-like value (must be alphanumeric/dashes only).\n * Prevents path traversal via `../` in URL segments.\n *\n * @returns true if the value is safe, false otherwise.\n */\nexport function sanitizeId(value: string): boolean {\n return /^[\\w-]+$/.test(value);\n}\n\n/**\n * Create an error result.\n */\nexport function errorResult(message: string): ToolResult {\n return {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n}\n\n/**\n * Create an input error result from a UserInputError or a plain message with an optional suggestion.\n *\n * When a UserInputError is passed, its formatted message (including hints) is used.\n * When a plain string is passed, the optional suggestion is appended.\n */\nexport function inputErrorResult(error: UserInputError | string, suggestion?: string): ToolResult {\n let text: string;\n if (error instanceof UserInputError) {\n text = error.toFormattedMessage();\n } else {\n text = suggestion ? `Error: ${error}\\n\\nSuggestion: ${suggestion}` : `Error: ${error}`;\n }\n return {\n content: [{ type: \"text\", text }],\n isError: true,\n };\n}\n","/**\n * Factory for creating Forge resource handlers.\n *\n * Encapsulates the repetitive list/get/create/update/delete pattern\n * shared by all MCP resource handlers.\n */\n\nimport type { ExecutorContext, ExecutorResult } from \"@studiometa/forge-core\";\n\nimport type { ContextualHints } from \"../hints.ts\";\nimport type { CommonArgs, HandlerContext, ToolResult } from \"./types.ts\";\n\nimport { errorResult, jsonResult, sanitizeId } from \"./utils.ts\";\n\n/**\n * Configuration for a resource handler.\n */\nexport interface ResourceHandlerConfig {\n /** Resource name for error messages */\n resource: string;\n\n /** Valid actions for this resource */\n actions: string[];\n\n /** Fields required per action (in addition to defaults) */\n requiredFields?: Record<string, string[]>;\n\n /** Executor functions keyed by action name */\n // biome-ignore lint: executor signatures vary per resource\n executors: Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (options: any, ctx: ExecutorContext) => Promise<ExecutorResult<unknown>>\n >;\n\n /**\n * Generate contextual hints for the get action response.\n *\n * Called with the executor result data and the resource id.\n * Only injected when `ctx.includeHints` is true.\n */\n hints?: (data: unknown, id: string) => ContextualHints;\n\n /** Map tool args to executor options. Defaults to pass-through. */\n mapOptions?: (action: string, args: CommonArgs) => Record<string, unknown>;\n\n /**\n * Format the executor result data into human-readable text for MCP output.\n *\n * Called with the executor result data and the tool args when compact mode\n * is enabled. If not provided, the data is JSON-serialized.\n */\n // biome-ignore lint: formatter signatures vary per resource\n formatResult?: (action: string, data: any, args: CommonArgs) => string;\n}\n\n/**\n * Create a resource handler from configuration.\n *\n * Returns a function that routes actions to the correct executor,\n * validates required fields, and formats results.\n *\n * @example\n * ```typescript\n * export const handleDatabases = createResourceHandler({\n * resource: 'databases',\n * actions: ['list', 'get', 'create', 'delete'],\n * requiredFields: {\n * list: ['server_id'],\n * get: ['server_id', 'id'],\n * create: ['server_id', 'name'],\n * delete: ['server_id', 'id'],\n * },\n * executors: {\n * list: listDatabases,\n * get: getDatabase,\n * create: createDatabase,\n * delete: deleteDatabase,\n * },\n * formatResult: (action, data) => {\n * if (action === 'list') return formatDatabaseList(data);\n * if (action === 'get') return formatDatabase(data);\n * return 'Done.';\n * },\n * });\n * ```\n */\nexport function createResourceHandler(\n config: ResourceHandlerConfig,\n): (action: string, args: CommonArgs, ctx: HandlerContext) => Promise<ToolResult> {\n const {\n resource,\n actions,\n requiredFields = {},\n executors,\n hints,\n mapOptions,\n formatResult,\n } = config;\n\n return async (action: string, args: CommonArgs, ctx: HandlerContext): Promise<ToolResult> => {\n // Validate action\n if (!actions.includes(action)) {\n return errorResult(\n `Unknown action \"${action}\" for ${resource}. Valid actions: ${actions.join(\", \")}.`,\n );\n }\n\n // Check required fields\n const required = requiredFields[action] ?? [];\n for (const field of required) {\n if (!args[field]) {\n return errorResult(`Missing required field: ${field}`);\n }\n }\n\n // Validate ID-like fields to prevent path traversal\n for (const field of [\"id\", \"server_id\", \"site_id\"]) {\n const value = args[field];\n if (value !== undefined && !sanitizeId(String(value))) {\n return errorResult(`Invalid ${field}: \"${value}\". IDs must be alphanumeric.`);\n }\n }\n\n // Get executor\n const executor = executors[action];\n if (!executor) {\n return errorResult(`Action \"${action}\" is not yet implemented for ${resource}.`);\n }\n\n // Map args to executor options — strip MCP-specific fields from passthrough\n let options: Record<string, unknown>;\n if (mapOptions) {\n options = mapOptions(action, args);\n } else {\n const { resource: _r, action: _a, compact: _c, ...rest } = args;\n options = rest;\n }\n\n // Execute\n const result = await executor(options as Record<string, unknown>, ctx.executorContext);\n\n // Format result\n if (result.data === undefined) {\n // Void result (delete, activate, etc.) — use formatter or generic message\n const text = formatResult ? formatResult(action, undefined, args) : \"Done.\";\n return jsonResult(text);\n }\n\n if (ctx.compact && formatResult) {\n return jsonResult(formatResult(action, result.data, args));\n }\n\n // For non-compact get responses, inject contextual hints when enabled\n if (action === \"get\" && ctx.includeHints && hints) {\n /* v8 ignore start */\n const id = args.id ?? args.server_id ?? \"\";\n /* v8 ignore stop */\n const responseData = {\n ...(result.data as Record<string, unknown>),\n _hints: hints(result.data, String(id)),\n };\n return jsonResult(responseData);\n }\n\n return jsonResult(result.data);\n };\n}\n","import {\n createBackupConfig,\n deleteBackupConfig,\n getBackupConfig,\n listBackupConfigs,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeBackupConfig } from \"@studiometa/forge-api\";\n\nimport { formatBackupConfig, formatBackupConfigList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleBackups = createResourceHandler({\n resource: \"backups\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"provider\", \"credentials\", \"frequency\", \"databases\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listBackupConfigs,\n get: getBackupConfig,\n create: createBackupConfig,\n delete: deleteBackupConfig,\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatBackupConfigList(data as ForgeBackupConfig[]);\n case \"get\":\n return formatBackupConfig(data as ForgeBackupConfig);\n case \"create\":\n return formatBackupConfig(data as ForgeBackupConfig);\n case \"delete\":\n return `Backup config ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","/**\n * Contextual hints for AI agents.\n *\n * After get/list actions, suggests related resources and common next steps\n * to help agents discover what's available.\n */\n\ninterface ResourceHint {\n resource: string;\n description: string;\n example: Record<string, unknown>;\n}\n\nexport interface ContextualHints {\n related_resources?: ResourceHint[];\n common_actions?: { action: string; example: Record<string, unknown> }[];\n}\n\n/**\n * Hints after getting a server.\n */\nexport function getServerHints(serverId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"sites\",\n description: \"List sites on this server\",\n example: { resource: \"sites\", action: \"list\", server_id: serverId },\n },\n {\n resource: \"databases\",\n description: \"List databases\",\n example: { resource: \"databases\", action: \"list\", server_id: serverId },\n },\n {\n resource: \"daemons\",\n description: \"List background processes\",\n example: { resource: \"daemons\", action: \"list\", server_id: serverId },\n },\n {\n resource: \"firewall-rules\",\n description: \"List firewall rules\",\n example: { resource: \"firewall-rules\", action: \"list\", server_id: serverId },\n },\n {\n resource: \"ssh-keys\",\n description: \"List SSH keys on this server\",\n example: { resource: \"ssh-keys\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Reboot server\",\n example: { resource: \"servers\", action: \"reboot\", id: serverId },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a site.\n */\nexport function getSiteHints(serverId: string, siteId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"deployments\",\n description: \"List deployments for this site\",\n example: { resource: \"deployments\", action: \"list\", server_id: serverId, site_id: siteId },\n },\n {\n resource: \"env\",\n description: \"Get environment variables\",\n example: { resource: \"env\", action: \"get\", server_id: serverId, site_id: siteId },\n },\n {\n resource: \"certificates\",\n description: \"List SSL certificates\",\n example: { resource: \"certificates\", action: \"list\", server_id: serverId, site_id: siteId },\n },\n {\n resource: \"nginx\",\n description: \"Get nginx configuration\",\n example: { resource: \"nginx\", action: \"get\", server_id: serverId, site_id: siteId },\n },\n ],\n common_actions: [\n {\n action: \"Deploy this site\",\n example: {\n resource: \"deployments\",\n action: \"deploy\",\n server_id: serverId,\n site_id: siteId,\n },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a database.\n */\nexport function getDatabaseHints(serverId: string, databaseId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"databases\",\n description: \"List all databases on this server\",\n example: { resource: \"databases\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Delete this database\",\n example: { resource: \"databases\", action: \"delete\", server_id: serverId, id: databaseId },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a database user.\n */\nexport function getDatabaseUserHints(serverId: string, userId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"database-users\",\n description: \"List all database users on this server\",\n example: { resource: \"database-users\", action: \"list\", server_id: serverId },\n },\n {\n resource: \"databases\",\n description: \"List databases on this server\",\n example: { resource: \"databases\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Delete this database user\",\n example: {\n resource: \"database-users\",\n action: \"delete\",\n server_id: serverId,\n id: userId,\n },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a daemon.\n */\nexport function getDaemonHints(serverId: string, daemonId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"daemons\",\n description: \"List all daemons on this server\",\n example: { resource: \"daemons\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Restart this daemon\",\n example: { resource: \"daemons\", action: \"restart\", server_id: serverId, id: daemonId },\n },\n {\n action: \"Delete this daemon\",\n example: { resource: \"daemons\", action: \"delete\", server_id: serverId, id: daemonId },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a certificate.\n */\nexport function getCertificateHints(\n serverId: string,\n siteId: string,\n certificateId: string,\n): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"certificates\",\n description: \"List all certificates for this site\",\n example: {\n resource: \"certificates\",\n action: \"list\",\n server_id: serverId,\n site_id: siteId,\n },\n },\n ],\n common_actions: [\n {\n action: \"Activate this certificate\",\n example: {\n resource: \"certificates\",\n action: \"activate\",\n server_id: serverId,\n site_id: siteId,\n id: certificateId,\n },\n },\n {\n action: \"Delete this certificate\",\n example: {\n resource: \"certificates\",\n action: \"delete\",\n server_id: serverId,\n site_id: siteId,\n id: certificateId,\n },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a firewall rule.\n */\nexport function getFirewallRuleHints(serverId: string, ruleId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"firewall-rules\",\n description: \"List all firewall rules on this server\",\n example: { resource: \"firewall-rules\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Delete this firewall rule\",\n example: {\n resource: \"firewall-rules\",\n action: \"delete\",\n server_id: serverId,\n id: ruleId,\n },\n },\n ],\n };\n}\n\n/**\n * Hints after getting an SSH key.\n */\nexport function getSshKeyHints(serverId: string, keyId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"ssh-keys\",\n description: \"List all SSH keys on this server\",\n example: { resource: \"ssh-keys\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Delete this SSH key\",\n example: { resource: \"ssh-keys\", action: \"delete\", server_id: serverId, id: keyId },\n },\n ],\n };\n}\n\n/**\n * Hints after getting a recipe.\n */\nexport function getRecipeHints(recipeId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"recipes\",\n description: \"List all recipes\",\n example: { resource: \"recipes\", action: \"list\" },\n },\n ],\n common_actions: [\n {\n action: \"Run this recipe on servers\",\n example: { resource: \"recipes\", action: \"run\", id: recipeId, servers: [] },\n },\n {\n action: \"Delete this recipe\",\n example: { resource: \"recipes\", action: \"delete\", id: recipeId },\n },\n ],\n };\n}\n\n/**\n * Hints after getting an nginx template.\n */\nexport function getNginxTemplateHints(serverId: string, templateId: string): ContextualHints {\n return {\n related_resources: [\n {\n resource: \"nginx-templates\",\n description: \"List all nginx templates on this server\",\n example: { resource: \"nginx-templates\", action: \"list\", server_id: serverId },\n },\n ],\n common_actions: [\n {\n action: \"Update this nginx template\",\n example: {\n resource: \"nginx-templates\",\n action: \"update\",\n server_id: serverId,\n id: templateId,\n content: \"<nginx config content>\",\n },\n },\n {\n action: \"Delete this nginx template\",\n example: {\n resource: \"nginx-templates\",\n action: \"delete\",\n server_id: serverId,\n id: templateId,\n },\n },\n ],\n };\n}\n","import {\n activateCertificate,\n createCertificate,\n deleteCertificate,\n getCertificate,\n listCertificates,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeCertificate } from \"@studiometa/forge-api\";\n\nimport { formatCertificate, formatCertificateList } from \"../formatters.ts\";\nimport { getCertificateHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleCertificates = createResourceHandler({\n resource: \"certificates\",\n actions: [\"list\", \"get\", \"create\", \"delete\", \"activate\"],\n requiredFields: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"domain\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n activate: [\"server_id\", \"site_id\", \"id\"],\n },\n executors: {\n list: listCertificates,\n get: getCertificate,\n create: createCertificate,\n delete: deleteCertificate,\n activate: activateCertificate,\n },\n hints: (data, id) => {\n const cert = data as ForgeCertificate;\n return getCertificateHints(String(cert.server_id), String(cert.site_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatCertificateList(data as ForgeCertificate[]);\n case \"get\":\n return formatCertificate(data as ForgeCertificate);\n case \"create\":\n return formatCertificate(data as ForgeCertificate);\n case \"delete\":\n return `Certificate ${args.id} deleted.`;\n case \"activate\":\n return `Certificate ${args.id} activated.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { createCommand, getCommand, listCommands } from \"@studiometa/forge-core\";\n\nimport type { ForgeCommand } from \"@studiometa/forge-api\";\n\nimport { formatCommand, formatCommandList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleCommands = createResourceHandler({\n resource: \"commands\",\n actions: [\"list\", \"get\", \"create\"],\n requiredFields: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"command\"],\n },\n executors: {\n list: listCommands,\n get: getCommand,\n create: createCommand,\n },\n formatResult: (action, data) => {\n switch (action) {\n case \"list\":\n return formatCommandList(data as ForgeCommand[]);\n case \"get\":\n return formatCommand(data as ForgeCommand);\n case \"create\":\n return formatCommand(data as ForgeCommand);\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createDaemon,\n deleteDaemon,\n getDaemon,\n listDaemons,\n restartDaemon,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeDaemon } from \"@studiometa/forge-api\";\n\nimport { formatDaemon, formatDaemonList } from \"../formatters.ts\";\nimport { getDaemonHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleDaemons = createResourceHandler({\n resource: \"daemons\",\n actions: [\"list\", \"get\", \"create\", \"delete\", \"restart\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"command\"],\n delete: [\"server_id\", \"id\"],\n restart: [\"server_id\", \"id\"],\n },\n executors: {\n list: listDaemons,\n get: getDaemon,\n create: createDaemon,\n delete: deleteDaemon,\n restart: restartDaemon,\n },\n hints: (data, id) => {\n const daemon = data as ForgeDaemon;\n return getDaemonHints(String(daemon.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatDaemonList(data as ForgeDaemon[]);\n case \"get\":\n return formatDaemon(data as ForgeDaemon);\n case \"create\":\n return formatDaemon(data as ForgeDaemon);\n case \"delete\":\n return `Daemon ${args.id} deleted.`;\n case \"restart\":\n return `Daemon ${args.id} restarted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { createDatabase, deleteDatabase, getDatabase, listDatabases } from \"@studiometa/forge-core\";\n\nimport type { ForgeDatabase } from \"@studiometa/forge-api\";\n\nimport { formatDatabase, formatDatabaseList } from \"../formatters.ts\";\nimport { getDatabaseHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleDatabases = createResourceHandler({\n resource: \"databases\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listDatabases,\n get: getDatabase,\n create: createDatabase,\n delete: deleteDatabase,\n },\n hints: (data, id) => {\n const db = data as ForgeDatabase;\n return getDatabaseHints(String(db.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatDatabaseList(data as ForgeDatabase[]);\n case \"get\":\n return formatDatabase(data as ForgeDatabase);\n case \"create\":\n return formatDatabase(data as ForgeDatabase);\n case \"delete\":\n return `Database ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createDatabaseUser,\n deleteDatabaseUser,\n getDatabaseUser,\n listDatabaseUsers,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeDatabaseUser } from \"@studiometa/forge-api\";\n\nimport { formatDatabaseUser, formatDatabaseUserList } from \"../formatters.ts\";\nimport { getDatabaseUserHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleDatabaseUsers = createResourceHandler({\n resource: \"database-users\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"password\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listDatabaseUsers,\n get: getDatabaseUser,\n create: createDatabaseUser,\n delete: deleteDatabaseUser,\n },\n hints: (data, id) => {\n const user = data as ForgeDatabaseUser;\n return getDatabaseUserHints(String(user.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatDatabaseUserList(data as ForgeDatabaseUser[]);\n case \"get\":\n return formatDatabaseUser(data as ForgeDatabaseUser);\n case \"create\":\n return formatDatabaseUser(data as ForgeDatabaseUser);\n case \"delete\":\n return `Database user ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n deploySite,\n getDeploymentOutput,\n getDeploymentScript,\n listDeployments,\n updateDeploymentScript,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeDeployment } from \"@studiometa/forge-api\";\n\nimport {\n formatDeploymentList,\n formatDeploymentOutput,\n formatDeploymentScript,\n formatDeploymentScriptUpdated,\n formatDeployAction,\n} from \"../formatters.ts\";\nimport type { CommonArgs, HandlerContext, ToolResult } from \"./types.ts\";\n\nimport { errorResult, jsonResult, sanitizeId } from \"./utils.ts\";\n\n/**\n * Handle deployment resource actions.\n *\n * Not using the factory because the `get` action has special logic\n * (with id → output, without id → script).\n */\nexport async function handleDeployments(\n action: string,\n args: CommonArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n if (!args.server_id) return errorResult(\"Missing required field: server_id\");\n if (!args.site_id) return errorResult(\"Missing required field: site_id\");\n\n // Validate IDs to prevent path traversal\n if (!sanitizeId(args.server_id)) {\n return errorResult(`Invalid server_id: \"${args.server_id}\". IDs must be alphanumeric.`);\n }\n if (!sanitizeId(args.site_id)) {\n return errorResult(`Invalid site_id: \"${args.site_id}\". IDs must be alphanumeric.`);\n }\n if (args.id && !sanitizeId(args.id)) {\n return errorResult(`Invalid id: \"${args.id}\". IDs must be alphanumeric.`);\n }\n\n const opts = { server_id: args.server_id, site_id: args.site_id };\n\n switch (action) {\n case \"list\": {\n const result = await listDeployments(opts, ctx.executorContext);\n if (ctx.compact) {\n return jsonResult(formatDeploymentList(result.data as ForgeDeployment[]));\n }\n return jsonResult(result.data);\n }\n\n case \"deploy\": {\n await deploySite(opts, ctx.executorContext);\n return jsonResult(formatDeployAction(args.site_id, args.server_id));\n }\n\n case \"get\": {\n if (args.id) {\n const result = await getDeploymentOutput(\n { ...opts, deployment_id: args.id },\n ctx.executorContext,\n );\n return jsonResult(formatDeploymentOutput(args.id, result.data as string));\n }\n const result = await getDeploymentScript(opts, ctx.executorContext);\n return jsonResult(formatDeploymentScript(result.data as string));\n }\n\n case \"update\": {\n if (!args.content) return errorResult(\"Missing required field: content\");\n await updateDeploymentScript(\n { ...opts, content: args.content as string },\n ctx.executorContext,\n );\n return jsonResult(formatDeploymentScriptUpdated(args.site_id, args.server_id));\n }\n\n default:\n return errorResult(\n `Unknown action \"${action}\" for deployments. Valid actions: list, deploy, get, update.`,\n );\n }\n}\n","import { getEnv, updateEnv } from \"@studiometa/forge-core\";\n\nimport { formatEnv } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleEnv = createResourceHandler({\n resource: \"env\",\n actions: [\"get\", \"update\"],\n requiredFields: {\n get: [\"server_id\", \"site_id\"],\n update: [\"server_id\", \"site_id\", \"content\"],\n },\n executors: {\n get: getEnv,\n update: updateEnv,\n },\n mapOptions: (_action, args) => ({\n server_id: args.server_id,\n site_id: args.site_id,\n content: args.content,\n }),\n formatResult: (action, data) => {\n switch (action) {\n case \"get\":\n return formatEnv(data as string);\n case \"update\":\n return \"Environment variables updated.\";\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createFirewallRule,\n deleteFirewallRule,\n getFirewallRule,\n listFirewallRules,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeFirewallRule } from \"@studiometa/forge-api\";\n\nimport { formatFirewallRule, formatFirewallRuleList } from \"../formatters.ts\";\nimport { getFirewallRuleHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleFirewallRules = createResourceHandler({\n resource: \"firewall-rules\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"port\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listFirewallRules,\n get: getFirewallRule,\n create: createFirewallRule,\n delete: deleteFirewallRule,\n },\n hints: (data, id) => {\n const rule = data as ForgeFirewallRule;\n return getFirewallRuleHints(String(rule.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatFirewallRuleList(data as ForgeFirewallRule[]);\n case \"get\":\n return formatFirewallRule(data as ForgeFirewallRule);\n case \"create\":\n return formatFirewallRule(data as ForgeFirewallRule);\n case \"delete\":\n return `Firewall rule ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","/**\n * Help handler — provides detailed documentation for each resource.\n *\n * Follows the productive-tools convention: per-resource docs with\n * actions, required fields, field descriptions, and examples.\n */\n\nimport type { ToolResult } from \"./types.ts\";\n\nimport { jsonResult } from \"./utils.ts\";\n\ninterface ResourceHelp {\n description: string;\n scope: string;\n actions: Record<string, string>;\n fields?: Record<string, string>;\n examples?: Array<{ description: string; params: Record<string, unknown> }>;\n}\n\nconst RESOURCE_HELP: Record<string, ResourceHelp> = {\n servers: {\n description:\n \"Manage Laravel Forge servers — provisioned cloud instances (DigitalOcean, AWS, Hetzner, etc.)\",\n scope: \"global (no parent ID needed)\",\n actions: {\n list: \"List all servers in your Forge account\",\n get: \"Get a single server by ID with full details\",\n create: \"Provision a new server (requires provider, type, region, name)\",\n delete: \"Delete a server by ID (irreversible)\",\n reboot: \"Reboot a server by ID\",\n },\n fields: {\n id: \"Server ID\",\n name: \"Server name (hostname)\",\n provider: \"Cloud provider (hetzner, ocean2, aws, linode, vultr, custom)\",\n region: \"Provider region code\",\n ip_address: \"Public IP address\",\n is_ready: \"Whether the server has finished provisioning\",\n php_version: \"Default PHP version (php84, php83, etc.)\",\n },\n examples: [\n { description: \"List all servers\", params: { resource: \"servers\", action: \"list\" } },\n {\n description: \"Get server details\",\n params: { resource: \"servers\", action: \"get\", id: \"123\" },\n },\n {\n description: \"Reboot a server\",\n params: { resource: \"servers\", action: \"reboot\", id: \"123\" },\n },\n ],\n },\n\n sites: {\n description: \"Manage sites on a Forge server — web applications, PHP projects, static sites\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List all sites on a server\",\n get: \"Get a single site by ID\",\n create: \"Create a new site (requires domain, project_type)\",\n delete: \"Delete a site by ID\",\n },\n fields: {\n id: \"Site ID\",\n server_id: \"Parent server ID\",\n name: \"Domain name (e.g. example.com)\",\n project_type: \"Project type (php, html, symfony, symfony_dev, symfony_four, laravel)\",\n directory: \"Web root directory (e.g. /public)\",\n repository: \"Git repository URL (if connected)\",\n deployment_status: \"Last deployment status (null, deploying, deployed, failed)\",\n },\n examples: [\n {\n description: \"List sites on a server\",\n params: { resource: \"sites\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Get site details\",\n params: { resource: \"sites\", action: \"get\", server_id: \"123\", id: \"456\" },\n },\n {\n description: \"Create a Laravel site\",\n params: {\n resource: \"sites\",\n action: \"create\",\n server_id: \"123\",\n domain: \"app.example.com\",\n project_type: \"php\",\n directory: \"/public\",\n },\n },\n ],\n },\n\n deployments: {\n description: \"Manage site deployments — trigger, monitor, and configure deploy scripts\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n list: \"List recent deployments for a site\",\n deploy: \"Trigger a new deployment\",\n get: \"Get deployment output (requires deployment_id in 'id' field)\",\n update: \"Update the deployment script (provide 'content' field)\",\n },\n fields: {\n id: \"Deployment ID\",\n server_id: \"Parent server ID\",\n site_id: \"Parent site ID\",\n status: \"Deployment status (null, deploying, deployed, failed)\",\n displayable_type: \"Type of deployment trigger\",\n ended_at: \"Completion timestamp\",\n },\n examples: [\n {\n description: \"Deploy a site\",\n params: { resource: \"deployments\", action: \"deploy\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"List deployments\",\n params: { resource: \"deployments\", action: \"list\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Get deployment output\",\n params: {\n resource: \"deployments\",\n action: \"get\",\n server_id: \"123\",\n site_id: \"456\",\n id: \"789\",\n },\n },\n {\n description: \"Update deploy script\",\n params: {\n resource: \"deployments\",\n action: \"update\",\n server_id: \"123\",\n site_id: \"456\",\n content:\n \"cd /home/forge/app.example.com\\ngit pull\\ncomposer install\\nphp artisan migrate --force\",\n },\n },\n ],\n },\n\n env: {\n description: \"Manage environment variables (.env file) for a site\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n get: \"Get the current .env file content\",\n update: \"Replace the entire .env file (provide 'content' field)\",\n },\n examples: [\n {\n description: \"Get env variables\",\n params: { resource: \"env\", action: \"get\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Update env\",\n params: {\n resource: \"env\",\n action: \"update\",\n server_id: \"123\",\n site_id: \"456\",\n content: \"APP_ENV=production\\nAPP_DEBUG=false\\nDB_HOST=127.0.0.1\",\n },\n },\n ],\n },\n\n nginx: {\n description: \"Manage Nginx configuration for a site\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n get: \"Get the current Nginx config\",\n update: \"Replace the Nginx config (provide 'content' field)\",\n },\n examples: [\n {\n description: \"Get nginx config\",\n params: { resource: \"nginx\", action: \"get\", server_id: \"123\", site_id: \"456\" },\n },\n ],\n },\n\n certificates: {\n description: \"Manage SSL/TLS certificates for a site — Let's Encrypt, custom, or cloned\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n list: \"List certificates for a site\",\n get: \"Get certificate details\",\n create: \"Create/request a new certificate\",\n delete: \"Delete a certificate\",\n activate: \"Activate a certificate (make it the active cert for the site)\",\n },\n examples: [\n {\n description: \"List certificates\",\n params: { resource: \"certificates\", action: \"list\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Create Let's Encrypt cert\",\n params: {\n resource: \"certificates\",\n action: \"create\",\n server_id: \"123\",\n site_id: \"456\",\n domain: \"example.com\",\n type: \"new\",\n },\n },\n {\n description: \"Activate a certificate\",\n params: {\n resource: \"certificates\",\n action: \"activate\",\n server_id: \"123\",\n site_id: \"456\",\n id: \"789\",\n },\n },\n ],\n },\n\n databases: {\n description: \"Manage MySQL/PostgreSQL databases on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List databases on a server\",\n get: \"Get database details\",\n create: \"Create a new database (optionally with user)\",\n delete: \"Delete a database\",\n },\n fields: {\n name: \"Database name\",\n user: \"(create only) Create a database user\",\n password: \"(create only) User password\",\n },\n examples: [\n {\n description: \"List databases\",\n params: { resource: \"databases\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Create database with user\",\n params: {\n resource: \"databases\",\n action: \"create\",\n server_id: \"123\",\n name: \"myapp\",\n user: \"admin\",\n password: \"secret123\",\n },\n },\n ],\n },\n\n \"database-users\": {\n description: \"Manage database users on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List database users on a server\",\n get: \"Get database user details\",\n create: \"Create a new database user\",\n delete: \"Delete a database user\",\n },\n fields: {\n name: \"Database user name\",\n password: \"User password\",\n databases: \"(create only) Array of database IDs to grant access to\",\n },\n examples: [\n {\n description: \"List database users\",\n params: { resource: \"database-users\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Create a database user\",\n params: {\n resource: \"database-users\",\n action: \"create\",\n server_id: \"123\",\n name: \"forge\",\n password: \"secret123\",\n databases: [1, 2],\n },\n },\n ],\n },\n\n daemons: {\n description: \"Manage background processes (daemons) — queue workers, websocket servers, etc.\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List daemons on a server\",\n get: \"Get daemon details\",\n create: \"Create a new daemon\",\n delete: \"Delete a daemon\",\n restart: \"Restart a daemon\",\n },\n fields: {\n command: \"Shell command to run\",\n user: \"Execution user (default: forge)\",\n directory: \"Working directory\",\n processes: \"Number of processes (default: 1)\",\n },\n examples: [\n {\n description: \"List daemons\",\n params: { resource: \"daemons\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Create queue worker\",\n params: {\n resource: \"daemons\",\n action: \"create\",\n server_id: \"123\",\n command: \"php artisan queue:work --tries=3\",\n user: \"forge\",\n },\n },\n {\n description: \"Restart a daemon\",\n params: { resource: \"daemons\", action: \"restart\", server_id: \"123\", id: \"456\" },\n },\n ],\n },\n\n \"firewall-rules\": {\n description: \"Manage UFW firewall rules on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List firewall rules\",\n get: \"Get rule details\",\n create: \"Create a new firewall rule\",\n delete: \"Delete a firewall rule\",\n },\n fields: {\n name: \"Rule name/description\",\n port: \"Port number or range (e.g. 80, 8000-9000)\",\n type: \"allow or deny (default: allow)\",\n ip_address: \"Restrict to specific IP (optional)\",\n },\n examples: [\n {\n description: \"List firewall rules\",\n params: { resource: \"firewall-rules\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Open port 3000\",\n params: {\n resource: \"firewall-rules\",\n action: \"create\",\n server_id: \"123\",\n name: \"Allow Node.js\",\n port: 3000,\n },\n },\n ],\n },\n\n \"ssh-keys\": {\n description: \"Manage SSH keys on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List SSH keys\",\n get: \"Get key details\",\n create: \"Add an SSH key to the server\",\n delete: \"Remove an SSH key\",\n },\n fields: {\n name: \"Key label/description\",\n key: \"Public key content (ssh-rsa ...)\",\n username: \"User to add the key to (optional)\",\n },\n examples: [\n {\n description: \"List SSH keys\",\n params: { resource: \"ssh-keys\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Add SSH key\",\n params: {\n resource: \"ssh-keys\",\n action: \"create\",\n server_id: \"123\",\n name: \"Deploy Key\",\n key: \"ssh-rsa AAAA...\",\n },\n },\n ],\n },\n\n \"security-rules\": {\n description: \"Manage HTTP Basic Auth security rules for a site\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n list: \"List security rules\",\n get: \"Get rule details\",\n create: \"Create a security rule with credentials\",\n delete: \"Delete a security rule\",\n },\n examples: [\n {\n description: \"List security rules\",\n params: { resource: \"security-rules\", action: \"list\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Create basic auth\",\n params: {\n resource: \"security-rules\",\n action: \"create\",\n server_id: \"123\",\n site_id: \"456\",\n name: \"Staging Auth\",\n credentials: [{ username: \"admin\", password: \"secret\" }],\n },\n },\n ],\n },\n\n \"redirect-rules\": {\n description: \"Manage URL redirect rules for a site\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n list: \"List redirect rules\",\n get: \"Get rule details\",\n create: \"Create a redirect rule\",\n delete: \"Delete a redirect rule\",\n },\n fields: {\n from: \"Source path (regex supported)\",\n to: \"Destination URL\",\n type: \"redirect (302, default) or permanent (301)\",\n },\n examples: [\n {\n description: \"List redirects\",\n params: { resource: \"redirect-rules\", action: \"list\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Create redirect\",\n params: {\n resource: \"redirect-rules\",\n action: \"create\",\n server_id: \"123\",\n site_id: \"456\",\n from: \"/old-page\",\n to: \"/new-page\",\n type: \"permanent\",\n },\n },\n ],\n },\n\n monitors: {\n description: \"Manage server monitoring alerts — CPU, disk, memory thresholds\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List monitors\",\n get: \"Get monitor details\",\n create: \"Create a monitor\",\n delete: \"Delete a monitor\",\n },\n fields: {\n type: \"Monitor type (disk, cpu, memory)\",\n operator: \"Comparison operator (gte, lte)\",\n threshold: \"Threshold value (e.g. 80 for 80%)\",\n minutes: \"Check interval in minutes\",\n },\n examples: [\n {\n description: \"List monitors\",\n params: { resource: \"monitors\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Alert on high disk usage\",\n params: {\n resource: \"monitors\",\n action: \"create\",\n server_id: \"123\",\n type: \"disk\",\n operator: \"gte\",\n threshold: 80,\n minutes: 5,\n },\n },\n ],\n },\n\n \"nginx-templates\": {\n description: \"Manage reusable Nginx configuration templates on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List nginx templates\",\n get: \"Get template with content\",\n create: \"Create a new template\",\n update: \"Update template name or content\",\n delete: \"Delete a template\",\n },\n examples: [\n {\n description: \"List templates\",\n params: { resource: \"nginx-templates\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Get template content\",\n params: { resource: \"nginx-templates\", action: \"get\", server_id: \"123\", id: \"456\" },\n },\n ],\n },\n\n backups: {\n description:\n \"Manage backup configurations — automated database backups to S3, Spaces, or other providers\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List backup configurations on a server\",\n get: \"Get backup config details (databases, schedule, retention)\",\n create: \"Create a new backup configuration\",\n delete: \"Delete a backup configuration\",\n },\n fields: {\n provider: \"Backup provider (s3, spaces, custom)\",\n credentials: \"Provider credentials (keys, bucket, region)\",\n frequency: \"Backup frequency (daily, weekly, custom)\",\n databases: \"Array of database IDs to back up\",\n retention: \"Number of backups to retain\",\n },\n examples: [\n {\n description: \"List backup configs\",\n params: { resource: \"backups\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Get backup config details\",\n params: { resource: \"backups\", action: \"get\", server_id: \"123\", id: \"456\" },\n },\n ],\n },\n\n commands: {\n description: \"Execute and list site commands — run artisan commands or shell scripts on a site\",\n scope: \"site (requires server_id + site_id)\",\n actions: {\n list: \"List commands executed on a site\",\n get: \"Get command details and status\",\n create: \"Execute a new command on the site\",\n },\n fields: {\n command: \"Shell command to execute\",\n },\n examples: [\n {\n description: \"List commands\",\n params: { resource: \"commands\", action: \"list\", server_id: \"123\", site_id: \"456\" },\n },\n {\n description: \"Run a command\",\n params: {\n resource: \"commands\",\n action: \"create\",\n server_id: \"123\",\n site_id: \"456\",\n command: \"php artisan migrate --force\",\n },\n },\n ],\n },\n\n \"scheduled-jobs\": {\n description: \"Manage cron jobs (scheduled tasks) on a server\",\n scope: \"server (requires server_id)\",\n actions: {\n list: \"List scheduled jobs on a server\",\n get: \"Get job details (command, frequency, cron expression)\",\n create: \"Create a new scheduled job\",\n delete: \"Delete a scheduled job\",\n },\n fields: {\n command: \"Shell command to schedule\",\n user: \"Execution user (default: forge)\",\n frequency: \"Frequency preset (minutely, hourly, nightly, weekly, monthly, custom)\",\n minute: \"(custom frequency) Minute field\",\n hour: \"(custom frequency) Hour field\",\n day: \"(custom frequency) Day of month field\",\n month: \"(custom frequency) Month field\",\n weekday: \"(custom frequency) Day of week field\",\n },\n examples: [\n {\n description: \"List scheduled jobs\",\n params: { resource: \"scheduled-jobs\", action: \"list\", server_id: \"123\" },\n },\n {\n description: \"Create minutely scheduler\",\n params: {\n resource: \"scheduled-jobs\",\n action: \"create\",\n server_id: \"123\",\n command: \"php /home/forge/app.com/artisan schedule:run\",\n frequency: \"minutely\",\n user: \"forge\",\n },\n },\n ],\n },\n\n user: {\n description: \"Get the currently authenticated Forge user profile\",\n scope: \"global (no parent ID needed)\",\n actions: {\n get: \"Get the authenticated user's profile (name, email, connected services)\",\n },\n examples: [\n {\n description: \"Get user profile\",\n params: { resource: \"user\", action: \"get\" },\n },\n ],\n },\n\n recipes: {\n description:\n \"Manage and run server recipes — reusable bash scripts executed on one or more servers\",\n scope: \"global (no parent ID needed)\",\n actions: {\n list: \"List all recipes\",\n get: \"Get recipe details and script content\",\n create: \"Create a new recipe\",\n delete: \"Delete a recipe\",\n run: \"Run a recipe on specified servers (provide 'servers' as array of server IDs)\",\n },\n fields: {\n name: \"Recipe name\",\n script: \"Bash script content\",\n user: \"Execution user (default: root)\",\n servers: \"(run only) Array of server IDs to run on\",\n },\n examples: [\n { description: \"List recipes\", params: { resource: \"recipes\", action: \"list\" } },\n {\n description: \"Create a recipe\",\n params: {\n resource: \"recipes\",\n action: \"create\",\n name: \"Clear caches\",\n script: \"php artisan cache:clear\\nphp artisan view:clear\",\n },\n },\n {\n description: \"Run recipe on servers\",\n params: { resource: \"recipes\", action: \"run\", id: \"123\", servers: [1, 2, 3] },\n },\n ],\n },\n};\n\n/**\n * Handle help action — returns documentation for a specific resource.\n */\nexport function handleHelp(resource: string): ToolResult {\n const help = RESOURCE_HELP[resource];\n\n if (!help) {\n return handleHelpOverview();\n }\n\n return jsonResult({ resource, ...help });\n}\n\n/**\n * Get help for all resources (overview).\n */\nexport function handleHelpOverview(): ToolResult {\n const overview = Object.entries(RESOURCE_HELP).map(([resource, help]) => ({\n resource,\n description: help.description,\n scope: help.scope,\n actions: Object.keys(help.actions),\n }));\n\n return jsonResult({\n message: 'Use action=\"help\" with a specific resource for detailed documentation',\n resources: overview,\n _tip: \"Always call { action: 'help', resource: '<name>' } before your first interaction with any resource to learn required fields and examples.\",\n });\n}\n","import { createMonitor, deleteMonitor, getMonitor, listMonitors } from \"@studiometa/forge-core\";\n\nimport type { ForgeMonitor } from \"@studiometa/forge-api\";\n\nimport { formatMonitor, formatMonitorList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleMonitors = createResourceHandler({\n resource: \"monitors\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"type\", \"operator\", \"threshold\", \"minutes\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listMonitors,\n get: getMonitor,\n create: createMonitor,\n delete: deleteMonitor,\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatMonitorList(data as ForgeMonitor[]);\n case \"get\":\n return formatMonitor(data as ForgeMonitor);\n case \"create\":\n return formatMonitor(data as ForgeMonitor);\n case \"delete\":\n return `Monitor ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { getNginxConfig, updateNginxConfig } from \"@studiometa/forge-core\";\n\nimport { formatNginxConfig } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleNginxConfig = createResourceHandler({\n resource: \"nginx\",\n actions: [\"get\", \"update\"],\n requiredFields: {\n get: [\"server_id\", \"site_id\"],\n update: [\"server_id\", \"site_id\", \"content\"],\n },\n executors: {\n get: getNginxConfig,\n update: updateNginxConfig,\n },\n mapOptions: (_action, args) => ({\n server_id: args.server_id,\n site_id: args.site_id,\n content: args.content,\n }),\n formatResult: (action, data) => {\n switch (action) {\n case \"get\":\n return formatNginxConfig(data as string);\n case \"update\":\n return \"Nginx configuration updated.\";\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createNginxTemplate,\n deleteNginxTemplate,\n getNginxTemplate,\n listNginxTemplates,\n updateNginxTemplate,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeNginxTemplate } from \"@studiometa/forge-api\";\n\nimport { formatNginxTemplate, formatNginxTemplateList } from \"../formatters.ts\";\nimport { getNginxTemplateHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleNginxTemplates = createResourceHandler({\n resource: \"nginx-templates\",\n actions: [\"list\", \"get\", \"create\", \"update\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"content\"],\n update: [\"server_id\", \"id\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listNginxTemplates,\n get: getNginxTemplate,\n create: createNginxTemplate,\n update: updateNginxTemplate,\n delete: deleteNginxTemplate,\n },\n hints: (data, id) => {\n const template = data as ForgeNginxTemplate;\n return getNginxTemplateHints(String(template.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatNginxTemplateList(data as ForgeNginxTemplate[]);\n case \"get\":\n return formatNginxTemplate(data as ForgeNginxTemplate);\n case \"create\":\n return formatNginxTemplate(data as ForgeNginxTemplate);\n case \"update\":\n return formatNginxTemplate(data as ForgeNginxTemplate);\n case \"delete\":\n return `Nginx template ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createRecipe,\n deleteRecipe,\n getRecipe,\n listRecipes,\n runRecipe,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeRecipe } from \"@studiometa/forge-api\";\n\nimport { formatRecipe, formatRecipeList } from \"../formatters.ts\";\nimport { getRecipeHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleRecipes = createResourceHandler({\n resource: \"recipes\",\n actions: [\"list\", \"get\", \"create\", \"delete\", \"run\"],\n requiredFields: {\n get: [\"id\"],\n create: [\"name\", \"script\"],\n delete: [\"id\"],\n run: [\"id\", \"servers\"],\n },\n executors: {\n list: listRecipes,\n get: getRecipe,\n create: createRecipe,\n delete: deleteRecipe,\n run: runRecipe,\n },\n hints: (_data, id) => getRecipeHints(id),\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatRecipeList(data as ForgeRecipe[]);\n case \"get\":\n return formatRecipe(data as ForgeRecipe);\n case \"create\":\n return formatRecipe(data as ForgeRecipe);\n case \"delete\":\n return `Recipe ${args.id} deleted.`;\n case \"run\": {\n const servers = args.servers;\n const count = Array.isArray(servers) ? servers.length : 1;\n return `Recipe ${args.id} run on ${count} server(s).`;\n }\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createRedirectRule,\n deleteRedirectRule,\n getRedirectRule,\n listRedirectRules,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeRedirectRule } from \"@studiometa/forge-api\";\n\nimport { formatRedirectRule, formatRedirectRuleList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleRedirectRules = createResourceHandler({\n resource: \"redirect-rules\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"from\", \"to\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n },\n executors: {\n list: listRedirectRules,\n get: getRedirectRule,\n create: createRedirectRule,\n delete: deleteRedirectRule,\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatRedirectRuleList(data as ForgeRedirectRule[]);\n case \"get\":\n return formatRedirectRule(data as ForgeRedirectRule);\n case \"create\":\n return formatRedirectRule(data as ForgeRedirectRule);\n case \"delete\":\n return `Redirect rule ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createScheduledJob,\n deleteScheduledJob,\n getScheduledJob,\n listScheduledJobs,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeScheduledJob } from \"@studiometa/forge-api\";\n\nimport { formatScheduledJob, formatScheduledJobList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleScheduledJobs = createResourceHandler({\n resource: \"scheduled-jobs\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"command\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listScheduledJobs,\n get: getScheduledJob,\n create: createScheduledJob,\n delete: deleteScheduledJob,\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatScheduledJobList(data as ForgeScheduledJob[]);\n case \"get\":\n return formatScheduledJob(data as ForgeScheduledJob);\n case \"create\":\n return formatScheduledJob(data as ForgeScheduledJob);\n case \"delete\":\n return `Scheduled job ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","/**\n * Schema handler — compact, machine-readable resource specifications.\n *\n * More concise than action=help, optimized for LLM consumption when only\n * field metadata is needed (actions, required params, field descriptions).\n */\n\nimport type { ToolResult } from \"./types.ts\";\n\nimport { jsonResult } from \"./utils.ts\";\n\ninterface ResourceFieldSpec {\n required: boolean;\n type: string;\n}\n\ninterface ResourceSchemaData {\n actions: string[];\n scope: string;\n required: Record<string, string[]>;\n create?: Record<string, ResourceFieldSpec>;\n}\n\nconst RESOURCE_SCHEMAS: Record<string, ResourceSchemaData> = {\n servers: {\n actions: [\"list\", \"get\", \"create\", \"delete\", \"reboot\"],\n scope: \"global\",\n required: {\n get: [\"id\"],\n create: [\"provider\", \"type\", \"region\", \"name\"],\n delete: [\"id\"],\n reboot: [\"id\"],\n },\n create: {\n provider: { required: true, type: \"string — hetzner, ocean2, aws, etc.\" },\n type: { required: true, type: \"string — app, web, worker, etc.\" },\n region: { required: true, type: \"string — provider-specific region code\" },\n name: { required: true, type: \"string\" },\n credential_id: { required: false, type: \"string — provider credential ID\" },\n php_version: { required: false, type: \"string — php84, php83, etc.\" },\n database: { required: false, type: \"string — database name to create\" },\n },\n },\n\n sites: {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"domain\", \"project_type\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n domain: { required: true, type: \"string — e.g. example.com\" },\n project_type: { required: true, type: \"string — php, html, symfony, etc.\" },\n directory: { required: false, type: \"string — web root (/public)\" },\n },\n },\n\n deployments: {\n actions: [\"list\", \"deploy\", \"get\", \"update\"],\n scope: \"site\",\n required: {\n list: [\"server_id\", \"site_id\"],\n deploy: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n update: [\"server_id\", \"site_id\", \"content\"],\n },\n },\n\n env: {\n actions: [\"get\", \"update\"],\n scope: \"site\",\n required: {\n get: [\"server_id\", \"site_id\"],\n update: [\"server_id\", \"site_id\", \"content\"],\n },\n },\n\n nginx: {\n actions: [\"get\", \"update\"],\n scope: \"site\",\n required: {\n get: [\"server_id\", \"site_id\"],\n update: [\"server_id\", \"site_id\", \"content\"],\n },\n },\n\n certificates: {\n actions: [\"list\", \"get\", \"create\", \"delete\", \"activate\"],\n scope: \"site\",\n required: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"domain\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n activate: [\"server_id\", \"site_id\", \"id\"],\n },\n create: {\n type: { required: false, type: \"string — new, existing, clone (default: new)\" },\n domain: { required: true, type: \"string\" },\n },\n },\n\n databases: {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string — database name\" },\n user: { required: false, type: \"string — database user to create\" },\n password: { required: false, type: \"string — user password\" },\n },\n },\n\n \"database-users\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"password\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string — database user name\" },\n password: { required: true, type: \"string — user password\" },\n databases: { required: false, type: \"array — database IDs to grant access to\" },\n },\n },\n\n daemons: {\n actions: [\"list\", \"get\", \"create\", \"delete\", \"restart\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"command\"],\n delete: [\"server_id\", \"id\"],\n restart: [\"server_id\", \"id\"],\n },\n create: {\n command: { required: true, type: \"string — e.g. php artisan queue:work\" },\n user: { required: false, type: \"string — default: forge\" },\n directory: { required: false, type: \"string — working directory\" },\n processes: { required: false, type: \"number — default: 1\" },\n },\n },\n\n \"firewall-rules\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"port\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string\" },\n port: { required: true, type: \"number|string — e.g. 80, 443, 8000-9000\" },\n type: { required: false, type: \"string — allow (default) or deny\" },\n ip_address: { required: false, type: \"string — restrict to IP\" },\n },\n },\n\n \"ssh-keys\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"key\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string — key label\" },\n key: { required: true, type: \"string — public key content\" },\n username: { required: false, type: \"string — user to add key to\" },\n },\n },\n\n \"security-rules\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"site\",\n required: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"name\", \"credentials\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string — rule name\" },\n path: { required: false, type: \"string — protected path (default: /)\" },\n credentials: { required: true, type: \"array — [{username, password}]\" },\n },\n },\n\n \"redirect-rules\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"site\",\n required: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"from\", \"to\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n },\n create: {\n from: { required: true, type: \"string — source path\" },\n to: { required: true, type: \"string — destination URL\" },\n type: { required: false, type: \"string — redirect (302) or permanent (301)\" },\n },\n },\n\n monitors: {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"type\", \"operator\", \"threshold\", \"minutes\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n type: { required: true, type: \"string — disk, cpu, memory, etc.\" },\n operator: { required: true, type: \"string — gte, lte\" },\n threshold: { required: true, type: \"number — e.g. 80\" },\n minutes: { required: true, type: \"number — check interval in minutes\" },\n },\n },\n\n \"nginx-templates\": {\n actions: [\"list\", \"get\", \"create\", \"update\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"content\"],\n update: [\"server_id\", \"id\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n name: { required: true, type: \"string — template name\" },\n content: { required: true, type: \"string — nginx configuration template\" },\n },\n },\n\n backups: {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"provider\", \"credentials\", \"frequency\", \"databases\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n provider: { required: true, type: \"string — s3, spaces, custom\" },\n credentials: { required: true, type: \"object — provider credentials (key, secret, etc.)\" },\n frequency: { required: true, type: \"string — daily, weekly, custom\" },\n databases: { required: true, type: \"array — database IDs to back up\" },\n directory: { required: false, type: \"string — backup directory\" },\n email: { required: false, type: \"string — notification email\" },\n retention: { required: false, type: \"number — backups to retain (default: 7)\" },\n },\n },\n\n commands: {\n actions: [\"list\", \"get\", \"create\"],\n scope: \"site\",\n required: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"command\"],\n },\n create: {\n command: { required: true, type: \"string — shell command to execute\" },\n },\n },\n\n \"scheduled-jobs\": {\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n scope: \"server\",\n required: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"command\"],\n delete: [\"server_id\", \"id\"],\n },\n create: {\n command: { required: true, type: \"string — command to schedule\" },\n user: { required: false, type: \"string — execution user (default: forge)\" },\n frequency: {\n required: false,\n type: \"string — minutely, hourly, nightly, weekly, monthly, custom\",\n },\n minute: { required: false, type: \"string — cron minute field (custom frequency)\" },\n hour: { required: false, type: \"string — cron hour field\" },\n day: { required: false, type: \"string — cron day field\" },\n month: { required: false, type: \"string — cron month field\" },\n weekday: { required: false, type: \"string — cron weekday field\" },\n },\n },\n\n user: {\n actions: [\"get\"],\n scope: \"global\",\n required: {},\n },\n\n recipes: {\n actions: [\"list\", \"get\", \"create\", \"delete\", \"run\"],\n scope: \"global\",\n required: {\n get: [\"id\"],\n create: [\"name\", \"script\"],\n delete: [\"id\"],\n run: [\"id\", \"servers\"],\n },\n create: {\n name: { required: true, type: \"string — recipe name\" },\n script: { required: true, type: \"string — bash script content\" },\n user: { required: false, type: \"string — execution user (default: root)\" },\n },\n },\n};\n\n/**\n * Handle schema action — returns compact spec for a specific resource.\n */\nexport function handleSchema(resource: string): ToolResult {\n const schema = RESOURCE_SCHEMAS[resource];\n\n if (!schema) {\n return jsonResult({\n error: `Unknown resource: ${resource}`,\n available_resources: Object.keys(RESOURCE_SCHEMAS),\n });\n }\n\n return jsonResult({ resource, ...schema });\n}\n\n/**\n * Get schema overview for all resources.\n */\nexport function handleSchemaOverview(): ToolResult {\n const overview = Object.entries(RESOURCE_SCHEMAS).map(([resource, schema]) => ({\n resource,\n actions: schema.actions,\n scope: schema.scope,\n }));\n\n return jsonResult({\n _tip: 'Use action=\"schema\" with a specific resource for full required/create spec',\n resources: overview,\n });\n}\n","import {\n createSecurityRule,\n deleteSecurityRule,\n getSecurityRule,\n listSecurityRules,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeSecurityRule } from \"@studiometa/forge-api\";\n\nimport { formatSecurityRule, formatSecurityRuleList } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleSecurityRules = createResourceHandler({\n resource: \"security-rules\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\", \"site_id\"],\n get: [\"server_id\", \"site_id\", \"id\"],\n create: [\"server_id\", \"site_id\", \"name\", \"credentials\"],\n delete: [\"server_id\", \"site_id\", \"id\"],\n },\n executors: {\n list: listSecurityRules,\n get: getSecurityRule,\n create: createSecurityRule,\n delete: deleteSecurityRule,\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatSecurityRuleList(data as ForgeSecurityRule[]);\n case \"get\":\n return formatSecurityRule(data as ForgeSecurityRule);\n case \"create\":\n return formatSecurityRule(data as ForgeSecurityRule);\n case \"delete\":\n return `Security rule ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import {\n createServer,\n deleteServer,\n getServer,\n listServers,\n rebootServer,\n} from \"@studiometa/forge-core\";\n\nimport type { ForgeServer } from \"@studiometa/forge-api\";\n\nimport { formatServer, formatServerList } from \"../formatters.ts\";\nimport { getServerHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleServers = createResourceHandler({\n resource: \"servers\",\n actions: [\"list\", \"get\", \"create\", \"delete\", \"reboot\"],\n requiredFields: {\n get: [\"id\"],\n create: [\"provider\", \"name\", \"type\", \"region\"],\n delete: [\"id\"],\n reboot: [\"id\"],\n },\n executors: {\n list: listServers,\n get: getServer,\n create: createServer,\n delete: deleteServer,\n reboot: rebootServer,\n },\n hints: (_data, id) => getServerHints(id),\n mapOptions: (action, args) => {\n switch (action) {\n case \"get\":\n case \"delete\":\n case \"reboot\":\n return { server_id: args.id };\n case \"create\":\n return {\n provider: args.provider,\n /* v8 ignore next */\n credential_id: Number(args.credential_id) || 0,\n name: args.name,\n /* v8 ignore next */\n type: args.type ?? \"app\",\n /* v8 ignore next */\n size: args.size ?? \"\",\n region: args.region,\n };\n default:\n return {};\n }\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatServerList(data as ForgeServer[]);\n case \"get\":\n return formatServer(data as ForgeServer);\n case \"create\":\n return formatServer(data as ForgeServer);\n case \"delete\":\n return `Server ${args.id} deleted.`;\n case \"reboot\":\n return `Server ${args.id} reboot initiated.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { createSite, deleteSite, getSite, listSites } from \"@studiometa/forge-core\";\n\nimport type { ForgeSite } from \"@studiometa/forge-api\";\n\nimport { formatSite, formatSiteList } from \"../formatters.ts\";\nimport { getSiteHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleSites = createResourceHandler({\n resource: \"sites\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"domain\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listSites,\n get: getSite,\n create: createSite,\n delete: deleteSite,\n },\n hints: (data, id) => {\n const site = data as ForgeSite;\n return getSiteHints(String(site.server_id), id);\n },\n mapOptions: (action, args) => {\n switch (action) {\n case \"list\":\n return { server_id: args.server_id };\n case \"get\":\n return { server_id: args.server_id, site_id: args.id };\n case \"create\":\n return {\n server_id: args.server_id,\n domain: args.domain,\n project_type: args.project_type ?? \"php\",\n directory: args.directory,\n };\n case \"delete\":\n return { server_id: args.server_id, site_id: args.id };\n /* v8 ignore next */\n default:\n return {};\n }\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatSiteList(data as ForgeSite[], args.server_id as string | undefined);\n case \"get\":\n return formatSite(data as ForgeSite);\n case \"create\":\n return formatSite(data as ForgeSite);\n case \"delete\":\n return `Site ${args.id} deleted from server ${args.server_id}.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { createSshKey, deleteSshKey, getSshKey, listSshKeys } from \"@studiometa/forge-core\";\n\nimport type { ForgeSshKey } from \"@studiometa/forge-api\";\n\nimport { formatSshKey, formatSshKeyList } from \"../formatters.ts\";\nimport { getSshKeyHints } from \"../hints.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleSshKeys = createResourceHandler({\n resource: \"ssh-keys\",\n actions: [\"list\", \"get\", \"create\", \"delete\"],\n requiredFields: {\n list: [\"server_id\"],\n get: [\"server_id\", \"id\"],\n create: [\"server_id\", \"name\", \"key\"],\n delete: [\"server_id\", \"id\"],\n },\n executors: {\n list: listSshKeys,\n get: getSshKey,\n create: createSshKey,\n delete: deleteSshKey,\n },\n hints: (data, id) => {\n const key = data as ForgeSshKey;\n return getSshKeyHints(String(key.server_id), id);\n },\n formatResult: (action, data, args) => {\n switch (action) {\n case \"list\":\n return formatSshKeyList(data as ForgeSshKey[]);\n case \"get\":\n return formatSshKey(data as ForgeSshKey);\n case \"create\":\n return formatSshKey(data as ForgeSshKey);\n case \"delete\":\n return `SSH key ${args.id} deleted.`;\n /* v8 ignore next */\n default:\n return \"Done.\";\n }\n },\n});\n","import { getUser } from \"@studiometa/forge-core\";\n\nimport type { ForgeUser } from \"@studiometa/forge-api\";\n\nimport { formatUser } from \"../formatters.ts\";\nimport { createResourceHandler } from \"./factory.ts\";\n\nexport const handleUser = createResourceHandler({\n resource: \"user\",\n actions: [\"get\"],\n executors: {\n get: getUser,\n },\n formatResult: (_action, data) => {\n return formatUser(data as ForgeUser);\n },\n});\n","/**\n * Tool execution handlers for Forge MCP server.\n * Shared between stdio and HTTP transports.\n *\n * Single consolidated tool for minimal token overhead:\n * - forge: resource + action based API\n */\n\nimport type { ExecutorContext } from \"@studiometa/forge-core\";\n\nimport { HttpClient } from \"@studiometa/forge-api\";\nimport { RESOURCES } from \"@studiometa/forge-core\";\n\nimport type { CommonArgs, HandlerContext, ToolResult } from \"./types.ts\";\n\nimport { handleBackups } from \"./backups.ts\";\nimport { handleCertificates } from \"./certificates.ts\";\nimport { handleCommands } from \"./commands.ts\";\nimport { handleDaemons } from \"./daemons.ts\";\nimport { handleDatabases } from \"./databases.ts\";\nimport { handleDatabaseUsers } from \"./database-users.ts\";\nimport { handleDeployments } from \"./deployments.ts\";\nimport { handleEnv } from \"./env.ts\";\nimport { handleFirewallRules } from \"./firewall-rules.ts\";\nimport { handleHelp, handleHelpOverview } from \"./help.ts\";\nimport { handleMonitors } from \"./monitors.ts\";\nimport { handleNginxConfig } from \"./nginx-config.ts\";\nimport { handleNginxTemplates } from \"./nginx-templates.ts\";\nimport { handleRecipes } from \"./recipes.ts\";\nimport { handleRedirectRules } from \"./redirect-rules.ts\";\nimport { handleScheduledJobs } from \"./scheduled-jobs.ts\";\nimport { handleSchema, handleSchemaOverview } from \"./schema.ts\";\nimport { handleSecurityRules } from \"./security-rules.ts\";\nimport { handleServers } from \"./servers.ts\";\nimport { handleSites } from \"./sites.ts\";\nimport { handleSshKeys } from \"./ssh-keys.ts\";\nimport { handleUser } from \"./user.ts\";\nimport { isForgeApiError } from \"@studiometa/forge-api\";\n\nimport { isUserInputError } from \"../errors.ts\";\nimport { errorResult } from \"./utils.ts\";\n\nexport type { ToolResult } from \"./types.ts\";\n\n/** Valid resources derived from core constants */\nconst VALID_RESOURCES = [...RESOURCES];\n\n/**\n * Route to the appropriate resource handler.\n */\nfunction routeToHandler(\n resource: string,\n action: string,\n args: CommonArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n switch (resource) {\n case \"servers\":\n return handleServers(action, args, ctx);\n case \"sites\":\n return handleSites(action, args, ctx);\n case \"deployments\":\n return handleDeployments(action, args, ctx);\n case \"env\":\n return handleEnv(action, args, ctx);\n case \"nginx\":\n return handleNginxConfig(action, args, ctx);\n case \"certificates\":\n return handleCertificates(action, args, ctx);\n case \"databases\":\n return handleDatabases(action, args, ctx);\n case \"database-users\":\n return handleDatabaseUsers(action, args, ctx);\n case \"daemons\":\n return handleDaemons(action, args, ctx);\n case \"firewall-rules\":\n return handleFirewallRules(action, args, ctx);\n case \"ssh-keys\":\n return handleSshKeys(action, args, ctx);\n case \"security-rules\":\n return handleSecurityRules(action, args, ctx);\n case \"redirect-rules\":\n return handleRedirectRules(action, args, ctx);\n case \"monitors\":\n return handleMonitors(action, args, ctx);\n case \"nginx-templates\":\n return handleNginxTemplates(action, args, ctx);\n case \"recipes\":\n return handleRecipes(action, args, ctx);\n case \"backups\":\n return handleBackups(action, args, ctx);\n case \"commands\":\n return handleCommands(action, args, ctx);\n case \"scheduled-jobs\":\n return handleScheduledJobs(action, args, ctx);\n case \"user\":\n return handleUser(action, args, ctx);\n /* v8 ignore next 6 -- all valid resources are handled above; unreachable in practice */\n default:\n return Promise.resolve(\n errorResult(\n `Unknown resource \"${resource}\". Valid resources: ${VALID_RESOURCES.join(\", \")}. Use action=\"help\" for documentation.`,\n ),\n );\n }\n}\n\n/**\n * Execute a tool call with provided credentials.\n *\n * This is the main entry point shared between stdio and HTTP transports.\n */\nexport async function executeToolWithCredentials(\n _name: string,\n args: Record<string, unknown>,\n credentials: { apiToken: string },\n): Promise<ToolResult> {\n const { resource, action, compact, ...rest } = args as CommonArgs;\n\n if (!resource || !action) {\n return errorResult('Missing required fields: \"resource\" and \"action\".');\n }\n\n // Help is available for all resources (doesn't need API)\n if (action === \"help\") {\n /* v8 ignore start */\n return resource ? handleHelp(resource) : handleHelpOverview();\n /* v8 ignore stop */\n }\n\n // Schema is available for all resources (doesn't need API)\n if (action === \"schema\") {\n /* v8 ignore start */\n return resource ? handleSchema(resource) : handleSchemaOverview();\n /* v8 ignore stop */\n }\n\n // Validate resource\n if (!VALID_RESOURCES.includes(resource as (typeof VALID_RESOURCES)[number])) {\n return errorResult(\n `Unknown resource \"${resource}\". Valid resources: ${VALID_RESOURCES.join(\", \")}. Use action=\"help\" for documentation.`,\n );\n }\n\n // Create executor context\n const client = new HttpClient({ token: credentials.apiToken });\n const executorContext: ExecutorContext = { client };\n const handlerContext: HandlerContext = {\n executorContext,\n compact: compact ?? action !== \"get\",\n includeHints: action === \"get\",\n };\n\n // Route to resource handler with error catching\n try {\n return await routeToHandler(\n resource,\n action,\n { resource, action, ...rest } as CommonArgs,\n handlerContext,\n );\n } catch (error) {\n if (isUserInputError(error)) {\n return errorResult(error.toFormattedMessage());\n }\n if (isForgeApiError(error)) {\n return errorResult(`Forge API error (${error.status}): ${error.message}`);\n }\n /* v8 ignore start */\n const message = error instanceof Error ? error.message : String(error);\n /* v8 ignore stop */\n return errorResult(message);\n }\n}\n","import { ACTIONS, RESOURCES } from \"@studiometa/forge-core\";\n\n/**\n * Tool type matching MCP SDK expectations.\n */\ninterface Tool {\n name: string;\n description: string;\n annotations?: Record<string, unknown>;\n inputSchema: Record<string, unknown>;\n}\n\n/**\n * Generate the tool description dynamically from the constants.\n */\nfunction generateDescription(): string {\n return [\n \"Laravel Forge API.\",\n `Resources: ${RESOURCES.join(\", \")}.`,\n `Actions: ${ACTIONS.join(\", \")} (varies by resource).`,\n \"Discovery: action=help with any resource for filters and examples.\",\n \"Server operations require id. Site operations require server_id.\",\n \"Deployment operations require server_id and site_id.\",\n ].join(\"\\n\");\n}\n\n/**\n * Single consolidated tool for Laravel Forge MCP server.\n *\n * The resource/action enums and description are derived from\n * the shared constants in forge-core — the single source of truth.\n */\nexport const TOOLS: Tool[] = [\n {\n name: \"forge\",\n description: generateDescription(),\n annotations: {\n title: \"Laravel Forge\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n inputSchema: {\n type: \"object\",\n properties: {\n resource: {\n type: \"string\",\n enum: [...RESOURCES],\n },\n action: {\n type: \"string\",\n enum: [...ACTIONS],\n description: 'Use \"help\" for resource documentation',\n },\n id: { type: \"string\", description: \"Resource ID\" },\n server_id: { type: \"string\", description: \"Server ID (required for most resources)\" },\n site_id: { type: \"string\", description: \"Site ID (required for site-level resources)\" },\n compact: {\n type: \"boolean\",\n description: \"Compact output (default: true for list, false for get)\",\n },\n // Server fields\n name: { type: \"string\" },\n provider: { type: \"string\" },\n region: { type: \"string\" },\n size: { type: \"string\" },\n credential_id: { type: \"string\" },\n type: { type: \"string\" },\n // Site fields\n domain: { type: \"string\" },\n project_type: { type: \"string\" },\n directory: { type: \"string\" },\n // Content fields (env, nginx, deployment script)\n content: { type: \"string\", description: \"Content for env, nginx, or deployment script\" },\n // Daemon fields\n command: { type: \"string\", description: \"Shell command (daemons, recipes)\" },\n user: { type: \"string\", description: \"Execution user (daemons, recipes)\" },\n // Firewall fields\n port: { type: [\"string\", \"number\"], description: \"Port number or range (firewall rules)\" },\n ip_address: { type: \"string\", description: \"IP address (firewall rules)\" },\n // SSH key fields\n key: { type: \"string\", description: \"Public SSH key content\" },\n // Redirect fields\n from: { type: \"string\", description: \"Source path (redirect rules)\" },\n to: { type: \"string\", description: \"Destination URL (redirect rules)\" },\n // Security rule fields\n credentials: {\n type: \"array\",\n description: \"Credentials array [{username, password}] (security rules)\",\n items: { type: \"object\" },\n },\n // Monitor fields\n operator: { type: \"string\", description: \"Comparison operator (monitors)\" },\n threshold: { type: \"number\", description: \"Threshold value (monitors)\" },\n minutes: { type: \"number\", description: \"Check interval in minutes (monitors)\" },\n // Recipe fields\n script: { type: \"string\", description: \"Bash script content (recipes)\" },\n servers: {\n type: \"array\",\n description: \"Server IDs to run recipe on\",\n items: { type: \"number\" },\n },\n },\n required: [\"resource\", \"action\"],\n },\n },\n];\n\n/**\n * Additional tools only available in stdio mode.\n */\nexport const STDIO_ONLY_TOOLS: Tool[] = [\n {\n name: \"forge_configure\",\n description: \"Configure Laravel Forge API token\",\n annotations: {\n title: \"Configure Forge\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: \"object\",\n properties: {\n apiToken: { type: \"string\", description: \"Your Laravel Forge API token\" },\n },\n required: [\"apiToken\"],\n },\n },\n {\n name: \"forge_get_config\",\n description: \"Get current Forge configuration\",\n annotations: {\n title: \"Get Forge Config\",\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n];\n","declare const __VERSION__: string;\n\nexport const VERSION: string = typeof __VERSION__ !== \"undefined\" ? __VERSION__ : \"0.0.0-dev\";\n"],"mappings":"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"}
|