@mcp-abap-adt/calm-server 0.1.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.
Files changed (200) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE +22 -0
  3. package/README.md +213 -0
  4. package/dist/bin/stdio.d.ts +3 -0
  5. package/dist/bin/stdio.d.ts.map +1 -0
  6. package/dist/bin/stdio.js +15 -0
  7. package/dist/bin/stdio.js.map +1 -0
  8. package/dist/index.d.ts +14 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +34 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/registry/CalmToolRegistry.d.ts +27 -0
  13. package/dist/registry/CalmToolRegistry.d.ts.map +1 -0
  14. package/dist/registry/CalmToolRegistry.js +62 -0
  15. package/dist/registry/CalmToolRegistry.js.map +1 -0
  16. package/dist/registry/HandlerGroup.d.ts +14 -0
  17. package/dist/registry/HandlerGroup.d.ts.map +1 -0
  18. package/dist/registry/HandlerGroup.js +24 -0
  19. package/dist/registry/HandlerGroup.js.map +1 -0
  20. package/dist/registry/index.d.ts +5 -0
  21. package/dist/registry/index.d.ts.map +1 -0
  22. package/dist/registry/index.js +10 -0
  23. package/dist/registry/index.js.map +1 -0
  24. package/dist/registry/jsonSchemaToZod.d.ts +13 -0
  25. package/dist/registry/jsonSchemaToZod.d.ts.map +1 -0
  26. package/dist/registry/jsonSchemaToZod.js +57 -0
  27. package/dist/registry/jsonSchemaToZod.js.map +1 -0
  28. package/dist/registry/types.d.ts +59 -0
  29. package/dist/registry/types.d.ts.map +1 -0
  30. package/dist/registry/types.js +3 -0
  31. package/dist/registry/types.js.map +1 -0
  32. package/dist/server/BaseCalmMcpServer.d.ts +37 -0
  33. package/dist/server/BaseCalmMcpServer.d.ts.map +1 -0
  34. package/dist/server/BaseCalmMcpServer.js +44 -0
  35. package/dist/server/BaseCalmMcpServer.js.map +1 -0
  36. package/dist/server/buildClient.d.ts +10 -0
  37. package/dist/server/buildClient.d.ts.map +1 -0
  38. package/dist/server/buildClient.js +74 -0
  39. package/dist/server/buildClient.js.map +1 -0
  40. package/dist/server/config.d.ts +18 -0
  41. package/dist/server/config.d.ts.map +1 -0
  42. package/dist/server/config.js +58 -0
  43. package/dist/server/config.js.map +1 -0
  44. package/dist/server/index.d.ts +5 -0
  45. package/dist/server/index.d.ts.map +1 -0
  46. package/dist/server/index.js +13 -0
  47. package/dist/server/index.js.map +1 -0
  48. package/dist/server/runStdio.d.ts +12 -0
  49. package/dist/server/runStdio.d.ts.map +1 -0
  50. package/dist/server/runStdio.js +48 -0
  51. package/dist/server/runStdio.js.map +1 -0
  52. package/dist/tools/analytics/index.d.ts +8 -0
  53. package/dist/tools/analytics/index.d.ts.map +1 -0
  54. package/dist/tools/analytics/index.js +16 -0
  55. package/dist/tools/analytics/index.js.map +1 -0
  56. package/dist/tools/analytics/listAnalyticsProviders.d.ts +5 -0
  57. package/dist/tools/analytics/listAnalyticsProviders.d.ts.map +1 -0
  58. package/dist/tools/analytics/listAnalyticsProviders.js +16 -0
  59. package/dist/tools/analytics/listAnalyticsProviders.js.map +1 -0
  60. package/dist/tools/analytics/queryAnalytics.d.ts +15 -0
  61. package/dist/tools/analytics/queryAnalytics.d.ts.map +1 -0
  62. package/dist/tools/analytics/queryAnalytics.js +61 -0
  63. package/dist/tools/analytics/queryAnalytics.js.map +1 -0
  64. package/dist/tools/documents/getDocument.d.ts +7 -0
  65. package/dist/tools/documents/getDocument.d.ts.map +1 -0
  66. package/dist/tools/documents/getDocument.js +34 -0
  67. package/dist/tools/documents/getDocument.js.map +1 -0
  68. package/dist/tools/documents/index.d.ts +9 -0
  69. package/dist/tools/documents/index.d.ts.map +1 -0
  70. package/dist/tools/documents/index.js +16 -0
  71. package/dist/tools/documents/index.js.map +1 -0
  72. package/dist/tools/documents/listDocuments.d.ts +16 -0
  73. package/dist/tools/documents/listDocuments.d.ts.map +1 -0
  74. package/dist/tools/documents/listDocuments.js +85 -0
  75. package/dist/tools/documents/listDocuments.js.map +1 -0
  76. package/dist/tools/features/createFeature.d.ts +5 -0
  77. package/dist/tools/features/createFeature.d.ts.map +1 -0
  78. package/dist/tools/features/createFeature.js +55 -0
  79. package/dist/tools/features/createFeature.js.map +1 -0
  80. package/dist/tools/features/deleteFeature.d.ts +10 -0
  81. package/dist/tools/features/deleteFeature.d.ts.map +1 -0
  82. package/dist/tools/features/deleteFeature.js +35 -0
  83. package/dist/tools/features/deleteFeature.js.map +1 -0
  84. package/dist/tools/features/getFeature.d.ts +7 -0
  85. package/dist/tools/features/getFeature.d.ts.map +1 -0
  86. package/dist/tools/features/getFeature.js +37 -0
  87. package/dist/tools/features/getFeature.js.map +1 -0
  88. package/dist/tools/features/getFeatureByDisplayId.d.ts +7 -0
  89. package/dist/tools/features/getFeatureByDisplayId.d.ts.map +1 -0
  90. package/dist/tools/features/getFeatureByDisplayId.js +37 -0
  91. package/dist/tools/features/getFeatureByDisplayId.js.map +1 -0
  92. package/dist/tools/features/index.d.ts +21 -0
  93. package/dist/tools/features/index.d.ts.map +1 -0
  94. package/dist/tools/features/index.js +40 -0
  95. package/dist/tools/features/index.js.map +1 -0
  96. package/dist/tools/features/listFeaturePriorities.d.ts +7 -0
  97. package/dist/tools/features/listFeaturePriorities.d.ts.map +1 -0
  98. package/dist/tools/features/listFeaturePriorities.js +23 -0
  99. package/dist/tools/features/listFeaturePriorities.js.map +1 -0
  100. package/dist/tools/features/listFeatureStatuses.d.ts +7 -0
  101. package/dist/tools/features/listFeatureStatuses.d.ts.map +1 -0
  102. package/dist/tools/features/listFeatureStatuses.js +23 -0
  103. package/dist/tools/features/listFeatureStatuses.js.map +1 -0
  104. package/dist/tools/features/listFeatures.d.ts +19 -0
  105. package/dist/tools/features/listFeatures.d.ts.map +1 -0
  106. package/dist/tools/features/listFeatures.js +123 -0
  107. package/dist/tools/features/listFeatures.js.map +1 -0
  108. package/dist/tools/features/updateFeature.d.ts +7 -0
  109. package/dist/tools/features/updateFeature.d.ts.map +1 -0
  110. package/dist/tools/features/updateFeature.js +44 -0
  111. package/dist/tools/features/updateFeature.js.map +1 -0
  112. package/dist/tools/hierarchy/getHierarchyWithChildren.d.ts +10 -0
  113. package/dist/tools/hierarchy/getHierarchyWithChildren.d.ts.map +1 -0
  114. package/dist/tools/hierarchy/getHierarchyWithChildren.js +45 -0
  115. package/dist/tools/hierarchy/getHierarchyWithChildren.js.map +1 -0
  116. package/dist/tools/hierarchy/index.d.ts +9 -0
  117. package/dist/tools/hierarchy/index.d.ts.map +1 -0
  118. package/dist/tools/hierarchy/index.js +16 -0
  119. package/dist/tools/hierarchy/index.js.map +1 -0
  120. package/dist/tools/hierarchy/listHierarchy.d.ts +16 -0
  121. package/dist/tools/hierarchy/listHierarchy.d.ts.map +1 -0
  122. package/dist/tools/hierarchy/listHierarchy.js +74 -0
  123. package/dist/tools/hierarchy/listHierarchy.js.map +1 -0
  124. package/dist/tools/index.d.ts +16 -0
  125. package/dist/tools/index.d.ts.map +1 -0
  126. package/dist/tools/index.js +45 -0
  127. package/dist/tools/index.js.map +1 -0
  128. package/dist/tools/logs/getLogs.d.ts +15 -0
  129. package/dist/tools/logs/getLogs.d.ts.map +1 -0
  130. package/dist/tools/logs/getLogs.js +55 -0
  131. package/dist/tools/logs/getLogs.js.map +1 -0
  132. package/dist/tools/logs/index.d.ts +7 -0
  133. package/dist/tools/logs/index.d.ts.map +1 -0
  134. package/dist/tools/logs/index.js +10 -0
  135. package/dist/tools/logs/index.js.map +1 -0
  136. package/dist/tools/processMonitoring/index.d.ts +7 -0
  137. package/dist/tools/processMonitoring/index.d.ts.map +1 -0
  138. package/dist/tools/processMonitoring/index.js +12 -0
  139. package/dist/tools/processMonitoring/index.js.map +1 -0
  140. package/dist/tools/processMonitoring/listBusinessProcesses.d.ts +10 -0
  141. package/dist/tools/processMonitoring/listBusinessProcesses.d.ts.map +1 -0
  142. package/dist/tools/processMonitoring/listBusinessProcesses.js +36 -0
  143. package/dist/tools/processMonitoring/listBusinessProcesses.js.map +1 -0
  144. package/dist/tools/projects/getProject.d.ts +7 -0
  145. package/dist/tools/projects/getProject.d.ts.map +1 -0
  146. package/dist/tools/projects/getProject.js +32 -0
  147. package/dist/tools/projects/getProject.js.map +1 -0
  148. package/dist/tools/projects/index.d.ts +9 -0
  149. package/dist/tools/projects/index.d.ts.map +1 -0
  150. package/dist/tools/projects/index.js +16 -0
  151. package/dist/tools/projects/index.js.map +1 -0
  152. package/dist/tools/projects/listProjects.d.ts +16 -0
  153. package/dist/tools/projects/listProjects.d.ts.map +1 -0
  154. package/dist/tools/projects/listProjects.js +69 -0
  155. package/dist/tools/projects/listProjects.js.map +1 -0
  156. package/dist/tools/tasks/getTask.d.ts +7 -0
  157. package/dist/tools/tasks/getTask.d.ts.map +1 -0
  158. package/dist/tools/tasks/getTask.js +34 -0
  159. package/dist/tools/tasks/getTask.js.map +1 -0
  160. package/dist/tools/tasks/index.d.ts +11 -0
  161. package/dist/tools/tasks/index.d.ts.map +1 -0
  162. package/dist/tools/tasks/index.js +20 -0
  163. package/dist/tools/tasks/index.js.map +1 -0
  164. package/dist/tools/tasks/listTaskComments.d.ts +11 -0
  165. package/dist/tools/tasks/listTaskComments.d.ts.map +1 -0
  166. package/dist/tools/tasks/listTaskComments.js +46 -0
  167. package/dist/tools/tasks/listTaskComments.js.map +1 -0
  168. package/dist/tools/tasks/listTasks.d.ts +17 -0
  169. package/dist/tools/tasks/listTasks.d.ts.map +1 -0
  170. package/dist/tools/tasks/listTasks.js +89 -0
  171. package/dist/tools/tasks/listTasks.js.map +1 -0
  172. package/dist/tools/testCases/getTestCase.d.ts +7 -0
  173. package/dist/tools/testCases/getTestCase.d.ts.map +1 -0
  174. package/dist/tools/testCases/getTestCase.js +34 -0
  175. package/dist/tools/testCases/getTestCase.js.map +1 -0
  176. package/dist/tools/testCases/index.d.ts +9 -0
  177. package/dist/tools/testCases/index.d.ts.map +1 -0
  178. package/dist/tools/testCases/index.js +16 -0
  179. package/dist/tools/testCases/index.js.map +1 -0
  180. package/dist/tools/testCases/listTestCases.d.ts +16 -0
  181. package/dist/tools/testCases/listTestCases.d.ts.map +1 -0
  182. package/dist/tools/testCases/listTestCases.js +69 -0
  183. package/dist/tools/testCases/listTestCases.js.map +1 -0
  184. package/dist/utils/errorMapping.d.ts +28 -0
  185. package/dist/utils/errorMapping.d.ts.map +1 -0
  186. package/dist/utils/errorMapping.js +88 -0
  187. package/dist/utils/errorMapping.js.map +1 -0
  188. package/dist/utils/index.d.ts +4 -0
  189. package/dist/utils/index.d.ts.map +1 -0
  190. package/dist/utils/index.js +15 -0
  191. package/dist/utils/index.js.map +1 -0
  192. package/dist/utils/odataFilter.d.ts +15 -0
  193. package/dist/utils/odataFilter.d.ts.map +1 -0
  194. package/dist/utils/odataFilter.js +24 -0
  195. package/dist/utils/odataFilter.js.map +1 -0
  196. package/dist/utils/tokenEconomy.d.ts +36 -0
  197. package/dist/utils/tokenEconomy.d.ts.map +1 -0
  198. package/dist/utils/tokenEconomy.js +37 -0
  199. package/dist/utils/tokenEconomy.js.map +1 -0
  200. package/package.json +86 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-04-24
4
+
5
+ First usable release. 23 MCP tools covering all 9 Cloud ALM services,
6
+ dual library + runnable-server package, 103 unit tests, full build green.
7
+
8
+ ### Added
9
+
10
+ - **`BaseCalmMcpServer`** — subclass of `@modelcontextprotocol/sdk`'s
11
+ `McpServer`. Accepts a `CalmClient` + handler groups and registers
12
+ every tool with automatic context injection on each call.
13
+ - **`CalmToolRegistry`** + **`HandlerGroup`** — service-scoped tool
14
+ bundling with duplicate detection and JSON Schema → Zod conversion
15
+ at registration time (handler files stay pure).
16
+ - **23 MCP tools** across 9 services (see README for the full table).
17
+ All list tools follow the same token-economy contract (compact
18
+ default fields, `limit` capped at 200, `offset`, optional `withCount`).
19
+ - **`calm-mcp` bin** — `npx @mcp-abap-adt/calm-server` runs the server
20
+ on stdio. `.env` + standard `CALM_MODE=oauth2|sandbox` config; same
21
+ env shape as `@mcp-abap-adt/calm-client` integration tests.
22
+ - **Error mapping** — `CalmApiError` (from calm-client) → `CalmToolError`
23
+ with machine codes (`NOT_FOUND`, `ODATA_ERROR`, `HTTP_ERROR`,
24
+ `NETWORK`, `JSON_PARSE`, `UNKNOWN`, `INVALID_ARGUMENT`).
25
+ - **Token-economy helpers** — `clampListLimit`, `toListResponse`,
26
+ `escapeODataString`, `joinAndFilters`. Reusable in downstream tool
27
+ implementations.
28
+ - **XSUAA client_credentials refresher** (`XsuaaRefresher` in
29
+ `buildClient.ts`) — minimal standalone-mode auth; production
30
+ consumers can inject their own `ITokenRefresher`.
31
+ - **Subpath exports** — `./tools` + `./registry` for composing the
32
+ tool set into a larger MCP server.
33
+
34
+ ### Requires
35
+
36
+ - `@mcp-abap-adt/calm-client` ^0.1.0 (peer)
37
+ - `@mcp-abap-adt/interfaces` ^7.1.0 (peer)
38
+ - `@modelcontextprotocol/sdk` ^1.0.0 (peer)
39
+ - Node.js ≥ 18
40
+
41
+ ### Notes
42
+
43
+ - Destructive tools (create/update/delete) shipped for **Features only**;
44
+ other services expose read-only tools in 0.1.0. Full CRUD everywhere
45
+ is planned for a later minor after live-tenant validation.
46
+ - No integration tests in this package — the `CalmClient` peer already
47
+ verifies transport-level behavior against live tenants.
48
+
49
+ ## 0.0.1 — planning scaffold (superseded)
50
+
51
+ - Project scaffolded: package.json, tsconfig, biome, jest, LICENSE, .gitignore.
52
+ - PLAN.md drafted with architecture, directory layout, tool surface,
53
+ MCP SDK choice, runtime config pattern, milestones, and open decisions.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Oleksii Kyslytsia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # @mcp-abap-adt/calm-server
2
+
3
+ [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
4
+
5
+ MCP server for **SAP Cloud ALM**, built on
6
+ [`@mcp-abap-adt/calm-client`](https://github.com/fr0ster/mcp-calm-client).
7
+ Ships 23 MCP tools covering all 9 Cloud ALM services, with rich JSON
8
+ Schema descriptions that let an LLM plan multi-step workflows.
9
+
10
+ This package is **dual-purpose**:
11
+
12
+ - **Runnable stdio server** — `npx @mcp-abap-adt/calm-server`. Plug
13
+ directly into Claude Desktop, Claude Code, or any MCP-compatible host.
14
+ - **Reusable library of tool primitives** — import individual tools
15
+ (`FEATURES_GROUP`, `TASKS_GROUP`, …) and embed them in a larger
16
+ composed MCP server without reimplementing anything.
17
+
18
+ ## Status
19
+
20
+ **0.1.0** — 23 tools, 103 unit tests, full build green. Integration
21
+ against a live Cloud ALM tenant/sandbox is driven by the host — no
22
+ server-side credential storage beyond the standalone `.env`.
23
+
24
+ ## Installation
25
+
26
+ ### As a standalone MCP server
27
+
28
+ ```bash
29
+ npm install -g @mcp-abap-adt/calm-server
30
+ # or per-project:
31
+ npm install @mcp-abap-adt/calm-server
32
+ ```
33
+
34
+ ### As a library (compose into your own MCP server)
35
+
36
+ ```bash
37
+ npm install @mcp-abap-adt/calm-server
38
+ # peers:
39
+ npm install @mcp-abap-adt/calm-client @mcp-abap-adt/interfaces @modelcontextprotocol/sdk
40
+ ```
41
+
42
+ ## Standalone: running the server
43
+
44
+ ### 1. Configure credentials
45
+
46
+ Copy the template and fill in:
47
+
48
+ ```bash
49
+ cp .env.example .env
50
+ ```
51
+
52
+ **OAuth2 mode (real tenant)** — paste values from an XSUAA service key:
53
+
54
+ ```env
55
+ CALM_MODE=oauth2
56
+ CALM_BASE_URL=https://<tenant>.<region>.alm.cloud.sap
57
+ CALM_UAA_URL=https://<tenant>.authentication.<region>.hana.ondemand.com
58
+ CALM_UAA_CLIENT_ID=sb-…!b…|calm!b…
59
+ CALM_UAA_CLIENT_SECRET=…
60
+ ```
61
+
62
+ **Sandbox mode (SAP API Business Hub)**:
63
+
64
+ ```env
65
+ CALM_MODE=sandbox
66
+ CALM_API_KEY=<your-key-from-api.sap.com>
67
+ # CALM_BASE_URL defaults to https://sandbox.api.sap.com/SAPCALM
68
+ ```
69
+
70
+ ### 2. Launch
71
+
72
+ ```bash
73
+ # Global install:
74
+ calm-mcp
75
+ # Or via npx without install:
76
+ npx @mcp-abap-adt/calm-server
77
+ # Or from a clone:
78
+ npm run build && node dist/bin/stdio.js
79
+ ```
80
+
81
+ The server speaks MCP over stdio. Misconfiguration is reported to
82
+ `stderr` with a non-zero exit code.
83
+
84
+ ### 3. Wire into Claude Desktop
85
+
86
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`
87
+ on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
88
+
89
+ ```json
90
+ {
91
+ "mcpServers": {
92
+ "calm": {
93
+ "command": "npx",
94
+ "args": ["-y", "@mcp-abap-adt/calm-server"],
95
+ "env": {
96
+ "CALM_MODE": "sandbox",
97
+ "CALM_API_KEY": "<your-sandbox-key>"
98
+ }
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ Restart Claude Desktop; the 23 `calm_*` tools become available to the
105
+ model.
106
+
107
+ ## Library: composing into another MCP server
108
+
109
+ Useful when you want to expose Cloud ALM tools alongside ADT tools,
110
+ Reports tools, or your own domain tools in a single MCP process.
111
+
112
+ ```ts
113
+ import { CalmClient, CalmConnection } from '@mcp-abap-adt/calm-client';
114
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
115
+ import {
116
+ ALL_GROUPS,
117
+ BaseCalmMcpServer,
118
+ CalmToolRegistry,
119
+ FEATURES_GROUP,
120
+ TASKS_GROUP,
121
+ } from '@mcp-abap-adt/calm-server';
122
+
123
+ // Option A — BaseCalmMcpServer with a curated subset
124
+ const calm = new CalmClient(
125
+ new CalmConnection({ baseUrl, apiKey }),
126
+ );
127
+ const server = new BaseCalmMcpServer({
128
+ name: 'my-mcp',
129
+ version: '1.0.0',
130
+ calm,
131
+ groups: [FEATURES_GROUP, TASKS_GROUP], // only these land as tools
132
+ });
133
+
134
+ // Option B — embed into your existing McpServer
135
+ const existing = new McpServer({ name: 'combined', version: '1.0.0' });
136
+ const registry = new CalmToolRegistry([...ALL_GROUPS]);
137
+ registry.registerAll(existing, () => ({ calm }));
138
+ // Now `existing` serves Cloud ALM tools + whatever else you registered.
139
+ ```
140
+
141
+ Subpath exports:
142
+
143
+ ```ts
144
+ import { ALL_GROUPS } from '@mcp-abap-adt/calm-server/tools';
145
+ import { CalmToolRegistry } from '@mcp-abap-adt/calm-server/registry';
146
+ ```
147
+
148
+ ## Tool surface (23 tools across 9 services)
149
+
150
+ | Service | Tools |
151
+ |---|---|
152
+ | **Features** (8) | `list`, `get`, `get_by_display_id`, `create`, `update`, `delete`, `list_statuses`, `list_priorities` |
153
+ | **Documents** (2) | `list`, `get` |
154
+ | **TestCases** (2) | `list`, `get` |
155
+ | **Hierarchy** (2) | `list`, `get_with_children` (default `$expand=[toChildNodes, toParentNode]`) |
156
+ | **Analytics** (2, read-only) | `query` (17 endpoints), `list_providers` (static catalog) |
157
+ | **ProcessMonitoring** (1, read-only) | `list_processes` |
158
+ | **Tasks** (3) | `list`, `get`, `list_comments` |
159
+ | **Projects** (2) | `list`, `get` |
160
+ | **Logs** (1, domain-specific REST) | `get` (provider + serviceId + time window) |
161
+
162
+ Every MCP tool:
163
+ - Has a full JSON Schema with descriptions — the LLM reads these to plan.
164
+ - Wraps arguments into OData `$filter` / `$select` / `$top` / `$skip`
165
+ internally — the LLM never sees raw OData syntax.
166
+ - Returns compact records by default (`limit=20`, `fields` default ≈ 6
167
+ columns per entity); callers opt into more via `fields`, `limit`,
168
+ `withCount`, `offset`.
169
+ - Maps `CalmApiError` → a typed MCP error the LLM can branch on
170
+ (`NOT_FOUND`, `NETWORK`, `ODATA_ERROR` with `serviceCode`, …).
171
+
172
+ See `src/tools/<service>/*.ts` for per-tool argument schemas.
173
+
174
+ ## Destructive tools (write operations)
175
+
176
+ Currently only **Features** exposes `create` / `update` / `delete`. For
177
+ the other 8 services, destructive tools are deferred to a future minor
178
+ release — they require live-tenant validation before the patterns are
179
+ promoted. If you need them earlier, open an issue or contribute via the
180
+ per-service handler modules; pattern is identical to the Features ones.
181
+
182
+ ## Debug logging
183
+
184
+ ```bash
185
+ CALM_LOG_LEVEL=debug # error | warn | info | debug
186
+ DEBUG_CALM_CONNECTORS=true # CalmConnection retries, 401 refresh, URLs
187
+ DEBUG_CALM_LIBS=true # resource-client internals
188
+ DEBUG_CALM_TESTS=true # test execution progress
189
+ ```
190
+
191
+ Logging goes to stderr (stdout is reserved for the MCP protocol stream).
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ git clone git@github.com:fr0ster/mcp-calm-server.git
197
+ cd mcp-calm-server
198
+ npm install
199
+
200
+ npm run test # 103 unit tests, no network
201
+ npm run build # emits dist/, includes executable bin
202
+ npm run lint:check # biome
203
+ ```
204
+
205
+ No integration tests in this package — the `CalmClient` peer already
206
+ covers live-tenant verification (see
207
+ [mcp-calm-client/docs/TESTING.md](https://github.com/fr0ster/mcp-calm-client/blob/main/docs/TESTING.md)).
208
+ Tools here only mediate between MCP and the client; their contracts
209
+ are fully exercised via mocks.
210
+
211
+ ## License
212
+
213
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/bin/stdio.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const runStdio_1 = require("../server/runStdio");
5
+ (0, runStdio_1.runStdio)().catch((err) => {
6
+ const msg = err instanceof Error ? err.message : String(err);
7
+ // All diagnostic output on stderr — stdout is reserved for the MCP
8
+ // protocol stream.
9
+ process.stderr.write(`[calm-mcp] startup failed: ${msg}\n`);
10
+ if (err instanceof Error && err.stack) {
11
+ process.stderr.write(`${err.stack}\n`);
12
+ }
13
+ process.exit(1);
14
+ });
15
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/bin/stdio.ts"],"names":[],"mappings":";;;AACA,iDAA8C;AAE9C,IAAA,mBAAQ,GAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAChC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,mEAAmE;IACnE,mBAAmB;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAAC;IAC5D,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @mcp-abap-adt/calm-server — public API
3
+ *
4
+ * Two ways to consume:
5
+ * 1. Library: import handler groups and compose them onto your own
6
+ * `McpServer` instance (optionally alongside other MCP packages).
7
+ * 2. Runnable server: `npx calm-mcp` (see bin/stdio.ts, planned M5).
8
+ *
9
+ * See PLAN.md for roadmap.
10
+ */
11
+ export { type CalmToolHandler, CalmToolRegistry, HandlerGroup, type ICalmHandlerContext, type ICalmHandlerEntry, type ICalmHandlerGroup, type ICalmToolDefinition, } from './registry';
12
+ export { BaseCalmMcpServer, type IBaseCalmMcpServerOptions, } from './server';
13
+ export * from './tools';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,eAAe,EACpB,gBAAgB,EAChB,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,KAAK,yBAAyB,GAC/B,MAAM,UAAU,CAAC;AAClB,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * @mcp-abap-adt/calm-server — public API
4
+ *
5
+ * Two ways to consume:
6
+ * 1. Library: import handler groups and compose them onto your own
7
+ * `McpServer` instance (optionally alongside other MCP packages).
8
+ * 2. Runnable server: `npx calm-mcp` (see bin/stdio.ts, planned M5).
9
+ *
10
+ * See PLAN.md for roadmap.
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
24
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.BaseCalmMcpServer = exports.HandlerGroup = exports.CalmToolRegistry = void 0;
28
+ var registry_1 = require("./registry");
29
+ Object.defineProperty(exports, "CalmToolRegistry", { enumerable: true, get: function () { return registry_1.CalmToolRegistry; } });
30
+ Object.defineProperty(exports, "HandlerGroup", { enumerable: true, get: function () { return registry_1.HandlerGroup; } });
31
+ var server_1 = require("./server");
32
+ Object.defineProperty(exports, "BaseCalmMcpServer", { enumerable: true, get: function () { return server_1.BaseCalmMcpServer; } });
33
+ __exportStar(require("./tools"), exports);
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;AAEH,uCAQoB;AANlB,4GAAA,gBAAgB,OAAA;AAChB,wGAAA,YAAY,OAAA;AAMd,mCAGkB;AAFhB,2GAAA,iBAAiB,OAAA;AAGnB,0CAAwB"}
@@ -0,0 +1,27 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ICalmHandlerContext, ICalmHandlerGroup } from './types';
3
+ /**
4
+ * Registers Cloud ALM tools on an MCP server instance.
5
+ *
6
+ * Accepts one or more handler groups (service-level tool bundles) and
7
+ * a context factory. The factory is invoked lazily per tool call so
8
+ * consumers can inject per-request connections (SSE/HTTP transport) if
9
+ * they ever need it; for stdio the factory returns the same context
10
+ * every call.
11
+ */
12
+ export declare class CalmToolRegistry {
13
+ private readonly groups;
14
+ private readonly registered;
15
+ constructor(groups?: ICalmHandlerGroup[]);
16
+ addGroup(group: ICalmHandlerGroup): void;
17
+ listGroups(): readonly ICalmHandlerGroup[];
18
+ listTools(): string[];
19
+ /**
20
+ * Register every tool from every group on the MCP server.
21
+ * Throws on duplicate tool names so misconfiguration fails fast
22
+ * during development.
23
+ */
24
+ registerAll(server: McpServer, getContext: () => ICalmHandlerContext | Promise<ICalmHandlerContext>): void;
25
+ private registerOne;
26
+ }
27
+ //# sourceMappingURL=CalmToolRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalmToolRegistry.d.ts","sourceRoot":"","sources":["../../src/registry/CalmToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EACV,mBAAmB,EAEnB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAEpC,MAAM,GAAE,iBAAiB,EAAO;IAI5C,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIxC,UAAU,IAAI,SAAS,iBAAiB,EAAE;IAI1C,SAAS,IAAI,MAAM,EAAE;IAIrB;;;;OAIG;IACH,WAAW,CACT,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,GACnE,IAAI;IASP,OAAO,CAAC,WAAW;CA6BpB"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalmToolRegistry = void 0;
4
+ const jsonSchemaToZod_1 = require("./jsonSchemaToZod");
5
+ /**
6
+ * Registers Cloud ALM tools on an MCP server instance.
7
+ *
8
+ * Accepts one or more handler groups (service-level tool bundles) and
9
+ * a context factory. The factory is invoked lazily per tool call so
10
+ * consumers can inject per-request connections (SSE/HTTP transport) if
11
+ * they ever need it; for stdio the factory returns the same context
12
+ * every call.
13
+ */
14
+ class CalmToolRegistry {
15
+ groups;
16
+ registered = new Set();
17
+ constructor(groups = []) {
18
+ this.groups = [...groups];
19
+ }
20
+ addGroup(group) {
21
+ this.groups.push(group);
22
+ }
23
+ listGroups() {
24
+ return [...this.groups];
25
+ }
26
+ listTools() {
27
+ return [...this.registered];
28
+ }
29
+ /**
30
+ * Register every tool from every group on the MCP server.
31
+ * Throws on duplicate tool names so misconfiguration fails fast
32
+ * during development.
33
+ */
34
+ registerAll(server, getContext) {
35
+ this.registered.clear();
36
+ for (const group of this.groups) {
37
+ for (const entry of group.getHandlers()) {
38
+ this.registerOne(server, entry, getContext);
39
+ }
40
+ }
41
+ }
42
+ registerOne(server, entry, getContext) {
43
+ const { toolDefinition, handler } = entry;
44
+ if (this.registered.has(toolDefinition.name)) {
45
+ throw new Error(`CalmToolRegistry: duplicate tool name "${toolDefinition.name}"`);
46
+ }
47
+ this.registered.add(toolDefinition.name);
48
+ const zodShape = (0, jsonSchemaToZod_1.jsonSchemaToZodShape)(toolDefinition.inputSchema);
49
+ server.registerTool(toolDefinition.name, {
50
+ description: toolDefinition.description,
51
+ inputSchema: zodShape,
52
+ }, async (args) => {
53
+ const ctx = await getContext();
54
+ const result = await handler(ctx, args);
55
+ return {
56
+ content: [{ type: 'text', text: JSON.stringify(result) }],
57
+ };
58
+ });
59
+ }
60
+ }
61
+ exports.CalmToolRegistry = CalmToolRegistry;
62
+ //# sourceMappingURL=CalmToolRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalmToolRegistry.js","sourceRoot":"","sources":["../../src/registry/CalmToolRegistry.ts"],"names":[],"mappings":";;;AACA,uDAAyD;AAOzD;;;;;;;;GAQG;AACH,MAAa,gBAAgB;IACV,MAAM,CAAsB;IAC5B,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,YAAY,SAA8B,EAAE;QAC1C,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,KAAwB;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,WAAW,CACT,MAAiB,EACjB,UAAoE;QAEpE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAEO,WAAW,CACjB,MAAiB,EACjB,KAAwB,EACxB,UAAoE;QAEpE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,0CAA0C,cAAc,CAAC,IAAI,GAAG,CACjE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,QAAQ,GAAG,IAAA,sCAAoB,EAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAClE,MAAM,CAAC,YAAY,CACjB,cAAc,CAAC,IAAI,EACnB;YACE,WAAW,EAAE,cAAc,CAAC,WAAW;YACvC,WAAW,EAAE,QAAQ;SACtB,EACD,KAAK,EAAE,IAAa,EAAE,EAAE;YACtB,MAAM,GAAG,GAAG,MAAM,UAAU,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACxC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAlED,4CAkEC"}
@@ -0,0 +1,14 @@
1
+ import type { ICalmHandlerEntry, ICalmHandlerGroup } from './types';
2
+ /**
3
+ * Minimal `ICalmHandlerGroup` implementation. Wraps a static list of
4
+ * handler entries with a group name. All per-service tool modules
5
+ * export one of these via `XXX_GROUP`.
6
+ */
7
+ export declare class HandlerGroup implements ICalmHandlerGroup {
8
+ private readonly name;
9
+ private readonly handlers;
10
+ constructor(name: string, handlers: readonly ICalmHandlerEntry[]);
11
+ getName(): string;
12
+ getHandlers(): readonly ICalmHandlerEntry[];
13
+ }
14
+ //# sourceMappingURL=HandlerGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HandlerGroup.d.ts","sourceRoot":"","sources":["../../src/registry/HandlerGroup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpE;;;;GAIG;AACH,qBAAa,YAAa,YAAW,iBAAiB;IAElD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,iBAAiB,EAAE;IAGzD,OAAO,IAAI,MAAM;IAIjB,WAAW,IAAI,SAAS,iBAAiB,EAAE;CAG5C"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HandlerGroup = void 0;
4
+ /**
5
+ * Minimal `ICalmHandlerGroup` implementation. Wraps a static list of
6
+ * handler entries with a group name. All per-service tool modules
7
+ * export one of these via `XXX_GROUP`.
8
+ */
9
+ class HandlerGroup {
10
+ name;
11
+ handlers;
12
+ constructor(name, handlers) {
13
+ this.name = name;
14
+ this.handlers = handlers;
15
+ }
16
+ getName() {
17
+ return this.name;
18
+ }
19
+ getHandlers() {
20
+ return this.handlers;
21
+ }
22
+ }
23
+ exports.HandlerGroup = HandlerGroup;
24
+ //# sourceMappingURL=HandlerGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HandlerGroup.js","sourceRoot":"","sources":["../../src/registry/HandlerGroup.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACH,MAAa,YAAY;IAEJ;IACA;IAFnB,YACmB,IAAY,EACZ,QAAsC;QADtC,SAAI,GAAJ,IAAI,CAAQ;QACZ,aAAQ,GAAR,QAAQ,CAA8B;IACtD,CAAC;IAEJ,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAbD,oCAaC"}
@@ -0,0 +1,5 @@
1
+ export { CalmToolRegistry } from './CalmToolRegistry';
2
+ export { HandlerGroup } from './HandlerGroup';
3
+ export { jsonSchemaToZodShape, type ZodShape } from './jsonSchemaToZod';
4
+ export type { CalmToolHandler, ICalmHandlerContext, ICalmHandlerEntry, ICalmHandlerGroup, ICalmToolDefinition, } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsonSchemaToZodShape = exports.HandlerGroup = exports.CalmToolRegistry = void 0;
4
+ var CalmToolRegistry_1 = require("./CalmToolRegistry");
5
+ Object.defineProperty(exports, "CalmToolRegistry", { enumerable: true, get: function () { return CalmToolRegistry_1.CalmToolRegistry; } });
6
+ var HandlerGroup_1 = require("./HandlerGroup");
7
+ Object.defineProperty(exports, "HandlerGroup", { enumerable: true, get: function () { return HandlerGroup_1.HandlerGroup; } });
8
+ var jsonSchemaToZod_1 = require("./jsonSchemaToZod");
9
+ Object.defineProperty(exports, "jsonSchemaToZodShape", { enumerable: true, get: function () { return jsonSchemaToZod_1.jsonSchemaToZodShape; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":";;;AAAA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,qDAAwE;AAA/D,uHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ export type ZodShape = Record<string, z.ZodTypeAny>;
3
+ /**
4
+ * Minimal JSON Schema → Zod raw shape converter. Covers the shapes our
5
+ * Cloud ALM tools use: `{ type, properties: { field: { type, enum?,
6
+ * items?, minimum?, maximum?, description? } }, required: [...] }`.
7
+ *
8
+ * Not a full JSON-Schema implementation — anyOf/allOf/oneOf, refs,
9
+ * patternProperties, etc. are out of scope. Extend here when a tool
10
+ * needs them.
11
+ */
12
+ export declare function jsonSchemaToZodShape(schema: Record<string, unknown>): ZodShape;
13
+ //# sourceMappingURL=jsonSchemaToZod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonSchemaToZod.d.ts","sourceRoot":"","sources":["../../src/registry/jsonSchemaToZod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;AAkBpD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,QAAQ,CAaV"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsonSchemaToZodShape = jsonSchemaToZodShape;
4
+ const zod_1 = require("zod");
5
+ /**
6
+ * Minimal JSON Schema → Zod raw shape converter. Covers the shapes our
7
+ * Cloud ALM tools use: `{ type, properties: { field: { type, enum?,
8
+ * items?, minimum?, maximum?, description? } }, required: [...] }`.
9
+ *
10
+ * Not a full JSON-Schema implementation — anyOf/allOf/oneOf, refs,
11
+ * patternProperties, etc. are out of scope. Extend here when a tool
12
+ * needs them.
13
+ */
14
+ function jsonSchemaToZodShape(schema) {
15
+ const obj = schema;
16
+ const properties = obj.properties ?? {};
17
+ const required = new Set(obj.required ?? []);
18
+ const shape = {};
19
+ for (const [key, prop] of Object.entries(properties)) {
20
+ let zodType = propToZod(prop);
21
+ if (prop.description)
22
+ zodType = zodType.describe(prop.description);
23
+ if (!required.has(key))
24
+ zodType = zodType.optional();
25
+ shape[key] = zodType;
26
+ }
27
+ return shape;
28
+ }
29
+ function propToZod(prop) {
30
+ switch (prop.type) {
31
+ case 'string': {
32
+ if (prop.enum && prop.enum.length > 0) {
33
+ const values = prop.enum.map(String);
34
+ if (values.length === 1)
35
+ return zod_1.z.literal(values[0]);
36
+ return zod_1.z.enum(values);
37
+ }
38
+ return zod_1.z.string();
39
+ }
40
+ case 'integer':
41
+ case 'number': {
42
+ let n = prop.type === 'integer' ? zod_1.z.number().int() : zod_1.z.number();
43
+ if (prop.minimum !== undefined)
44
+ n = n.min(prop.minimum);
45
+ if (prop.maximum !== undefined)
46
+ n = n.max(prop.maximum);
47
+ return n;
48
+ }
49
+ case 'boolean':
50
+ return zod_1.z.boolean();
51
+ case 'array':
52
+ return zod_1.z.array(prop.items ? propToZod(prop.items) : zod_1.z.unknown());
53
+ default:
54
+ return zod_1.z.unknown();
55
+ }
56
+ }
57
+ //# sourceMappingURL=jsonSchemaToZod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonSchemaToZod.js","sourceRoot":"","sources":["../../src/registry/jsonSchemaToZod.ts"],"names":[],"mappings":";;AA6BA,oDAeC;AA5CD,6BAAwB;AAoBxB;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CAClC,MAA+B;IAE/B,MAAM,GAAG,GAAG,MAAsC,CAAC;IACnD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrD,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAAqB;IACtC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,OAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,OAAO,OAAC,CAAC,IAAI,CAAC,MAA+B,CAAC,CAAC;YACjD,CAAC;YACD,OAAO,OAAC,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;YAChE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;gBAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;gBAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,OAAC,CAAC,OAAO,EAAE,CAAC;QACrB,KAAK,OAAO;YACV,OAAO,OAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE;YACE,OAAO,OAAC,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}