@robinmordasiewicz/f5xc-api-mcp 1.0.82-2512312028

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.
Files changed (329) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +415 -0
  3. package/dist/auth/credential-manager.d.ts +151 -0
  4. package/dist/auth/credential-manager.d.ts.map +1 -0
  5. package/dist/auth/credential-manager.js +330 -0
  6. package/dist/auth/credential-manager.js.map +1 -0
  7. package/dist/auth/http-client.d.ts +81 -0
  8. package/dist/auth/http-client.d.ts.map +1 -0
  9. package/dist/auth/http-client.js +197 -0
  10. package/dist/auth/http-client.js.map +1 -0
  11. package/dist/auth/index.d.ts +8 -0
  12. package/dist/auth/index.d.ts.map +1 -0
  13. package/dist/auth/index.js +6 -0
  14. package/dist/auth/index.js.map +1 -0
  15. package/dist/config/config-manager.d.ts +72 -0
  16. package/dist/config/config-manager.d.ts.map +1 -0
  17. package/dist/config/config-manager.js +247 -0
  18. package/dist/config/config-manager.js.map +1 -0
  19. package/dist/config/index.d.ts +7 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +7 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/schema.d.ts +74 -0
  24. package/dist/config/schema.d.ts.map +1 -0
  25. package/dist/config/schema.js +75 -0
  26. package/dist/config/schema.js.map +1 -0
  27. package/dist/config/types.d.ts +77 -0
  28. package/dist/config/types.d.ts.map +1 -0
  29. package/dist/config/types.js +31 -0
  30. package/dist/config/types.js.map +1 -0
  31. package/dist/generator/dependency-extractor.d.ts +103 -0
  32. package/dist/generator/dependency-extractor.d.ts.map +1 -0
  33. package/dist/generator/dependency-extractor.js +473 -0
  34. package/dist/generator/dependency-extractor.js.map +1 -0
  35. package/dist/generator/dependency-graph.d.ts +67 -0
  36. package/dist/generator/dependency-graph.d.ts.map +1 -0
  37. package/dist/generator/dependency-graph.js +330 -0
  38. package/dist/generator/dependency-graph.js.map +1 -0
  39. package/dist/generator/dependency-types.d.ts +206 -0
  40. package/dist/generator/dependency-types.d.ts.map +1 -0
  41. package/dist/generator/dependency-types.js +37 -0
  42. package/dist/generator/dependency-types.js.map +1 -0
  43. package/dist/generator/index.d.ts +7 -0
  44. package/dist/generator/index.d.ts.map +1 -0
  45. package/dist/generator/index.js +7 -0
  46. package/dist/generator/index.js.map +1 -0
  47. package/dist/generator/naming/acronyms.d.ts +81 -0
  48. package/dist/generator/naming/acronyms.d.ts.map +1 -0
  49. package/dist/generator/naming/acronyms.js +253 -0
  50. package/dist/generator/naming/acronyms.js.map +1 -0
  51. package/dist/generator/naming/index.d.ts +6 -0
  52. package/dist/generator/naming/index.d.ts.map +1 -0
  53. package/dist/generator/naming/index.js +6 -0
  54. package/dist/generator/naming/index.js.map +1 -0
  55. package/dist/generator/naming/volterra-mapping.d.ts +102 -0
  56. package/dist/generator/naming/volterra-mapping.d.ts.map +1 -0
  57. package/dist/generator/naming/volterra-mapping.js +259 -0
  58. package/dist/generator/naming/volterra-mapping.js.map +1 -0
  59. package/dist/generator/openapi-parser.d.ts +701 -0
  60. package/dist/generator/openapi-parser.d.ts.map +1 -0
  61. package/dist/generator/openapi-parser.js +704 -0
  62. package/dist/generator/openapi-parser.js.map +1 -0
  63. package/dist/generator/tool-generator.d.ts +118 -0
  64. package/dist/generator/tool-generator.d.ts.map +1 -0
  65. package/dist/generator/tool-generator.js +529 -0
  66. package/dist/generator/tool-generator.js.map +1 -0
  67. package/dist/generator/transformers/index.d.ts +7 -0
  68. package/dist/generator/transformers/index.d.ts.map +1 -0
  69. package/dist/generator/transformers/index.js +7 -0
  70. package/dist/generator/transformers/index.js.map +1 -0
  71. package/dist/generator/transformers/normalize-examples.d.ts +48 -0
  72. package/dist/generator/transformers/normalize-examples.d.ts.map +1 -0
  73. package/dist/generator/transformers/normalize-examples.js +66 -0
  74. package/dist/generator/transformers/normalize-examples.js.map +1 -0
  75. package/dist/index.d.ts +22 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +101 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/prompts/error-resolution.d.ts +70 -0
  80. package/dist/prompts/error-resolution.d.ts.map +1 -0
  81. package/dist/prompts/error-resolution.js +350 -0
  82. package/dist/prompts/error-resolution.js.map +1 -0
  83. package/dist/prompts/index.d.ts +8 -0
  84. package/dist/prompts/index.d.ts.map +1 -0
  85. package/dist/prompts/index.js +7 -0
  86. package/dist/prompts/index.js.map +1 -0
  87. package/dist/prompts/workflows.d.ts +59 -0
  88. package/dist/prompts/workflows.d.ts.map +1 -0
  89. package/dist/prompts/workflows.js +441 -0
  90. package/dist/prompts/workflows.js.map +1 -0
  91. package/dist/resources/handlers.d.ts +70 -0
  92. package/dist/resources/handlers.d.ts.map +1 -0
  93. package/dist/resources/handlers.js +270 -0
  94. package/dist/resources/handlers.js.map +1 -0
  95. package/dist/resources/index.d.ts +8 -0
  96. package/dist/resources/index.d.ts.map +1 -0
  97. package/dist/resources/index.js +6 -0
  98. package/dist/resources/index.js.map +1 -0
  99. package/dist/resources/templates.d.ts +86 -0
  100. package/dist/resources/templates.d.ts.map +1 -0
  101. package/dist/resources/templates.js +248 -0
  102. package/dist/resources/templates.js.map +1 -0
  103. package/dist/server.d.ts +78 -0
  104. package/dist/server.d.ts.map +1 -0
  105. package/dist/server.js +721 -0
  106. package/dist/server.js.map +1 -0
  107. package/dist/tools/discovery/best-practices.d.ts +140 -0
  108. package/dist/tools/discovery/best-practices.d.ts.map +1 -0
  109. package/dist/tools/discovery/best-practices.js +499 -0
  110. package/dist/tools/discovery/best-practices.js.map +1 -0
  111. package/dist/tools/discovery/consolidate.d.ts +97 -0
  112. package/dist/tools/discovery/consolidate.d.ts.map +1 -0
  113. package/dist/tools/discovery/consolidate.js +200 -0
  114. package/dist/tools/discovery/consolidate.js.map +1 -0
  115. package/dist/tools/discovery/cost-estimator.d.ts +114 -0
  116. package/dist/tools/discovery/cost-estimator.d.ts.map +1 -0
  117. package/dist/tools/discovery/cost-estimator.js +273 -0
  118. package/dist/tools/discovery/cost-estimator.js.map +1 -0
  119. package/dist/tools/discovery/dependencies.d.ts +113 -0
  120. package/dist/tools/discovery/dependencies.d.ts.map +1 -0
  121. package/dist/tools/discovery/dependencies.js +258 -0
  122. package/dist/tools/discovery/dependencies.js.map +1 -0
  123. package/dist/tools/discovery/describe.d.ts +133 -0
  124. package/dist/tools/discovery/describe.d.ts.map +1 -0
  125. package/dist/tools/discovery/describe.js +208 -0
  126. package/dist/tools/discovery/describe.js.map +1 -0
  127. package/dist/tools/discovery/execute.d.ts +96 -0
  128. package/dist/tools/discovery/execute.d.ts.map +1 -0
  129. package/dist/tools/discovery/execute.js +220 -0
  130. package/dist/tools/discovery/execute.js.map +1 -0
  131. package/dist/tools/discovery/index-loader.d.ts +28 -0
  132. package/dist/tools/discovery/index-loader.d.ts.map +1 -0
  133. package/dist/tools/discovery/index-loader.js +72 -0
  134. package/dist/tools/discovery/index-loader.js.map +1 -0
  135. package/dist/tools/discovery/index.d.ts +363 -0
  136. package/dist/tools/discovery/index.d.ts.map +1 -0
  137. package/dist/tools/discovery/index.js +361 -0
  138. package/dist/tools/discovery/index.js.map +1 -0
  139. package/dist/tools/discovery/resolver.d.ts +119 -0
  140. package/dist/tools/discovery/resolver.d.ts.map +1 -0
  141. package/dist/tools/discovery/resolver.js +369 -0
  142. package/dist/tools/discovery/resolver.js.map +1 -0
  143. package/dist/tools/discovery/search.d.ts +41 -0
  144. package/dist/tools/discovery/search.d.ts.map +1 -0
  145. package/dist/tools/discovery/search.js +176 -0
  146. package/dist/tools/discovery/search.js.map +1 -0
  147. package/dist/tools/discovery/types.d.ts +91 -0
  148. package/dist/tools/discovery/types.d.ts.map +1 -0
  149. package/dist/tools/discovery/types.js +9 -0
  150. package/dist/tools/discovery/types.js.map +1 -0
  151. package/dist/tools/discovery/validate.d.ts +63 -0
  152. package/dist/tools/discovery/validate.d.ts.map +1 -0
  153. package/dist/tools/discovery/validate.js +239 -0
  154. package/dist/tools/discovery/validate.js.map +1 -0
  155. package/dist/tools/generated/admin_console_and_ui/index.d.ts +8 -0
  156. package/dist/tools/generated/admin_console_and_ui/index.d.ts.map +1 -0
  157. package/dist/tools/generated/admin_console_and_ui/index.js +265 -0
  158. package/dist/tools/generated/admin_console_and_ui/index.js.map +1 -0
  159. package/dist/tools/generated/api/index.d.ts +8 -0
  160. package/dist/tools/generated/api/index.d.ts.map +1 -0
  161. package/dist/tools/generated/api/index.js +7016 -0
  162. package/dist/tools/generated/api/index.js.map +1 -0
  163. package/dist/tools/generated/authentication/index.d.ts +8 -0
  164. package/dist/tools/generated/authentication/index.d.ts.map +1 -0
  165. package/dist/tools/generated/authentication/index.js +907 -0
  166. package/dist/tools/generated/authentication/index.js.map +1 -0
  167. package/dist/tools/generated/bigip/index.d.ts +8 -0
  168. package/dist/tools/generated/bigip/index.d.ts.map +1 -0
  169. package/dist/tools/generated/bigip/index.js +3152 -0
  170. package/dist/tools/generated/bigip/index.js.map +1 -0
  171. package/dist/tools/generated/billing_and_usage/index.d.ts +8 -0
  172. package/dist/tools/generated/billing_and_usage/index.d.ts.map +1 -0
  173. package/dist/tools/generated/billing_and_usage/index.js +2452 -0
  174. package/dist/tools/generated/billing_and_usage/index.js.map +1 -0
  175. package/dist/tools/generated/blindfold/index.d.ts +8 -0
  176. package/dist/tools/generated/blindfold/index.d.ts.map +1 -0
  177. package/dist/tools/generated/blindfold/index.js +3790 -0
  178. package/dist/tools/generated/blindfold/index.js.map +1 -0
  179. package/dist/tools/generated/bot_and_threat_defense/index.d.ts +8 -0
  180. package/dist/tools/generated/bot_and_threat_defense/index.d.ts.map +1 -0
  181. package/dist/tools/generated/bot_and_threat_defense/index.js +2746 -0
  182. package/dist/tools/generated/bot_and_threat_defense/index.js.map +1 -0
  183. package/dist/tools/generated/cdn/index.d.ts +8 -0
  184. package/dist/tools/generated/cdn/index.d.ts.map +1 -0
  185. package/dist/tools/generated/cdn/index.js +2686 -0
  186. package/dist/tools/generated/cdn/index.js.map +1 -0
  187. package/dist/tools/generated/ce_management/index.d.ts +8 -0
  188. package/dist/tools/generated/ce_management/index.d.ts.map +1 -0
  189. package/dist/tools/generated/ce_management/index.js +3812 -0
  190. package/dist/tools/generated/ce_management/index.js.map +1 -0
  191. package/dist/tools/generated/certificates/index.d.ts +8 -0
  192. package/dist/tools/generated/certificates/index.d.ts.map +1 -0
  193. package/dist/tools/generated/certificates/index.js +2547 -0
  194. package/dist/tools/generated/certificates/index.js.map +1 -0
  195. package/dist/tools/generated/cloud_infrastructure/index.d.ts +8 -0
  196. package/dist/tools/generated/cloud_infrastructure/index.d.ts.map +1 -0
  197. package/dist/tools/generated/cloud_infrastructure/index.js +3959 -0
  198. package/dist/tools/generated/cloud_infrastructure/index.js.map +1 -0
  199. package/dist/tools/generated/container_services/index.d.ts +8 -0
  200. package/dist/tools/generated/container_services/index.d.ts.map +1 -0
  201. package/dist/tools/generated/container_services/index.js +2018 -0
  202. package/dist/tools/generated/container_services/index.js.map +1 -0
  203. package/dist/tools/generated/data_and_privacy_security/index.d.ts +8 -0
  204. package/dist/tools/generated/data_and_privacy_security/index.d.ts.map +1 -0
  205. package/dist/tools/generated/data_and_privacy_security/index.js +1662 -0
  206. package/dist/tools/generated/data_and_privacy_security/index.js.map +1 -0
  207. package/dist/tools/generated/data_intelligence/index.d.ts +8 -0
  208. package/dist/tools/generated/data_intelligence/index.d.ts.map +1 -0
  209. package/dist/tools/generated/data_intelligence/index.js +1600 -0
  210. package/dist/tools/generated/data_intelligence/index.js.map +1 -0
  211. package/dist/tools/generated/ddos/index.d.ts +8 -0
  212. package/dist/tools/generated/ddos/index.d.ts.map +1 -0
  213. package/dist/tools/generated/ddos/index.js +8091 -0
  214. package/dist/tools/generated/ddos/index.js.map +1 -0
  215. package/dist/tools/generated/dependency-graph.json +26358 -0
  216. package/dist/tools/generated/dns/index.d.ts +8 -0
  217. package/dist/tools/generated/dns/index.d.ts.map +1 -0
  218. package/dist/tools/generated/dns/index.js +6096 -0
  219. package/dist/tools/generated/dns/index.js.map +1 -0
  220. package/dist/tools/generated/generative_ai/index.d.ts +8 -0
  221. package/dist/tools/generated/generative_ai/index.d.ts.map +1 -0
  222. package/dist/tools/generated/generative_ai/index.js +1019 -0
  223. package/dist/tools/generated/generative_ai/index.js.map +1 -0
  224. package/dist/tools/generated/managed_kubernetes/index.d.ts +8 -0
  225. package/dist/tools/generated/managed_kubernetes/index.d.ts.map +1 -0
  226. package/dist/tools/generated/managed_kubernetes/index.js +3368 -0
  227. package/dist/tools/generated/managed_kubernetes/index.js.map +1 -0
  228. package/dist/tools/generated/marketplace/index.d.ts +8 -0
  229. package/dist/tools/generated/marketplace/index.d.ts.map +1 -0
  230. package/dist/tools/generated/marketplace/index.js +4329 -0
  231. package/dist/tools/generated/marketplace/index.js.map +1 -0
  232. package/dist/tools/generated/network/index.d.ts +8 -0
  233. package/dist/tools/generated/network/index.d.ts.map +1 -0
  234. package/dist/tools/generated/network/index.js +12424 -0
  235. package/dist/tools/generated/network/index.js.map +1 -0
  236. package/dist/tools/generated/network_security/index.d.ts +8 -0
  237. package/dist/tools/generated/network_security/index.d.ts.map +1 -0
  238. package/dist/tools/generated/network_security/index.js +9637 -0
  239. package/dist/tools/generated/network_security/index.js.map +1 -0
  240. package/dist/tools/generated/nginx_one/index.d.ts +8 -0
  241. package/dist/tools/generated/nginx_one/index.d.ts.map +1 -0
  242. package/dist/tools/generated/nginx_one/index.js +1692 -0
  243. package/dist/tools/generated/nginx_one/index.js.map +1 -0
  244. package/dist/tools/generated/object_storage/index.d.ts +8 -0
  245. package/dist/tools/generated/object_storage/index.d.ts.map +1 -0
  246. package/dist/tools/generated/object_storage/index.js +996 -0
  247. package/dist/tools/generated/object_storage/index.js.map +1 -0
  248. package/dist/tools/generated/observability/index.d.ts +8 -0
  249. package/dist/tools/generated/observability/index.d.ts.map +1 -0
  250. package/dist/tools/generated/observability/index.js +5285 -0
  251. package/dist/tools/generated/observability/index.js.map +1 -0
  252. package/dist/tools/generated/rate_limiting/index.d.ts +8 -0
  253. package/dist/tools/generated/rate_limiting/index.d.ts.map +1 -0
  254. package/dist/tools/generated/rate_limiting/index.js +2108 -0
  255. package/dist/tools/generated/rate_limiting/index.js.map +1 -0
  256. package/dist/tools/generated/secops_and_incident_response/index.d.ts +8 -0
  257. package/dist/tools/generated/secops_and_incident_response/index.d.ts.map +1 -0
  258. package/dist/tools/generated/secops_and_incident_response/index.js +710 -0
  259. package/dist/tools/generated/secops_and_incident_response/index.js.map +1 -0
  260. package/dist/tools/generated/service_mesh/index.d.ts +8 -0
  261. package/dist/tools/generated/service_mesh/index.d.ts.map +1 -0
  262. package/dist/tools/generated/service_mesh/index.js +6062 -0
  263. package/dist/tools/generated/service_mesh/index.js.map +1 -0
  264. package/dist/tools/generated/shape/index.d.ts +8 -0
  265. package/dist/tools/generated/shape/index.d.ts.map +1 -0
  266. package/dist/tools/generated/shape/index.js +19381 -0
  267. package/dist/tools/generated/shape/index.js.map +1 -0
  268. package/dist/tools/generated/sites/index.d.ts +8 -0
  269. package/dist/tools/generated/sites/index.d.ts.map +1 -0
  270. package/dist/tools/generated/sites/index.js +13160 -0
  271. package/dist/tools/generated/sites/index.js.map +1 -0
  272. package/dist/tools/generated/statistics/index.d.ts +8 -0
  273. package/dist/tools/generated/statistics/index.d.ts.map +1 -0
  274. package/dist/tools/generated/statistics/index.js +8131 -0
  275. package/dist/tools/generated/statistics/index.js.map +1 -0
  276. package/dist/tools/generated/support/index.d.ts +8 -0
  277. package/dist/tools/generated/support/index.d.ts.map +1 -0
  278. package/dist/tools/generated/support/index.js +5608 -0
  279. package/dist/tools/generated/support/index.js.map +1 -0
  280. package/dist/tools/generated/telemetry_and_insights/index.d.ts +8 -0
  281. package/dist/tools/generated/telemetry_and_insights/index.d.ts.map +1 -0
  282. package/dist/tools/generated/telemetry_and_insights/index.js +2404 -0
  283. package/dist/tools/generated/telemetry_and_insights/index.js.map +1 -0
  284. package/dist/tools/generated/tenant_and_identity/index.d.ts +8 -0
  285. package/dist/tools/generated/tenant_and_identity/index.d.ts.map +1 -0
  286. package/dist/tools/generated/tenant_and_identity/index.js +18938 -0
  287. package/dist/tools/generated/tenant_and_identity/index.js.map +1 -0
  288. package/dist/tools/generated/threat_campaign/index.d.ts +8 -0
  289. package/dist/tools/generated/threat_campaign/index.d.ts.map +1 -0
  290. package/dist/tools/generated/threat_campaign/index.js +102 -0
  291. package/dist/tools/generated/threat_campaign/index.js.map +1 -0
  292. package/dist/tools/generated/users/index.d.ts +8 -0
  293. package/dist/tools/generated/users/index.d.ts.map +1 -0
  294. package/dist/tools/generated/users/index.js +1515 -0
  295. package/dist/tools/generated/users/index.js.map +1 -0
  296. package/dist/tools/generated/virtual/index.d.ts +8 -0
  297. package/dist/tools/generated/virtual/index.d.ts.map +1 -0
  298. package/dist/tools/generated/virtual/index.js +11263 -0
  299. package/dist/tools/generated/virtual/index.js.map +1 -0
  300. package/dist/tools/generated/vpm_and_node_management/index.d.ts +8 -0
  301. package/dist/tools/generated/vpm_and_node_management/index.d.ts.map +1 -0
  302. package/dist/tools/generated/vpm_and_node_management/index.js +88 -0
  303. package/dist/tools/generated/vpm_and_node_management/index.js.map +1 -0
  304. package/dist/tools/generated/waf/index.d.ts +8 -0
  305. package/dist/tools/generated/waf/index.d.ts.map +1 -0
  306. package/dist/tools/generated/waf/index.js +4586 -0
  307. package/dist/tools/generated/waf/index.js.map +1 -0
  308. package/dist/tools/index.d.ts +7 -0
  309. package/dist/tools/index.d.ts.map +1 -0
  310. package/dist/tools/index.js +6 -0
  311. package/dist/tools/index.js.map +1 -0
  312. package/dist/tools/registry.d.ts +27 -0
  313. package/dist/tools/registry.d.ts.map +1 -0
  314. package/dist/tools/registry.js +115 -0
  315. package/dist/tools/registry.js.map +1 -0
  316. package/dist/utils/error-handling.d.ts +109 -0
  317. package/dist/utils/error-handling.d.ts.map +1 -0
  318. package/dist/utils/error-handling.js +239 -0
  319. package/dist/utils/error-handling.js.map +1 -0
  320. package/dist/utils/index.d.ts +7 -0
  321. package/dist/utils/index.d.ts.map +1 -0
  322. package/dist/utils/index.js +6 -0
  323. package/dist/utils/index.js.map +1 -0
  324. package/dist/utils/logging.d.ts +75 -0
  325. package/dist/utils/logging.d.ts.map +1 -0
  326. package/dist/utils/logging.js +131 -0
  327. package/dist/utils/logging.js.map +1 -0
  328. package/manifest.json +143 -0
  329. package/package.json +110 -0
package/dist/server.js ADDED
@@ -0,0 +1,721 @@
1
+ /**
2
+ * F5 Distributed Cloud API MCP Server
3
+ *
4
+ * This module initializes and configures the MCP server with STDIO transport.
5
+ * Supports dual-mode operation: documentation mode (unauthenticated) and
6
+ * execution mode (authenticated with F5XC credentials).
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
10
+ import { z } from "zod";
11
+ import { CredentialManager, AuthMode } from "./auth/credential-manager.js";
12
+ import { createHttpClient } from "./auth/http-client.js";
13
+ import { logger } from "./utils/logging.js";
14
+ import { VERSION } from "./index.js";
15
+ import { WORKFLOW_PROMPTS, processPromptTemplate, ERROR_PROMPTS, processErrorTemplate, } from "./prompts/index.js";
16
+ import { RESOURCE_TYPES, createResourceHandler } from "./resources/index.js";
17
+ import { DISCOVERY_TOOLS, searchTools, describeTool, executeTool, getIndexMetadata, getAvailableDomains, searchConsolidatedResources, resolveConsolidatedTool, getConsolidatedResource, getConsolidationStats, generateDependencyReport, getDependencyStats, validateToolParams, formatValidationResult, resolveDependencies, formatCreationPlan, estimateToolCost, estimateMultipleToolsCost, estimateWorkflowCost, formatCostEstimate, formatWorkflowCostEstimate, queryBestPractices, getAllDomainsSummary, formatBestPractices, } from "./tools/discovery/index.js";
18
+ /**
19
+ * F5XC API MCP Server
20
+ *
21
+ * Provides tools, resources, and prompts for interacting with F5 Distributed Cloud APIs.
22
+ * Works in two modes:
23
+ * - Documentation mode: Returns API documentation, schemas, and Terraform examples
24
+ * - Execution mode: Directly executes API calls when authenticated
25
+ */
26
+ export class F5XCApiServer {
27
+ server;
28
+ credentialManager;
29
+ httpClient = null;
30
+ resourceHandler;
31
+ transport = null;
32
+ constructor(config) {
33
+ this.credentialManager = config.credentialManager;
34
+ // Create HTTP client if authenticated
35
+ if (this.credentialManager.getAuthMode() !== AuthMode.NONE) {
36
+ this.httpClient = createHttpClient(this.credentialManager);
37
+ }
38
+ // Create resource handler
39
+ this.resourceHandler = createResourceHandler(this.credentialManager, this.httpClient);
40
+ this.server = new McpServer({
41
+ name: config.name,
42
+ version: config.version,
43
+ });
44
+ this.registerCapabilities();
45
+ }
46
+ /**
47
+ * Register all MCP capabilities (tools, resources, prompts)
48
+ */
49
+ registerCapabilities() {
50
+ this.registerTools();
51
+ this.registerResources();
52
+ this.registerPrompts();
53
+ }
54
+ /**
55
+ * Register MCP tools for F5XC API operations
56
+ *
57
+ * Uses the dynamic discovery pattern for token efficiency:
58
+ * - 3 meta-tools instead of 1,400+ individual tools
59
+ * - Reduces upfront token consumption from ~535K to ~500 tokens
60
+ * - Full tool schemas loaded on-demand via describe_tool
61
+ */
62
+ registerTools() {
63
+ const authMode = this.credentialManager.getAuthMode();
64
+ // Server info tool - provides server metadata and tool statistics
65
+ this.server.tool(DISCOVERY_TOOLS.serverInfo.name, DISCOVERY_TOOLS.serverInfo.description, {}, async () => {
66
+ const isAuthenticated = authMode !== AuthMode.NONE;
67
+ const tenantUrl = this.credentialManager.getApiUrl();
68
+ const indexMetadata = getIndexMetadata();
69
+ const domains = getAvailableDomains();
70
+ return {
71
+ content: [
72
+ {
73
+ type: "text",
74
+ text: JSON.stringify({
75
+ server: "f5xc-api-mcp",
76
+ version: VERSION,
77
+ mode: isAuthenticated ? "execution" : "documentation",
78
+ authenticated: isAuthenticated,
79
+ authMethod: authMode,
80
+ tenantUrl: isAuthenticated ? tenantUrl : null,
81
+ capabilities: {
82
+ documentation: true,
83
+ terraform_examples: true,
84
+ api_execution: isAuthenticated,
85
+ },
86
+ toolIndex: {
87
+ totalTools: indexMetadata.totalTools,
88
+ domains: indexMetadata.domains,
89
+ availableDomains: domains,
90
+ },
91
+ consolidation: getConsolidationStats(),
92
+ discoveryTools: [
93
+ "f5xc-api-search-tools",
94
+ "f5xc-api-describe-tool",
95
+ "f5xc-api-execute-tool",
96
+ "f5xc-api-search-resources",
97
+ "f5xc-api-execute-resource",
98
+ "f5xc-api-dependencies",
99
+ "f5xc-api-dependency-stats",
100
+ "f5xc-api-validate-params",
101
+ "f5xc-api-resolve-dependencies",
102
+ "f5xc-api-estimate-cost",
103
+ "f5xc-api-best-practices",
104
+ ],
105
+ message: isAuthenticated
106
+ ? "Authenticated - API execution enabled. Use f5xc-api-search-tools to find available API tools."
107
+ : "Documentation mode. Set F5XC_API_URL and F5XC_API_TOKEN to enable API execution.",
108
+ }, null, 2),
109
+ },
110
+ ],
111
+ };
112
+ });
113
+ // Search tools - find tools matching natural language queries
114
+ this.server.tool(DISCOVERY_TOOLS.search.name, DISCOVERY_TOOLS.search.description, {
115
+ query: z.string().describe("Natural language search query"),
116
+ limit: z.number().optional().describe("Maximum results (default: 10)"),
117
+ domains: z.array(z.string()).optional().describe("Filter by domains"),
118
+ operations: z.array(z.string()).optional().describe("Filter by operations"),
119
+ excludeDangerous: z.boolean().optional().describe("Exclude high-danger operations"),
120
+ excludeDeprecated: z.boolean().optional().describe("Exclude deprecated operations"),
121
+ includeDependencies: z
122
+ .boolean()
123
+ .optional()
124
+ .describe("Include prerequisite hints for create operations"),
125
+ }, async (args) => {
126
+ const results = searchTools(args.query, {
127
+ limit: Math.min(args.limit ?? 10, 50),
128
+ domains: args.domains,
129
+ operations: args.operations,
130
+ excludeDangerous: args.excludeDangerous,
131
+ excludeDeprecated: args.excludeDeprecated,
132
+ includeDependencies: args.includeDependencies,
133
+ });
134
+ return {
135
+ content: [
136
+ {
137
+ type: "text",
138
+ text: JSON.stringify({
139
+ query: args.query,
140
+ resultCount: results.length,
141
+ results: results.map((r) => ({
142
+ name: r.tool.name,
143
+ domain: r.tool.domain,
144
+ resource: r.tool.resource,
145
+ operation: r.tool.operation,
146
+ summary: r.tool.summary,
147
+ score: Math.round(r.score * 100) / 100,
148
+ // Phase A enhancement fields
149
+ dangerLevel: r.tool.dangerLevel,
150
+ isDeprecated: r.tool.isDeprecated,
151
+ // Phase B enhancement: prerequisites for create operations
152
+ ...(r.prerequisites && { prerequisites: r.prerequisites }),
153
+ })),
154
+ hint: "Use f5xc-api-describe-tool to get full schema for a specific tool.",
155
+ }, null, 2),
156
+ },
157
+ ],
158
+ };
159
+ });
160
+ // Describe tool - get full schema for a specific tool
161
+ this.server.tool(DISCOVERY_TOOLS.describe.name, DISCOVERY_TOOLS.describe.description, {
162
+ toolName: z.string().describe("Exact tool name to describe"),
163
+ }, async (args) => {
164
+ const description = describeTool(args.toolName);
165
+ if (!description) {
166
+ return {
167
+ content: [
168
+ {
169
+ type: "text",
170
+ text: JSON.stringify({
171
+ error: `Tool "${args.toolName}" not found`,
172
+ hint: "Use f5xc-api-search-tools to find available tools.",
173
+ }, null, 2),
174
+ },
175
+ ],
176
+ };
177
+ }
178
+ return {
179
+ content: [
180
+ {
181
+ type: "text",
182
+ text: JSON.stringify({
183
+ tool: description,
184
+ hint: "Use f5xc-api-execute-tool to execute this tool.",
185
+ }, null, 2),
186
+ },
187
+ ],
188
+ };
189
+ });
190
+ // Execute tool - execute a specific tool with parameters
191
+ this.server.tool(DISCOVERY_TOOLS.execute.name, DISCOVERY_TOOLS.execute.description, {
192
+ toolName: z.string().describe("Tool name to execute"),
193
+ pathParams: z.record(z.string(), z.string()).optional().describe("Path parameters"),
194
+ queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters"),
195
+ body: z.record(z.string(), z.unknown()).optional().describe("Request body"),
196
+ }, async (args) => {
197
+ const result = await executeTool({
198
+ toolName: args.toolName,
199
+ pathParams: args.pathParams,
200
+ queryParams: args.queryParams,
201
+ body: args.body,
202
+ }, this.credentialManager);
203
+ return {
204
+ content: [
205
+ {
206
+ type: "text",
207
+ text: JSON.stringify(result, null, 2),
208
+ },
209
+ ],
210
+ };
211
+ });
212
+ // Search resources - consolidated resource search
213
+ this.server.tool(DISCOVERY_TOOLS.searchResources.name, DISCOVERY_TOOLS.searchResources.description, {
214
+ query: z.string().describe("Natural language search query"),
215
+ limit: z.number().optional().describe("Maximum results (default: 10)"),
216
+ domains: z.array(z.string()).optional().describe("Filter by domains"),
217
+ }, async (args) => {
218
+ const results = searchConsolidatedResources(args.query, {
219
+ limit: Math.min(args.limit ?? 10, 50),
220
+ domains: args.domains,
221
+ });
222
+ return {
223
+ content: [
224
+ {
225
+ type: "text",
226
+ text: JSON.stringify({
227
+ query: args.query,
228
+ resultCount: results.length,
229
+ results: results.map((r) => ({
230
+ name: r.resource.name,
231
+ domain: r.resource.domain,
232
+ resource: r.resource.resource,
233
+ operations: r.resource.operations,
234
+ summary: r.resource.summary,
235
+ isFullCrud: r.resource.isFullCrud,
236
+ score: Math.round(r.score * 100) / 100,
237
+ })),
238
+ hint: "Use f5xc-api-execute-resource with resourceName and operation to execute.",
239
+ }, null, 2),
240
+ },
241
+ ],
242
+ };
243
+ });
244
+ // Execute resource - execute a CRUD operation on a consolidated resource
245
+ this.server.tool(DISCOVERY_TOOLS.executeResource.name, DISCOVERY_TOOLS.executeResource.description, {
246
+ resourceName: z.string().describe("Consolidated resource name"),
247
+ operation: z.enum(["create", "get", "list", "update", "delete"]).describe("CRUD operation"),
248
+ pathParams: z.record(z.string(), z.string()).optional().describe("Path parameters"),
249
+ queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters"),
250
+ body: z.record(z.string(), z.unknown()).optional().describe("Request body"),
251
+ }, async (args) => {
252
+ // Resolve to underlying tool
253
+ const toolName = resolveConsolidatedTool(args.resourceName, args.operation);
254
+ if (!toolName) {
255
+ const resource = getConsolidatedResource(args.resourceName);
256
+ if (!resource) {
257
+ return {
258
+ content: [
259
+ {
260
+ type: "text",
261
+ text: JSON.stringify({
262
+ error: `Resource "${args.resourceName}" not found`,
263
+ hint: "Use f5xc-api-search-resources to find available resources.",
264
+ }, null, 2),
265
+ },
266
+ ],
267
+ };
268
+ }
269
+ return {
270
+ content: [
271
+ {
272
+ type: "text",
273
+ text: JSON.stringify({
274
+ error: `Operation "${args.operation}" not available for "${args.resourceName}"`,
275
+ availableOperations: resource.operations,
276
+ }, null, 2),
277
+ },
278
+ ],
279
+ };
280
+ }
281
+ // Execute the resolved tool
282
+ const result = await executeTool({
283
+ toolName,
284
+ pathParams: args.pathParams,
285
+ queryParams: args.queryParams,
286
+ body: args.body,
287
+ }, this.credentialManager);
288
+ return {
289
+ content: [
290
+ {
291
+ type: "text",
292
+ text: JSON.stringify({
293
+ resolvedTool: toolName,
294
+ ...result,
295
+ }, null, 2),
296
+ },
297
+ ],
298
+ };
299
+ });
300
+ // Dependencies tool - get resource dependency information
301
+ this.server.tool(DISCOVERY_TOOLS.dependencies.name, DISCOVERY_TOOLS.dependencies.description, {
302
+ resource: z.string().describe("Resource name (e.g., 'http-loadbalancer')"),
303
+ domain: z.string().describe("Domain containing the resource (e.g., 'virtual')"),
304
+ action: z
305
+ .enum(["prerequisites", "dependents", "oneOf", "subscriptions", "creationOrder", "full"])
306
+ .optional()
307
+ .describe("Type of dependency information to retrieve (default: 'full')"),
308
+ }, async (args) => {
309
+ const action = (args.action ?? "full");
310
+ const report = generateDependencyReport(args.domain, args.resource, action);
311
+ return {
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify(report, null, 2),
316
+ },
317
+ ],
318
+ };
319
+ });
320
+ // Dependency stats tool - get graph statistics
321
+ this.server.tool(DISCOVERY_TOOLS.dependencyStats.name, DISCOVERY_TOOLS.dependencyStats.description, {}, async () => {
322
+ const stats = getDependencyStats();
323
+ return {
324
+ content: [
325
+ {
326
+ type: "text",
327
+ text: JSON.stringify(stats, null, 2),
328
+ },
329
+ ],
330
+ };
331
+ });
332
+ // Phase B: Parameter validation tool
333
+ this.server.tool(DISCOVERY_TOOLS.validateParams.name, DISCOVERY_TOOLS.validateParams.description, {
334
+ toolName: z.string().describe("Tool name to validate parameters for"),
335
+ pathParams: z
336
+ .record(z.string(), z.string())
337
+ .optional()
338
+ .describe("Path parameters to validate"),
339
+ queryParams: z
340
+ .record(z.string(), z.string())
341
+ .optional()
342
+ .describe("Query parameters to validate"),
343
+ body: z.record(z.string(), z.unknown()).optional().describe("Request body to validate"),
344
+ }, async (args) => {
345
+ const result = validateToolParams({
346
+ toolName: args.toolName,
347
+ pathParams: args.pathParams,
348
+ queryParams: args.queryParams,
349
+ body: args.body,
350
+ });
351
+ return {
352
+ content: [
353
+ {
354
+ type: "text",
355
+ text: JSON.stringify({
356
+ ...result,
357
+ formatted: formatValidationResult(result),
358
+ }, null, 2),
359
+ },
360
+ ],
361
+ };
362
+ });
363
+ // Phase C: Dependency resolver tool
364
+ this.server.tool(DISCOVERY_TOOLS.resolveDependencies.name, DISCOVERY_TOOLS.resolveDependencies.description, {
365
+ resource: z.string().describe("Target resource to create"),
366
+ domain: z.string().describe("Domain containing the resource"),
367
+ existingResources: z
368
+ .array(z.string())
369
+ .optional()
370
+ .describe("Resources that already exist (will be skipped)"),
371
+ includeOptional: z
372
+ .boolean()
373
+ .optional()
374
+ .default(false)
375
+ .describe("Include optional dependencies"),
376
+ maxDepth: z.number().optional().default(10).describe("Maximum dependency traversal depth"),
377
+ expandAlternatives: z
378
+ .boolean()
379
+ .optional()
380
+ .default(false)
381
+ .describe("Include alternative paths for oneOf choices"),
382
+ }, async (args) => {
383
+ const result = resolveDependencies({
384
+ resource: args.resource,
385
+ domain: args.domain,
386
+ existingResources: args.existingResources,
387
+ includeOptional: args.includeOptional,
388
+ maxDepth: args.maxDepth,
389
+ expandAlternatives: args.expandAlternatives,
390
+ });
391
+ if (!result.success || !result.plan) {
392
+ return {
393
+ content: [
394
+ {
395
+ type: "text",
396
+ text: JSON.stringify({ success: false, error: result.error }, null, 2),
397
+ },
398
+ ],
399
+ };
400
+ }
401
+ return {
402
+ content: [
403
+ {
404
+ type: "text",
405
+ text: JSON.stringify({
406
+ success: true,
407
+ plan: result.plan,
408
+ formatted: formatCreationPlan(result.plan),
409
+ }, null, 2),
410
+ },
411
+ ],
412
+ };
413
+ });
414
+ // Phase C: Cost estimation tool
415
+ this.server.tool(DISCOVERY_TOOLS.estimateCost.name, DISCOVERY_TOOLS.estimateCost.description, {
416
+ toolName: z.string().optional().describe("Single tool name to estimate"),
417
+ toolNames: z.array(z.string()).optional().describe("Multiple tool names to estimate"),
418
+ plan: z.record(z.string(), z.unknown()).optional().describe("CreationPlan to estimate"),
419
+ detailed: z.boolean().optional().default(true).describe("Include detailed breakdown"),
420
+ }, async (args) => {
421
+ // Single tool estimation
422
+ if (args.toolName) {
423
+ const estimate = estimateToolCost(args.toolName);
424
+ return {
425
+ content: [
426
+ {
427
+ type: "text",
428
+ text: JSON.stringify({
429
+ type: "single_tool",
430
+ estimate,
431
+ formatted: args.detailed ? formatCostEstimate(estimate) : undefined,
432
+ }, null, 2),
433
+ },
434
+ ],
435
+ };
436
+ }
437
+ // Multiple tools estimation
438
+ if (args.toolNames && args.toolNames.length > 0) {
439
+ const estimates = estimateMultipleToolsCost(args.toolNames);
440
+ const totalTokens = estimates.reduce((sum, e) => sum + e.tokens.totalTokens, 0);
441
+ return {
442
+ content: [
443
+ {
444
+ type: "text",
445
+ text: JSON.stringify({
446
+ type: "multiple_tools",
447
+ toolCount: estimates.length,
448
+ totalTokens,
449
+ estimates,
450
+ formatted: args.detailed
451
+ ? estimates.map((e) => formatCostEstimate(e)).join("\n\n---\n\n")
452
+ : undefined,
453
+ }, null, 2),
454
+ },
455
+ ],
456
+ };
457
+ }
458
+ // Workflow/plan estimation
459
+ if (args.plan) {
460
+ const estimate = estimateWorkflowCost(args.plan);
461
+ return {
462
+ content: [
463
+ {
464
+ type: "text",
465
+ text: JSON.stringify({
466
+ type: "workflow",
467
+ estimate,
468
+ formatted: args.detailed ? formatWorkflowCostEstimate(estimate) : undefined,
469
+ }, null, 2),
470
+ },
471
+ ],
472
+ };
473
+ }
474
+ // No valid input provided
475
+ return {
476
+ content: [
477
+ {
478
+ type: "text",
479
+ text: JSON.stringify({
480
+ error: "No valid input provided",
481
+ hint: "Provide either 'toolName', 'toolNames', or 'plan' parameter",
482
+ }, null, 2),
483
+ },
484
+ ],
485
+ };
486
+ });
487
+ // Phase C: Best practices tool
488
+ this.server.tool(DISCOVERY_TOOLS.bestPractices.name, DISCOVERY_TOOLS.bestPractices.description, {
489
+ domain: z.string().optional().describe("Domain to get best practices for"),
490
+ aspect: z
491
+ .enum(["errors", "workflows", "danger", "security", "performance", "all"])
492
+ .optional()
493
+ .default("all")
494
+ .describe("Specific aspect to retrieve"),
495
+ detailed: z.boolean().optional().default(true).describe("Include detailed breakdowns"),
496
+ }, async (args) => {
497
+ // If no domain specified, return domain summary
498
+ if (!args.domain) {
499
+ const summary = getAllDomainsSummary();
500
+ return {
501
+ content: [
502
+ {
503
+ type: "text",
504
+ text: JSON.stringify({
505
+ type: "domain_summary",
506
+ hint: "Specify a domain to get detailed best practices",
507
+ domains: summary,
508
+ }, null, 2),
509
+ },
510
+ ],
511
+ };
512
+ }
513
+ // Query best practices for specified domain
514
+ const result = queryBestPractices({
515
+ domain: args.domain,
516
+ aspect: args.aspect,
517
+ detailed: args.detailed,
518
+ });
519
+ if (!result.success) {
520
+ return {
521
+ content: [
522
+ {
523
+ type: "text",
524
+ text: JSON.stringify({ success: false, error: result.error }, null, 2),
525
+ },
526
+ ],
527
+ };
528
+ }
529
+ return {
530
+ content: [
531
+ {
532
+ type: "text",
533
+ text: JSON.stringify({
534
+ success: true,
535
+ practices: result.practices,
536
+ formatted: args.detailed && result.practices
537
+ ? formatBestPractices(result.practices)
538
+ : undefined,
539
+ }, null, 2),
540
+ },
541
+ ],
542
+ };
543
+ });
544
+ const indexMetadata = getIndexMetadata();
545
+ const consolidationStats = getConsolidationStats();
546
+ logger.info("Tool registration completed (dynamic discovery mode)", {
547
+ authMode,
548
+ authenticated: authMode !== AuthMode.NONE,
549
+ registeredTools: 12,
550
+ indexedTools: indexMetadata.totalTools,
551
+ consolidatedResources: consolidationStats.consolidatedCount,
552
+ consolidationReduction: consolidationStats.reductionPercent,
553
+ domains: Object.keys(indexMetadata.domains),
554
+ tokenSavings: "95%+ (535K → ~500 tokens upfront)",
555
+ });
556
+ }
557
+ /**
558
+ * Register MCP resources for F5XC configuration objects
559
+ */
560
+ registerResources() {
561
+ const tenant = this.credentialManager.getTenant() ?? "{tenant}";
562
+ // Register resource templates for each resource type
563
+ for (const rt of Object.values(RESOURCE_TYPES)) {
564
+ const uriTemplate = rt.namespaceScoped
565
+ ? `f5xc://${tenant}/{namespace}/${rt.type}/{name}`
566
+ : `f5xc://${tenant}/system/${rt.type}/{name}`;
567
+ this.server.resource(uriTemplate, rt.description, async (uri) => {
568
+ try {
569
+ const result = await this.resourceHandler.readResource(uri.href);
570
+ return {
571
+ contents: [
572
+ {
573
+ uri: result.uri,
574
+ mimeType: result.mimeType,
575
+ text: result.content,
576
+ },
577
+ ],
578
+ };
579
+ }
580
+ catch (error) {
581
+ logger.error(`Failed to read resource: ${uri.href}`, {
582
+ error: error instanceof Error ? error.message : String(error),
583
+ });
584
+ throw error;
585
+ }
586
+ });
587
+ }
588
+ logger.info("Resource registration completed", {
589
+ resourceTypes: Object.keys(RESOURCE_TYPES).length,
590
+ });
591
+ }
592
+ /**
593
+ * Register MCP prompts for common workflows
594
+ */
595
+ registerPrompts() {
596
+ // Register all workflow prompts
597
+ for (const workflow of WORKFLOW_PROMPTS) {
598
+ // Build Zod schema for arguments
599
+ const argSchema = {};
600
+ for (const arg of workflow.arguments) {
601
+ argSchema[arg.name] = arg.required
602
+ ? z.string().describe(arg.description)
603
+ : z.string().optional().describe(arg.description);
604
+ }
605
+ this.server.prompt(workflow.name, workflow.description, argSchema, async (args) => {
606
+ // Process template with provided arguments
607
+ const processedArgs = {};
608
+ for (const [key, value] of Object.entries(args)) {
609
+ if (typeof value === "string") {
610
+ processedArgs[key] = value;
611
+ }
612
+ }
613
+ // Apply default values for optional args
614
+ for (const arg of workflow.arguments) {
615
+ if (!processedArgs[arg.name] && !arg.required) {
616
+ // Set sensible defaults
617
+ if (arg.name === "backend_port")
618
+ processedArgs[arg.name] = "80";
619
+ if (arg.name === "enable_waf")
620
+ processedArgs[arg.name] = "false";
621
+ if (arg.name === "mode")
622
+ processedArgs[arg.name] = "blocking";
623
+ }
624
+ }
625
+ const processedTemplate = processPromptTemplate(workflow.template, processedArgs);
626
+ return {
627
+ messages: [
628
+ {
629
+ role: "user",
630
+ content: {
631
+ type: "text",
632
+ text: processedTemplate,
633
+ },
634
+ },
635
+ ],
636
+ };
637
+ });
638
+ }
639
+ // Phase B: Register error resolution prompts
640
+ for (const errorPrompt of ERROR_PROMPTS) {
641
+ // Build Zod schema for arguments
642
+ const argSchema = {};
643
+ for (const arg of errorPrompt.arguments) {
644
+ argSchema[arg.name] = arg.required
645
+ ? z.string().describe(arg.description)
646
+ : z.string().optional().describe(arg.description);
647
+ }
648
+ this.server.prompt(errorPrompt.name, errorPrompt.description, argSchema, async (args) => {
649
+ // Process template with provided arguments
650
+ const processedArgs = {};
651
+ for (const [key, value] of Object.entries(args)) {
652
+ if (typeof value === "string") {
653
+ processedArgs[key] = value;
654
+ }
655
+ }
656
+ const processedTemplate = processErrorTemplate(errorPrompt, processedArgs);
657
+ return {
658
+ messages: [
659
+ {
660
+ role: "user",
661
+ content: {
662
+ type: "text",
663
+ text: processedTemplate,
664
+ },
665
+ },
666
+ ],
667
+ };
668
+ });
669
+ }
670
+ logger.info("Prompt registration completed", {
671
+ workflows: WORKFLOW_PROMPTS.length,
672
+ errorPrompts: ERROR_PROMPTS.length,
673
+ });
674
+ }
675
+ /**
676
+ * Start the MCP server with STDIO transport
677
+ */
678
+ async start() {
679
+ this.transport = new StdioServerTransport();
680
+ logger.info("Starting F5XC API MCP Server", {
681
+ version: VERSION,
682
+ authMode: this.credentialManager.getAuthMode(),
683
+ });
684
+ await this.server.connect(this.transport);
685
+ logger.info("F5XC API MCP Server started successfully");
686
+ }
687
+ /**
688
+ * Stop the MCP server
689
+ */
690
+ async stop() {
691
+ if (this.transport) {
692
+ await this.server.close();
693
+ this.transport = null;
694
+ logger.info("F5XC API MCP Server stopped");
695
+ }
696
+ }
697
+ /**
698
+ * Get the underlying MCP server instance
699
+ */
700
+ getMcpServer() {
701
+ return this.server;
702
+ }
703
+ /**
704
+ * Get the credential manager
705
+ */
706
+ getCredentialManager() {
707
+ return this.credentialManager;
708
+ }
709
+ }
710
+ /**
711
+ * Create and configure the F5XC API MCP Server
712
+ */
713
+ export function createServer(configManager) {
714
+ const credentialManager = new CredentialManager(configManager);
715
+ return new F5XCApiServer({
716
+ name: "f5xc-api-mcp",
717
+ version: VERSION,
718
+ credentialManager,
719
+ });
720
+ }
721
+ //# sourceMappingURL=server.js.map