@studiometa/forge-mcp 0.4.4 → 0.4.6

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.
@@ -2,7 +2,8 @@ import { readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { HttpClient, isForgeApiError } from "@studiometa/forge-api";
5
- import { RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
5
+ import { RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDaemonLog, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listServices, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, restartService, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
6
+ //#region src/instructions.ts
6
7
  /**
7
8
  * MCP Server Instructions
8
9
  *
@@ -24,7 +25,9 @@ function loadInstructions() {
24
25
  return "Laravel Forge MCP Server - Use the forge tool with resource and action parameters. Call action=\"help\" for documentation.";
25
26
  }
26
27
  }
27
- const INSTRUCTIONS = loadInstructions();
28
+ var INSTRUCTIONS = loadInstructions();
29
+ //#endregion
30
+ //#region ../../node_modules/valibot/dist/index.mjs
28
31
  var store$4;
29
32
  /**
30
33
  * Returns the global configuration.
@@ -417,6 +420,8 @@ function safeParse(schema, input, config$1) {
417
420
  issues: dataset.issues
418
421
  };
419
422
  }
423
+ //#endregion
424
+ //#region src/formatters.ts
420
425
  /**
421
426
  * Format a list of servers.
422
427
  */
@@ -559,6 +564,12 @@ function formatDaemon(daemon) {
559
564
  return `Daemon: ${daemon.command} (ID: ${daemon.id})\nUser: ${daemon.user}\nProcesses: ${daemon.processes}\nStatus: ${daemon.status}`;
560
565
  }
561
566
  /**
567
+ * Format a daemon log.
568
+ */
569
+ function formatDaemonLog(daemonId, log) {
570
+ return `Daemon ${daemonId} log:\n${log}`;
571
+ }
572
+ /**
562
573
  * Format a list of firewall rules.
563
574
  */
564
575
  function formatFirewallRuleList(rules) {
@@ -741,6 +752,19 @@ function formatUser(user) {
741
752
  ].join("\n");
742
753
  }
743
754
  /**
755
+ * Format a list of services with their derived availability.
756
+ */
757
+ function formatServiceList(services) {
758
+ const lines = services.map((s) => {
759
+ const status = s.available ? "available" : "unavailable";
760
+ const detail = s.detail ? ` (${s.detail})` : "";
761
+ return `• ${s.service} — ${status}${detail}`;
762
+ });
763
+ return `${services.length} service(s):\n${lines.join("\n")}`;
764
+ }
765
+ //#endregion
766
+ //#region src/errors.ts
767
+ /**
744
768
  * Custom error classes for MCP server
745
769
  *
746
770
  * These provide structured error handling with LLM-friendly messages
@@ -774,6 +798,8 @@ var UserInputError = class extends Error {
774
798
  function isUserInputError(error) {
775
799
  return error instanceof UserInputError;
776
800
  }
801
+ //#endregion
802
+ //#region src/handlers/utils.ts
777
803
  /**
778
804
  * Create a successful result with both human-readable text and structured content.
779
805
  *
@@ -818,6 +844,8 @@ function errorResult(message) {
818
844
  isError: true
819
845
  };
820
846
  }
847
+ //#endregion
848
+ //#region src/handlers/factory.ts
821
849
  /**
822
850
  * Factory for creating Forge resource handlers.
823
851
  *
@@ -875,7 +903,9 @@ function createResourceHandler(config) {
875
903
  return jsonResult(result.data);
876
904
  };
877
905
  }
878
- const handleBackups = createResourceHandler({
906
+ //#endregion
907
+ //#region src/handlers/backups.ts
908
+ var handleBackups = createResourceHandler({
879
909
  resource: "backups",
880
910
  actions: [
881
911
  "list",
@@ -931,26 +961,30 @@ const handleBackups = createResourceHandler({
931
961
  case "create": return "Done.";
932
962
  case "update": return "Done.";
933
963
  case "delete": return `Backup config ${args.id} deleted.`;
964
+ /* v8 ignore next */
934
965
  default: return "Done.";
935
966
  }
936
967
  }
937
968
  });
969
+ //#endregion
970
+ //#region src/tools.ts
938
971
  /**
939
972
  * Read-only actions — safe operations that don't modify server state.
940
973
  */
941
- const READ_ACTIONS = [
974
+ var READ_ACTIONS = [
942
975
  "list",
943
976
  "get",
944
977
  "resolve",
945
978
  "help",
946
979
  "schema",
947
- "context"
980
+ "context",
981
+ "log"
948
982
  ];
949
983
  /**
950
984
  * Write actions — operations that modify server state.
951
985
  * These are separated into the `forge_write` tool for safety.
952
986
  */
953
- const WRITE_ACTIONS = [
987
+ var WRITE_ACTIONS = [
954
988
  "create",
955
989
  "update",
956
990
  "delete",
@@ -1042,7 +1076,7 @@ var SHARED_INPUT_PROPERTIES = {
1042
1076
  * - `forge` — read-only operations (auto-approvable by MCP clients)
1043
1077
  * - `forge_write` — write operations (always requires confirmation)
1044
1078
  */
1045
- const TOOLS = [{
1079
+ var TOOLS = [{
1046
1080
  name: "forge",
1047
1081
  title: "Laravel Forge",
1048
1082
  description: [
@@ -1208,6 +1242,14 @@ const TOOLS = [{
1208
1242
  type: "array",
1209
1243
  description: "Server IDs to run a recipe on (e.g. [123, 456])",
1210
1244
  items: { type: "number" }
1245
+ },
1246
+ service: {
1247
+ type: "string",
1248
+ description: "Service to restart (services: nginx, php, mysql, postgres, redis, supervisor)"
1249
+ },
1250
+ version: {
1251
+ type: "string",
1252
+ description: "PHP version required when restarting the php service (e.g. php83)"
1211
1253
  }
1212
1254
  },
1213
1255
  required: ["resource", "action"]
@@ -1227,7 +1269,7 @@ function getTools(options) {
1227
1269
  /**
1228
1270
  * Additional tools only available in stdio mode.
1229
1271
  */
1230
- const STDIO_ONLY_TOOLS = [{
1272
+ var STDIO_ONLY_TOOLS = [{
1231
1273
  name: "forge_configure",
1232
1274
  title: "Configure Forge",
1233
1275
  description: "Configure Laravel Forge API credentials. The token is stored locally in the XDG config directory.",
@@ -1300,6 +1342,8 @@ const STDIO_ONLY_TOOLS = [{
1300
1342
  required: ["configured"]
1301
1343
  }
1302
1344
  }];
1345
+ //#endregion
1346
+ //#region src/handlers/batch.ts
1303
1347
  var MAX_OPERATIONS = 10;
1304
1348
  /**
1305
1349
  * Validate and narrow an array element to a BatchOperation.
@@ -1392,6 +1436,8 @@ async function handleBatch(action, args, ctx, routeToHandler) {
1392
1436
  results
1393
1437
  });
1394
1438
  }
1439
+ //#endregion
1440
+ //#region src/hints.ts
1395
1441
  /**
1396
1442
  * Hints after getting a server.
1397
1443
  */
@@ -1755,7 +1801,9 @@ function getNginxTemplateHints(serverId, templateId) {
1755
1801
  }]
1756
1802
  };
1757
1803
  }
1758
- const handleCertificates = createResourceHandler({
1804
+ //#endregion
1805
+ //#region src/handlers/certificates.ts
1806
+ var handleCertificates = createResourceHandler({
1759
1807
  resource: "certificates",
1760
1808
  actions: [
1761
1809
  "get",
@@ -1799,11 +1847,14 @@ const handleCertificates = createResourceHandler({
1799
1847
  case "create": return formatCertificate(data);
1800
1848
  case "delete": return `Certificate for domain ${String(args.domain_id)} deleted.`;
1801
1849
  case "activate": return `Certificate for domain ${String(args.domain_id)} activated.`;
1850
+ /* v8 ignore next */
1802
1851
  default: return "Done.";
1803
1852
  }
1804
1853
  }
1805
1854
  });
1806
- const handleCommands = createResourceHandler({
1855
+ //#endregion
1856
+ //#region src/handlers/commands.ts
1857
+ var handleCommands = createResourceHandler({
1807
1858
  resource: "commands",
1808
1859
  actions: [
1809
1860
  "list",
@@ -1836,11 +1887,14 @@ const handleCommands = createResourceHandler({
1836
1887
  case "list": return formatCommandList(data);
1837
1888
  case "get": return formatCommand(data);
1838
1889
  case "create": return "Done.";
1890
+ /* v8 ignore next */
1839
1891
  default: return "Done.";
1840
1892
  }
1841
1893
  }
1842
1894
  });
1843
- const handleDaemons = createResourceHandler({
1895
+ //#endregion
1896
+ //#region src/handlers/daemons.ts
1897
+ var handleDaemons = createResourceHandler({
1844
1898
  resource: "daemons",
1845
1899
  actions: [
1846
1900
  "list",
@@ -1848,7 +1902,8 @@ const handleDaemons = createResourceHandler({
1848
1902
  "create",
1849
1903
  "update",
1850
1904
  "delete",
1851
- "restart"
1905
+ "restart",
1906
+ "log"
1852
1907
  ],
1853
1908
  inputSchemas: {
1854
1909
  list: /* @__PURE__ */ object({ server_id: /* @__PURE__ */ string() }),
@@ -1856,6 +1911,10 @@ const handleDaemons = createResourceHandler({
1856
1911
  server_id: /* @__PURE__ */ string(),
1857
1912
  id: /* @__PURE__ */ string()
1858
1913
  }),
1914
+ log: /* @__PURE__ */ object({
1915
+ server_id: /* @__PURE__ */ string(),
1916
+ id: /* @__PURE__ */ string()
1917
+ }),
1859
1918
  create: /* @__PURE__ */ object({
1860
1919
  server_id: /* @__PURE__ */ string(),
1861
1920
  command: /* @__PURE__ */ string()
@@ -1881,7 +1940,8 @@ const handleDaemons = createResourceHandler({
1881
1940
  create: createDaemon,
1882
1941
  update: updateDaemon,
1883
1942
  delete: deleteDaemon,
1884
- restart: restartDaemon
1943
+ restart: restartDaemon,
1944
+ log: getDaemonLog
1885
1945
  },
1886
1946
  hints: (_data, id, args) => getDaemonHints(String(args.server_id), id),
1887
1947
  formatResult: (action, data, args) => {
@@ -1892,11 +1952,15 @@ const handleDaemons = createResourceHandler({
1892
1952
  case "update": return formatDaemon(data);
1893
1953
  case "delete": return `Daemon ${args.id} deleted.`;
1894
1954
  case "restart": return `Daemon ${args.id} restarted.`;
1955
+ case "log": return formatDaemonLog(String(args.id), data);
1956
+ /* v8 ignore next */
1895
1957
  default: return "Done.";
1896
1958
  }
1897
1959
  }
1898
1960
  });
1899
- const handleDatabases = createResourceHandler({
1961
+ //#endregion
1962
+ //#region src/handlers/databases.ts
1963
+ var handleDatabases = createResourceHandler({
1900
1964
  resource: "databases",
1901
1965
  actions: [
1902
1966
  "list",
@@ -1932,11 +1996,14 @@ const handleDatabases = createResourceHandler({
1932
1996
  case "get": return formatDatabase(data);
1933
1997
  case "create": return formatDatabase(data);
1934
1998
  case "delete": return `Database ${args.id} deleted.`;
1999
+ /* v8 ignore next */
1935
2000
  default: return "Done.";
1936
2001
  }
1937
2002
  }
1938
2003
  });
1939
- const handleDatabaseUsers = createResourceHandler({
2004
+ //#endregion
2005
+ //#region src/handlers/database-users.ts
2006
+ var handleDatabaseUsers = createResourceHandler({
1940
2007
  resource: "database-users",
1941
2008
  actions: [
1942
2009
  "list",
@@ -1982,10 +2049,13 @@ const handleDatabaseUsers = createResourceHandler({
1982
2049
  case "create": return formatDatabaseUser(data);
1983
2050
  case "update": return formatDatabaseUser(data);
1984
2051
  case "delete": return `Database user ${args.id} deleted.`;
2052
+ /* v8 ignore next */
1985
2053
  default: return "Done.";
1986
2054
  }
1987
2055
  }
1988
2056
  });
2057
+ //#endregion
2058
+ //#region src/handlers/deployments.ts
1989
2059
  /**
1990
2060
  * Handle deployment resource actions.
1991
2061
  *
@@ -2031,7 +2101,9 @@ async function handleDeployments(action, args, ctx) {
2031
2101
  default: return errorResult(`Unknown action "${action}" for deployments. Valid actions: list, deploy, get, update.`);
2032
2102
  }
2033
2103
  }
2034
- const handleEnv = createResourceHandler({
2104
+ //#endregion
2105
+ //#region src/handlers/env.ts
2106
+ var handleEnv = createResourceHandler({
2035
2107
  resource: "env",
2036
2108
  actions: ["get", "update"],
2037
2109
  inputSchemas: {
@@ -2058,11 +2130,14 @@ const handleEnv = createResourceHandler({
2058
2130
  switch (action) {
2059
2131
  case "get": return formatEnv(data);
2060
2132
  case "update": return "Environment variables updated.";
2133
+ /* v8 ignore next */
2061
2134
  default: return "Done.";
2062
2135
  }
2063
2136
  }
2064
2137
  });
2065
- const handleFirewallRules = createResourceHandler({
2138
+ //#endregion
2139
+ //#region src/handlers/firewall-rules.ts
2140
+ var handleFirewallRules = createResourceHandler({
2066
2141
  resource: "firewall-rules",
2067
2142
  actions: [
2068
2143
  "list",
@@ -2099,10 +2174,13 @@ const handleFirewallRules = createResourceHandler({
2099
2174
  case "get": return formatFirewallRule(data);
2100
2175
  case "create": return "Done.";
2101
2176
  case "delete": return `Firewall rule ${args.id} deleted.`;
2177
+ /* v8 ignore next */
2102
2178
  default: return "Done.";
2103
2179
  }
2104
2180
  }
2105
2181
  });
2182
+ //#endregion
2183
+ //#region src/handlers/help.ts
2106
2184
  var RESOURCE_HELP = {
2107
2185
  servers: {
2108
2186
  description: "Manage Laravel Forge servers — provisioned cloud instances (DigitalOcean, AWS, Hetzner, etc.)",
@@ -2454,7 +2532,8 @@ var RESOURCE_HELP = {
2454
2532
  get: "Get daemon details",
2455
2533
  create: "Create a new daemon",
2456
2534
  delete: "Delete a daemon",
2457
- restart: "Restart a daemon"
2535
+ restart: "Restart a daemon",
2536
+ log: "Get the latest daemon log output"
2458
2537
  },
2459
2538
  fields: {
2460
2539
  command: "Shell command to run",
@@ -2489,6 +2568,58 @@ var RESOURCE_HELP = {
2489
2568
  server_id: "123",
2490
2569
  id: "456"
2491
2570
  }
2571
+ },
2572
+ {
2573
+ description: "Get daemon log output",
2574
+ params: {
2575
+ resource: "daemons",
2576
+ action: "log",
2577
+ server_id: "123",
2578
+ id: "456"
2579
+ }
2580
+ }
2581
+ ]
2582
+ },
2583
+ services: {
2584
+ description: "List and restart server services (nginx, php, mysql, postgres, redis, supervisor)",
2585
+ scope: "server (requires server_id)",
2586
+ actions: {
2587
+ list: "List services with a derived availability flag (heuristic — the API has no services GET endpoint)",
2588
+ restart: "Restart a service (maps to the API action reboot). The php service requires a version."
2589
+ },
2590
+ fields: {
2591
+ service: "One of: nginx, php, mysql, postgres, redis, supervisor",
2592
+ available: "Heuristic derived from the server object attributes",
2593
+ detail: "Extra info (php_version, database_type, redis_status) when relevant",
2594
+ version: "PHP version (e.g. php83) — required when restarting php"
2595
+ },
2596
+ examples: [
2597
+ {
2598
+ description: "List services",
2599
+ params: {
2600
+ resource: "services",
2601
+ action: "list",
2602
+ server_id: "123"
2603
+ }
2604
+ },
2605
+ {
2606
+ description: "Restart nginx",
2607
+ params: {
2608
+ resource: "services",
2609
+ action: "restart",
2610
+ server_id: "123",
2611
+ service: "nginx"
2612
+ }
2613
+ },
2614
+ {
2615
+ description: "Restart php (version required)",
2616
+ params: {
2617
+ resource: "services",
2618
+ action: "restart",
2619
+ server_id: "123",
2620
+ service: "php",
2621
+ version: "php83"
2622
+ }
2492
2623
  }
2493
2624
  ]
2494
2625
  },
@@ -2893,7 +3024,9 @@ function handleHelpOverview() {
2893
3024
  _tip: "Always call { action: 'help', resource: '<name>' } before your first interaction with any resource to learn required fields and examples."
2894
3025
  });
2895
3026
  }
2896
- const handleMonitors = createResourceHandler({
3027
+ //#endregion
3028
+ //#region src/handlers/monitors.ts
3029
+ var handleMonitors = createResourceHandler({
2897
3030
  resource: "monitors",
2898
3031
  actions: [
2899
3032
  "list",
@@ -2931,11 +3064,14 @@ const handleMonitors = createResourceHandler({
2931
3064
  case "get": return formatMonitor(data);
2932
3065
  case "create": return formatMonitor(data);
2933
3066
  case "delete": return `Monitor ${args.id} deleted.`;
3067
+ /* v8 ignore next */
2934
3068
  default: return "Done.";
2935
3069
  }
2936
3070
  }
2937
3071
  });
2938
- const handleNginxConfig = createResourceHandler({
3072
+ //#endregion
3073
+ //#region src/handlers/nginx-config.ts
3074
+ var handleNginxConfig = createResourceHandler({
2939
3075
  resource: "nginx",
2940
3076
  actions: ["get", "update"],
2941
3077
  inputSchemas: {
@@ -2962,11 +3098,14 @@ const handleNginxConfig = createResourceHandler({
2962
3098
  switch (action) {
2963
3099
  case "get": return formatNginxConfig(data);
2964
3100
  case "update": return "Nginx configuration updated.";
3101
+ /* v8 ignore next */
2965
3102
  default: return "Done.";
2966
3103
  }
2967
3104
  }
2968
3105
  });
2969
- const handleNginxTemplates = createResourceHandler({
3106
+ //#endregion
3107
+ //#region src/handlers/nginx-templates.ts
3108
+ var handleNginxTemplates = createResourceHandler({
2970
3109
  resource: "nginx-templates",
2971
3110
  actions: [
2972
3111
  "list",
@@ -3010,11 +3149,14 @@ const handleNginxTemplates = createResourceHandler({
3010
3149
  case "create": return formatNginxTemplate(data);
3011
3150
  case "update": return formatNginxTemplate(data);
3012
3151
  case "delete": return `Nginx template ${args.id} deleted.`;
3152
+ /* v8 ignore next */
3013
3153
  default: return "Done.";
3014
3154
  }
3015
3155
  }
3016
3156
  });
3017
- const handleRecipes = createResourceHandler({
3157
+ //#endregion
3158
+ //#region src/handlers/recipes.ts
3159
+ var handleRecipes = createResourceHandler({
3018
3160
  resource: "recipes",
3019
3161
  actions: [
3020
3162
  "list",
@@ -3063,11 +3205,14 @@ const handleRecipes = createResourceHandler({
3063
3205
  const count = Array.isArray(servers) ? servers.length : 1;
3064
3206
  return `Recipe ${args.id} run on ${count} server(s).`;
3065
3207
  }
3208
+ /* v8 ignore next */
3066
3209
  default: return "Done.";
3067
3210
  }
3068
3211
  }
3069
3212
  });
3070
- const handleRedirectRules = createResourceHandler({
3213
+ //#endregion
3214
+ //#region src/handlers/redirect-rules.ts
3215
+ var handleRedirectRules = createResourceHandler({
3071
3216
  resource: "redirect-rules",
3072
3217
  actions: [
3073
3218
  "list",
@@ -3109,11 +3254,14 @@ const handleRedirectRules = createResourceHandler({
3109
3254
  case "get": return formatRedirectRule(data);
3110
3255
  case "create": return "Done.";
3111
3256
  case "delete": return `Redirect rule ${args.id} deleted.`;
3257
+ /* v8 ignore next */
3112
3258
  default: return "Done.";
3113
3259
  }
3114
3260
  }
3115
3261
  });
3116
- const handleScheduledJobs = createResourceHandler({
3262
+ //#endregion
3263
+ //#region src/handlers/scheduled-jobs.ts
3264
+ var handleScheduledJobs = createResourceHandler({
3117
3265
  resource: "scheduled-jobs",
3118
3266
  actions: [
3119
3267
  "list",
@@ -3154,10 +3302,13 @@ const handleScheduledJobs = createResourceHandler({
3154
3302
  case "get": return formatScheduledJob(data);
3155
3303
  case "create": return formatScheduledJob(data);
3156
3304
  case "delete": return `Scheduled job ${args.id} deleted.`;
3305
+ /* v8 ignore next */
3157
3306
  default: return "Done.";
3158
3307
  }
3159
3308
  }
3160
3309
  });
3310
+ //#endregion
3311
+ //#region src/handlers/schema.ts
3161
3312
  var RESOURCE_SCHEMAS = {
3162
3313
  servers: {
3163
3314
  actions: [
@@ -3405,7 +3556,8 @@ var RESOURCE_SCHEMAS = {
3405
3556
  "get",
3406
3557
  "create",
3407
3558
  "delete",
3408
- "restart"
3559
+ "restart",
3560
+ "log"
3409
3561
  ],
3410
3562
  scope: "server",
3411
3563
  required: {
@@ -3413,7 +3565,8 @@ var RESOURCE_SCHEMAS = {
3413
3565
  get: ["server_id", "id"],
3414
3566
  create: ["server_id", "command"],
3415
3567
  delete: ["server_id", "id"],
3416
- restart: ["server_id", "id"]
3568
+ restart: ["server_id", "id"],
3569
+ log: ["server_id", "id"]
3417
3570
  },
3418
3571
  create: {
3419
3572
  command: {
@@ -3434,6 +3587,14 @@ var RESOURCE_SCHEMAS = {
3434
3587
  }
3435
3588
  }
3436
3589
  },
3590
+ services: {
3591
+ actions: ["list", "restart"],
3592
+ scope: "server",
3593
+ required: {
3594
+ list: ["server_id"],
3595
+ restart: ["server_id", "service"]
3596
+ }
3597
+ },
3437
3598
  "firewall-rules": {
3438
3599
  actions: [
3439
3600
  "list",
@@ -3851,7 +4012,9 @@ function handleSchemaOverview() {
3851
4012
  }))
3852
4013
  });
3853
4014
  }
3854
- const handleSecurityRules = createResourceHandler({
4015
+ //#endregion
4016
+ //#region src/handlers/security-rules.ts
4017
+ var handleSecurityRules = createResourceHandler({
3855
4018
  resource: "security-rules",
3856
4019
  actions: [
3857
4020
  "list",
@@ -3904,10 +4067,13 @@ const handleSecurityRules = createResourceHandler({
3904
4067
  case "create": return formatSecurityRule(data);
3905
4068
  case "update": return formatSecurityRule(data);
3906
4069
  case "delete": return `Security rule ${args.id} deleted.`;
4070
+ /* v8 ignore next */
3907
4071
  default: return "Done.";
3908
4072
  }
3909
4073
  }
3910
4074
  });
4075
+ //#endregion
4076
+ //#region src/handlers/context.ts
3911
4077
  /**
3912
4078
  * Handle server context action — fetches server details plus all sub-resources
3913
4079
  * (sites, databases, database users, daemons, firewall rules, scheduled jobs)
@@ -3973,6 +4139,8 @@ async function handleSiteContext(args, ctx) {
3973
4139
  security_rules: securityRules.data
3974
4140
  });
3975
4141
  }
4142
+ //#endregion
4143
+ //#region src/handlers/servers.ts
3976
4144
  var _handleServers = createResourceHandler({
3977
4145
  resource: "servers",
3978
4146
  actions: [
@@ -4011,9 +4179,12 @@ var _handleServers = createResourceHandler({
4011
4179
  case "reboot": return { server_id: args.id };
4012
4180
  case "create": return {
4013
4181
  provider: args.provider,
4182
+ /* v8 ignore next */
4014
4183
  credential_id: Number(args.credential_id) || 0,
4015
4184
  name: args.name,
4185
+ /* v8 ignore next */
4016
4186
  type: args.type ?? "app",
4187
+ /* v8 ignore next */
4017
4188
  size: args.size ?? "",
4018
4189
  region: args.region
4019
4190
  };
@@ -4034,6 +4205,7 @@ var _handleServers = createResourceHandler({
4034
4205
  const lines = result.matches.map((m) => `• ${m.name} (ID: ${m.id})`);
4035
4206
  return `${result.total} server(s) matching "${result.query}":\n${lines.join("\n")}`;
4036
4207
  }
4208
+ /* v8 ignore next */
4037
4209
  default: return "Done.";
4038
4210
  }
4039
4211
  }
@@ -4046,6 +4218,34 @@ async function handleServers(action, args, ctx) {
4046
4218
  if (action === "context") return handleServerContext(args, ctx);
4047
4219
  return _handleServers(action, args, ctx);
4048
4220
  }
4221
+ //#endregion
4222
+ //#region src/handlers/services.ts
4223
+ var handleServices = createResourceHandler({
4224
+ resource: "services",
4225
+ actions: ["list", "restart"],
4226
+ inputSchemas: {
4227
+ list: /* @__PURE__ */ object({ server_id: /* @__PURE__ */ string() }),
4228
+ restart: /* @__PURE__ */ object({
4229
+ server_id: /* @__PURE__ */ string(),
4230
+ service: /* @__PURE__ */ string(),
4231
+ version: /* @__PURE__ */ optional(/* @__PURE__ */ string())
4232
+ })
4233
+ },
4234
+ executors: {
4235
+ list: listServices,
4236
+ restart: restartService
4237
+ },
4238
+ formatResult: (action, data, args) => {
4239
+ switch (action) {
4240
+ case "list": return formatServiceList(data);
4241
+ case "restart": return `${String(args.service)} restart initiated on server ${String(args.server_id)}.`;
4242
+ /* v8 ignore next */
4243
+ default: return "Done.";
4244
+ }
4245
+ }
4246
+ });
4247
+ //#endregion
4248
+ //#region src/handlers/sites.ts
4049
4249
  var _handleSites = createResourceHandler({
4050
4250
  resource: "sites",
4051
4251
  actions: [
@@ -4119,6 +4319,7 @@ var _handleSites = createResourceHandler({
4119
4319
  server_id: args.server_id,
4120
4320
  query: args.query
4121
4321
  };
4322
+ /* v8 ignore next */
4122
4323
  default: return {};
4123
4324
  }
4124
4325
  },
@@ -4135,6 +4336,7 @@ var _handleSites = createResourceHandler({
4135
4336
  const lines = result.matches.map((m) => `• ${m.name} (ID: ${m.id})`);
4136
4337
  return `${result.total} site(s) matching "${result.query}" on server ${args.server_id}:\n${lines.join("\n")}`;
4137
4338
  }
4339
+ /* v8 ignore next */
4138
4340
  default: return "Done.";
4139
4341
  }
4140
4342
  }
@@ -4147,7 +4349,9 @@ async function handleSites(action, args, ctx) {
4147
4349
  if (action === "context") return handleSiteContext(args, ctx);
4148
4350
  return _handleSites(action, args, ctx);
4149
4351
  }
4150
- const handleSshKeys = createResourceHandler({
4352
+ //#endregion
4353
+ //#region src/handlers/ssh-keys.ts
4354
+ var handleSshKeys = createResourceHandler({
4151
4355
  resource: "ssh-keys",
4152
4356
  actions: [
4153
4357
  "list",
@@ -4184,11 +4388,14 @@ const handleSshKeys = createResourceHandler({
4184
4388
  case "get": return formatSshKey(data);
4185
4389
  case "create": return "Done.";
4186
4390
  case "delete": return `SSH key ${args.id} deleted.`;
4391
+ /* v8 ignore next */
4187
4392
  default: return "Done.";
4188
4393
  }
4189
4394
  }
4190
4395
  });
4191
- const handleUser = createResourceHandler({
4396
+ //#endregion
4397
+ //#region src/handlers/user.ts
4398
+ var handleUser = createResourceHandler({
4192
4399
  resource: "user",
4193
4400
  actions: ["get"],
4194
4401
  executors: { get: getUser },
@@ -4196,6 +4403,8 @@ const handleUser = createResourceHandler({
4196
4403
  return formatUser(data);
4197
4404
  }
4198
4405
  });
4406
+ //#endregion
4407
+ //#region src/handlers/auto-resolve.ts
4199
4408
  /**
4200
4409
  * Check if a value is a numeric ID.
4201
4410
  */
@@ -4258,6 +4467,8 @@ async function autoResolveIds(args, executorContext) {
4258
4467
  args: resolved
4259
4468
  };
4260
4469
  }
4470
+ //#endregion
4471
+ //#region src/handlers/index.ts
4261
4472
  /** Valid resources derived from core constants */
4262
4473
  var VALID_RESOURCES = [...RESOURCES];
4263
4474
  var _auditLogger = null;
@@ -4289,8 +4500,10 @@ function routeToHandler(resource, action, args, ctx) {
4289
4500
  case "backups": return handleBackups(action, args, ctx);
4290
4501
  case "commands": return handleCommands(action, args, ctx);
4291
4502
  case "scheduled-jobs": return handleScheduledJobs(action, args, ctx);
4503
+ case "services": return handleServices(action, args, ctx);
4292
4504
  case "user": return handleUser(action, args, ctx);
4293
4505
  case "batch": return handleBatch(action, args, ctx, routeToHandler);
4506
+ /* v8 ignore next 6 -- all valid resources are handled above; unreachable in practice */
4294
4507
  default: return Promise.resolve(errorResult(`Unknown resource "${resource}". Valid resources: ${VALID_RESOURCES.join(", ")}. Use action="help" for documentation.`));
4295
4508
  }
4296
4509
  }
@@ -4375,7 +4588,10 @@ async function executeToolWithCredentials(name, args, credentials) {
4375
4588
  return errorResult(errorMessage);
4376
4589
  }
4377
4590
  }
4378
- const VERSION = "0.4.4";
4591
+ //#endregion
4592
+ //#region src/version.ts
4593
+ var VERSION = "0.4.6";
4594
+ //#endregion
4379
4595
  export { INSTRUCTIONS as a, getTools as i, executeToolWithCredentials as n, STDIO_ONLY_TOOLS as r, VERSION as t };
4380
4596
 
4381
- //# sourceMappingURL=version-DNuuHvcD.js.map
4597
+ //# sourceMappingURL=version-BS77BDou.js.map