@mcp-abap-adt/calm-server 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/README.md +48 -25
- package/dist/bin/stdio.js +9 -6
- package/dist/bin/stdio.js.map +1 -1
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js +7 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/runStdio.d.ts +2 -4
- package/dist/server/runStdio.d.ts.map +1 -1
- package/dist/server/runStdio.js +15 -5
- package/dist/server/runStdio.js.map +1 -1
- package/dist/server/stderrLogger.d.ts +24 -0
- package/dist/server/stderrLogger.d.ts.map +1 -0
- package/dist/server/stderrLogger.js +44 -0
- package/dist/server/stderrLogger.js.map +1 -0
- package/dist/tools/documents/createDocument.d.ts +5 -0
- package/dist/tools/documents/createDocument.d.ts.map +1 -0
- package/dist/tools/documents/createDocument.js +48 -0
- package/dist/tools/documents/createDocument.js.map +1 -0
- package/dist/tools/documents/deleteDocument.d.ts +10 -0
- package/dist/tools/documents/deleteDocument.d.ts.map +1 -0
- package/dist/tools/documents/deleteDocument.js +35 -0
- package/dist/tools/documents/deleteDocument.js.map +1 -0
- package/dist/tools/documents/index.d.ts +10 -0
- package/dist/tools/documents/index.d.ts.map +1 -1
- package/dist/tools/documents/index.js +21 -1
- package/dist/tools/documents/index.js.map +1 -1
- package/dist/tools/documents/listDocumentStatuses.d.ts +7 -0
- package/dist/tools/documents/listDocumentStatuses.d.ts.map +1 -0
- package/dist/tools/documents/listDocumentStatuses.js +23 -0
- package/dist/tools/documents/listDocumentStatuses.js.map +1 -0
- package/dist/tools/documents/listDocumentTypes.d.ts +7 -0
- package/dist/tools/documents/listDocumentTypes.d.ts.map +1 -0
- package/dist/tools/documents/listDocumentTypes.js +23 -0
- package/dist/tools/documents/listDocumentTypes.js.map +1 -0
- package/dist/tools/documents/updateDocument.d.ts +7 -0
- package/dist/tools/documents/updateDocument.d.ts.map +1 -0
- package/dist/tools/documents/updateDocument.js +43 -0
- package/dist/tools/documents/updateDocument.js.map +1 -0
- package/dist/tools/features/createExternalReference.d.ts +5 -0
- package/dist/tools/features/createExternalReference.d.ts.map +1 -0
- package/dist/tools/features/createExternalReference.js +49 -0
- package/dist/tools/features/createExternalReference.js.map +1 -0
- package/dist/tools/features/deleteExternalReference.d.ts +12 -0
- package/dist/tools/features/deleteExternalReference.d.ts.map +1 -0
- package/dist/tools/features/deleteExternalReference.js +44 -0
- package/dist/tools/features/deleteExternalReference.js.map +1 -0
- package/dist/tools/features/index.d.ts +6 -0
- package/dist/tools/features/index.d.ts.map +1 -1
- package/dist/tools/features/index.js +13 -1
- package/dist/tools/features/index.js.map +1 -1
- package/dist/tools/features/listExternalReferences.d.ts +11 -0
- package/dist/tools/features/listExternalReferences.d.ts.map +1 -0
- package/dist/tools/features/listExternalReferences.js +47 -0
- package/dist/tools/features/listExternalReferences.js.map +1 -0
- package/dist/tools/hierarchy/createHierarchyNode.d.ts +5 -0
- package/dist/tools/hierarchy/createHierarchyNode.d.ts.map +1 -0
- package/dist/tools/hierarchy/createHierarchyNode.js +46 -0
- package/dist/tools/hierarchy/createHierarchyNode.js.map +1 -0
- package/dist/tools/hierarchy/deleteHierarchyNode.d.ts +10 -0
- package/dist/tools/hierarchy/deleteHierarchyNode.d.ts.map +1 -0
- package/dist/tools/hierarchy/deleteHierarchyNode.js +35 -0
- package/dist/tools/hierarchy/deleteHierarchyNode.js.map +1 -0
- package/dist/tools/hierarchy/index.d.ts +6 -0
- package/dist/tools/hierarchy/index.d.ts.map +1 -1
- package/dist/tools/hierarchy/index.js +13 -1
- package/dist/tools/hierarchy/index.js.map +1 -1
- package/dist/tools/hierarchy/listHierarchy.d.ts.map +1 -1
- package/dist/tools/hierarchy/listHierarchy.js +4 -2
- package/dist/tools/hierarchy/listHierarchy.js.map +1 -1
- package/dist/tools/hierarchy/updateHierarchyNode.d.ts +7 -0
- package/dist/tools/hierarchy/updateHierarchyNode.d.ts.map +1 -0
- package/dist/tools/hierarchy/updateHierarchyNode.js +38 -0
- package/dist/tools/hierarchy/updateHierarchyNode.js.map +1 -0
- package/dist/tools/logs/index.d.ts +2 -0
- package/dist/tools/logs/index.d.ts.map +1 -1
- package/dist/tools/logs/index.js +8 -2
- package/dist/tools/logs/index.js.map +1 -1
- package/dist/tools/logs/postLogs.d.ts +10 -0
- package/dist/tools/logs/postLogs.d.ts.map +1 -0
- package/dist/tools/logs/postLogs.js +58 -0
- package/dist/tools/logs/postLogs.js.map +1 -0
- package/dist/tools/projects/createProject.d.ts +5 -0
- package/dist/tools/projects/createProject.d.ts.map +1 -0
- package/dist/tools/projects/createProject.js +42 -0
- package/dist/tools/projects/createProject.js.map +1 -0
- package/dist/tools/projects/getProgram.d.ts +7 -0
- package/dist/tools/projects/getProgram.d.ts.map +1 -0
- package/dist/tools/projects/getProgram.js +32 -0
- package/dist/tools/projects/getProgram.js.map +1 -0
- package/dist/tools/projects/index.d.ts +10 -0
- package/dist/tools/projects/index.d.ts.map +1 -1
- package/dist/tools/projects/index.js +21 -1
- package/dist/tools/projects/index.js.map +1 -1
- package/dist/tools/projects/listPrograms.d.ts +10 -0
- package/dist/tools/projects/listPrograms.d.ts.map +1 -0
- package/dist/tools/projects/listPrograms.js +36 -0
- package/dist/tools/projects/listPrograms.js.map +1 -0
- package/dist/tools/projects/listTeamMembers.d.ts +11 -0
- package/dist/tools/projects/listTeamMembers.d.ts.map +1 -0
- package/dist/tools/projects/listTeamMembers.js +49 -0
- package/dist/tools/projects/listTeamMembers.js.map +1 -0
- package/dist/tools/projects/listTimeboxes.d.ts +11 -0
- package/dist/tools/projects/listTimeboxes.d.ts.map +1 -0
- package/dist/tools/projects/listTimeboxes.js +49 -0
- package/dist/tools/projects/listTimeboxes.js.map +1 -0
- package/dist/tools/tasks/createTask.d.ts +5 -0
- package/dist/tools/tasks/createTask.d.ts.map +1 -0
- package/dist/tools/tasks/createTask.js +58 -0
- package/dist/tools/tasks/createTask.js.map +1 -0
- package/dist/tools/tasks/createTaskComment.d.ts +7 -0
- package/dist/tools/tasks/createTaskComment.d.ts.map +1 -0
- package/dist/tools/tasks/createTaskComment.js +36 -0
- package/dist/tools/tasks/createTaskComment.js.map +1 -0
- package/dist/tools/tasks/deleteTask.d.ts +10 -0
- package/dist/tools/tasks/deleteTask.d.ts.map +1 -0
- package/dist/tools/tasks/deleteTask.js +35 -0
- package/dist/tools/tasks/deleteTask.js.map +1 -0
- package/dist/tools/tasks/index.d.ts +14 -0
- package/dist/tools/tasks/index.d.ts.map +1 -1
- package/dist/tools/tasks/index.js +29 -1
- package/dist/tools/tasks/index.js.map +1 -1
- package/dist/tools/tasks/listDeliverables.d.ts +11 -0
- package/dist/tools/tasks/listDeliverables.d.ts.map +1 -0
- package/dist/tools/tasks/listDeliverables.js +42 -0
- package/dist/tools/tasks/listDeliverables.js.map +1 -0
- package/dist/tools/tasks/listTaskReferences.d.ts +11 -0
- package/dist/tools/tasks/listTaskReferences.d.ts.map +1 -0
- package/dist/tools/tasks/listTaskReferences.js +46 -0
- package/dist/tools/tasks/listTaskReferences.js.map +1 -0
- package/dist/tools/tasks/listWorkstreams.d.ts +11 -0
- package/dist/tools/tasks/listWorkstreams.d.ts.map +1 -0
- package/dist/tools/tasks/listWorkstreams.js +42 -0
- package/dist/tools/tasks/listWorkstreams.js.map +1 -0
- package/dist/tools/tasks/updateTask.d.ts +7 -0
- package/dist/tools/tasks/updateTask.d.ts.map +1 -0
- package/dist/tools/tasks/updateTask.js +44 -0
- package/dist/tools/tasks/updateTask.js.map +1 -0
- package/dist/tools/testCases/createTestAction.d.ts +5 -0
- package/dist/tools/testCases/createTestAction.d.ts.map +1 -0
- package/dist/tools/testCases/createTestAction.js +54 -0
- package/dist/tools/testCases/createTestAction.js.map +1 -0
- package/dist/tools/testCases/createTestActivity.d.ts +5 -0
- package/dist/tools/testCases/createTestActivity.d.ts.map +1 -0
- package/dist/tools/testCases/createTestActivity.js +46 -0
- package/dist/tools/testCases/createTestActivity.js.map +1 -0
- package/dist/tools/testCases/createTestCase.d.ts +5 -0
- package/dist/tools/testCases/createTestCase.d.ts.map +1 -0
- package/dist/tools/testCases/createTestCase.js +42 -0
- package/dist/tools/testCases/createTestCase.js.map +1 -0
- package/dist/tools/testCases/deleteTestCase.d.ts +10 -0
- package/dist/tools/testCases/deleteTestCase.d.ts.map +1 -0
- package/dist/tools/testCases/deleteTestCase.js +35 -0
- package/dist/tools/testCases/deleteTestCase.js.map +1 -0
- package/dist/tools/testCases/index.d.ts +14 -0
- package/dist/tools/testCases/index.d.ts.map +1 -1
- package/dist/tools/testCases/index.js +29 -1
- package/dist/tools/testCases/index.js.map +1 -1
- package/dist/tools/testCases/listTestActions.d.ts +11 -0
- package/dist/tools/testCases/listTestActions.d.ts.map +1 -0
- package/dist/tools/testCases/listTestActions.js +45 -0
- package/dist/tools/testCases/listTestActions.js.map +1 -0
- package/dist/tools/testCases/listTestActivities.d.ts +11 -0
- package/dist/tools/testCases/listTestActivities.d.ts.map +1 -0
- package/dist/tools/testCases/listTestActivities.js +45 -0
- package/dist/tools/testCases/listTestActivities.js.map +1 -0
- package/dist/tools/testCases/listTestCases.d.ts.map +1 -1
- package/dist/tools/testCases/listTestCases.js +5 -7
- package/dist/tools/testCases/listTestCases.js.map +1 -1
- package/dist/tools/testCases/updateTestCase.d.ts +7 -0
- package/dist/tools/testCases/updateTestCase.d.ts.map +1 -0
- package/dist/tools/testCases/updateTestCase.js +38 -0
- package/dist/tools/testCases/updateTestCase.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — 2026-05-13
|
|
4
|
+
|
|
5
|
+
Parity with the consetto-Rust port plus a wider bonus surface, live
|
|
6
|
+
integration coverage, and a logger that is safe to use under MCP
|
|
7
|
+
stdio. **54 tools** (was 23), **232 tests** (was 103), full build
|
|
8
|
+
green.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Tasks CRUD (M7)** — `create`, `update`, `delete`, `create_comment`.
|
|
13
|
+
- **TestCases CRUD (M8)** — `create`, `update`, `delete`, plus nested
|
|
14
|
+
`create_activity` / `create_action`.
|
|
15
|
+
- **Documents CRUD (M9)** — `create`, `update`, `delete`.
|
|
16
|
+
- **Hierarchy CRUD (M10)** — `create_node`, `update_node`,
|
|
17
|
+
`delete_node`.
|
|
18
|
+
- **Feature external references (M11)** —
|
|
19
|
+
`create_external_reference`, `delete_external_reference`.
|
|
20
|
+
- **Projects writes (M12)** — `create`.
|
|
21
|
+
- **Logs writes (M13)** — `post` (OpenTelemetry-style record
|
|
22
|
+
ingestion).
|
|
23
|
+
- **Bonus read tools (M16, +12)** — surface every read method already
|
|
24
|
+
in `calm-client` that consetto-Rust does not expose:
|
|
25
|
+
- `documents.list_statuses`, `documents.list_types`
|
|
26
|
+
- `projects.list_programs`, `projects.get_program`,
|
|
27
|
+
`projects.list_team_members`, `projects.list_timeboxes`
|
|
28
|
+
- `features.list_external_references`
|
|
29
|
+
- `tasks.list_deliverables`, `tasks.list_workstreams`,
|
|
30
|
+
`tasks.list_references`
|
|
31
|
+
- `testCases.list_activities`, `testCases.list_actions`
|
|
32
|
+
- **Integration test suite (M14)** under
|
|
33
|
+
`src/__tests__/integration/*.sandbox.test.ts` — one file per service,
|
|
34
|
+
gated on env, runs against the SAP sandbox in CI.
|
|
35
|
+
- **Live OAuth2 gates (M17)** —
|
|
36
|
+
`describeWhenLive`, `describeOAuth2`, `describeMutating` alongside
|
|
37
|
+
the existing sandbox gates. Mutation tests are opt-in via
|
|
38
|
+
`CALM_ALLOW_MUTATIONS=1` and always finalise via
|
|
39
|
+
`try/finally { delete }`.
|
|
40
|
+
- **`StderrLogger` (M15)** — minimal `ILogger` that routes every level
|
|
41
|
+
to stderr. Wired into `runStdio` so the bin emits lifecycle events
|
|
42
|
+
(start, transport bound, shutdown) without ever touching stdout
|
|
43
|
+
(which MCP-stdio reserves for the JSON-RPC frame stream). The
|
|
44
|
+
family's `PinoLogger` / `DefaultLogger` write `info`/`debug` to
|
|
45
|
+
stdout by default — using either inside a stdio MCP server would
|
|
46
|
+
corrupt every call.
|
|
47
|
+
- **`scripts/smoke-sandbox.mjs`** — 30-second smoke check: spawns the
|
|
48
|
+
stdio bin, lists tools, exercises a handful of read endpoints,
|
|
49
|
+
exits non-zero on any unexpected failure.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- `list_hierarchy` and `list_test_cases` no longer ship sandbox-
|
|
54
|
+
incompatible properties in their default `$select`. The sandbox
|
|
55
|
+
OData type does not expose `parentNodeUuid` / `rootNodeUuid` on
|
|
56
|
+
`HierarchyNodes`, nor `statusCode` on `ManualTestCases`; defaults
|
|
57
|
+
returned 400 against the sandbox. Removed from `DEFAULT_FIELDS`;
|
|
58
|
+
callers can still opt in via `fields: [...]` against a tenant that
|
|
59
|
+
exposes them.
|
|
60
|
+
- `config.loadEnv` no longer reads the cwd-level `.env` under Jest.
|
|
61
|
+
The config-unit suite assumes a clean env; a developer's local
|
|
62
|
+
sandbox `.env` was silently leaking into it. Smoke scripts and the
|
|
63
|
+
stdio bin load `.env` explicitly via `dotenv` themselves.
|
|
64
|
+
|
|
65
|
+
### Notes
|
|
66
|
+
|
|
67
|
+
- All HTTP / OData work lives in `@mcp-abap-adt/calm-client`. This
|
|
68
|
+
package is pure tool-shim: JSON Schema, args validation, error
|
|
69
|
+
mapping. The 19 new mutation tools added in M7–M13 required *zero*
|
|
70
|
+
changes to the client.
|
|
71
|
+
- Mutations against the shared SAP sandbox at `api.sap.com` are
|
|
72
|
+
intentionally not exercised by `npm test`; reachability is verified
|
|
73
|
+
via each tool's `INVALID_ARGUMENT` guard. Real ingestion happens
|
|
74
|
+
only under `describeMutating` on an opt-in live backend.
|
|
75
|
+
|
|
3
76
|
## 0.1.0 — 2026-04-24
|
|
4
77
|
|
|
5
78
|
First usable release. 23 MCP tools covering all 9 Cloud ALM services,
|
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
MCP server for **SAP Cloud ALM**, built on
|
|
6
6
|
[`@mcp-abap-adt/calm-client`](https://github.com/fr0ster/mcp-calm-client).
|
|
7
|
-
Ships
|
|
8
|
-
|
|
7
|
+
Ships **54 MCP tools** covering all 9 Cloud ALM services — full CRUD
|
|
8
|
+
where the service supports it, plus a wide read surface — with rich
|
|
9
|
+
JSON Schema descriptions that let an LLM plan multi-step workflows.
|
|
9
10
|
|
|
10
11
|
This package is **dual-purpose**:
|
|
11
12
|
|
|
@@ -17,9 +18,10 @@ This package is **dual-purpose**:
|
|
|
17
18
|
|
|
18
19
|
## Status
|
|
19
20
|
|
|
20
|
-
**0.
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
**0.2.0** — 54 tools, 232 tests (224 unit + integration, 7 env-gated
|
|
22
|
+
skips, 1 todo), full build green. Integration suite runs live against
|
|
23
|
+
the SAP sandbox (api.sap.com) or any OAuth2 Cloud ALM tenant with a
|
|
24
|
+
single `.env` switch; gates skip cleanly when no backend is wired.
|
|
23
25
|
|
|
24
26
|
## Installation
|
|
25
27
|
|
|
@@ -101,7 +103,7 @@ on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
|
|
|
101
103
|
}
|
|
102
104
|
```
|
|
103
105
|
|
|
104
|
-
Restart Claude Desktop; the
|
|
106
|
+
Restart Claude Desktop; the 54 `calm_*` tools become available to the
|
|
105
107
|
model.
|
|
106
108
|
|
|
107
109
|
## Library: composing into another MCP server
|
|
@@ -145,19 +147,19 @@ import { ALL_GROUPS } from '@mcp-abap-adt/calm-server/tools';
|
|
|
145
147
|
import { CalmToolRegistry } from '@mcp-abap-adt/calm-server/registry';
|
|
146
148
|
```
|
|
147
149
|
|
|
148
|
-
## Tool surface (
|
|
150
|
+
## Tool surface (54 tools across 9 services)
|
|
149
151
|
|
|
150
152
|
| Service | Tools |
|
|
151
153
|
|---|---|
|
|
152
|
-
| **Features** (
|
|
153
|
-
| **
|
|
154
|
-
| **TestCases** (
|
|
155
|
-
| **
|
|
154
|
+
| **Features** (11) | `list`, `get`, `get_by_display_id`, `create`, `update`, `delete`, `create_external_reference`, `delete_external_reference`, `list_external_references`, `list_statuses`, `list_priorities` |
|
|
155
|
+
| **Tasks** (10) | `list`, `get`, `create`, `update`, `delete`, `list_comments`, `create_comment`, `list_references`, `list_deliverables`, `list_workstreams` |
|
|
156
|
+
| **TestCases** (9) | `list`, `get`, `create`, `update`, `delete`, `create_activity`, `create_action`, `list_activities`, `list_actions` |
|
|
157
|
+
| **Documents** (7) | `list`, `get`, `create`, `update`, `delete`, `list_statuses`, `list_types` |
|
|
158
|
+
| **Projects** (7) | `list`, `get`, `create`, `list_programs`, `get_program`, `list_team_members`, `list_timeboxes` |
|
|
159
|
+
| **Hierarchy** (5) | `list`, `get_with_children`, `create_node`, `update_node`, `delete_node` |
|
|
156
160
|
| **Analytics** (2, read-only) | `query` (17 endpoints), `list_providers` (static catalog) |
|
|
161
|
+
| **Logs** (2, domain-specific REST) | `get` (provider + serviceId + time window), `post` (inbound log records) |
|
|
157
162
|
| **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
163
|
|
|
162
164
|
Every MCP tool:
|
|
163
165
|
- Has a full JSON Schema with descriptions — the LLM reads these to plan.
|
|
@@ -173,11 +175,20 @@ See `src/tools/<service>/*.ts` for per-tool argument schemas.
|
|
|
173
175
|
|
|
174
176
|
## Destructive tools (write operations)
|
|
175
177
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
Every Cloud ALM service that supports writes is now exposed:
|
|
179
|
+
|
|
180
|
+
- **Features**: `create`, `update`, `delete`, plus external-reference
|
|
181
|
+
`create` / `delete`
|
|
182
|
+
- **Tasks**: `create`, `update`, `delete`, `create_comment`
|
|
183
|
+
- **TestCases**: `create`, `update`, `delete`, plus nested
|
|
184
|
+
`create_activity` / `create_action`
|
|
185
|
+
- **Documents**: `create`, `update`, `delete`
|
|
186
|
+
- **Hierarchy**: `create_node`, `update_node`, `delete_node`
|
|
187
|
+
- **Projects**: `create`
|
|
188
|
+
- **Logs**: `post` (inbound OpenTelemetry-style record ingestion)
|
|
189
|
+
|
|
190
|
+
The shared SAP sandbox at `api.sap.com` is read-friendly only — mutation
|
|
191
|
+
integration tests are opt-in (see Live-tenant integration below).
|
|
181
192
|
|
|
182
193
|
## Debug logging
|
|
183
194
|
|
|
@@ -197,16 +208,28 @@ git clone git@github.com:fr0ster/mcp-calm-server.git
|
|
|
197
208
|
cd mcp-calm-server
|
|
198
209
|
npm install
|
|
199
210
|
|
|
200
|
-
npm run test #
|
|
211
|
+
npm run test # 224 unit + integration tests
|
|
201
212
|
npm run build # emits dist/, includes executable bin
|
|
202
213
|
npm run lint:check # biome
|
|
203
214
|
```
|
|
204
215
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
### Live-tenant integration
|
|
217
|
+
|
|
218
|
+
`src/__tests__/integration/` runs against a real backend when env is
|
|
219
|
+
present, and skips cleanly when it isn't (so `npm test` without secrets
|
|
220
|
+
is always green). Five gates, drop them into `.env`:
|
|
221
|
+
|
|
222
|
+
| Gate | Env trigger | What it unlocks |
|
|
223
|
+
|---|---|---|
|
|
224
|
+
| `describeSandbox` | `CALM_MODE=sandbox` + `CALM_API_KEY` | The `api.sap.com` sandbox |
|
|
225
|
+
| `describeOAuth2` | `CALM_MODE=oauth2` + `CALM_BASE_URL` + 3× UAA env | Live tenant (incl. endpoints absent from the sandbox catalog, e.g. Business Processes) |
|
|
226
|
+
| `describeWhenLive` | either of the above | Read-side tests that work in either mode |
|
|
227
|
+
| `describeWithProject` | live backend + `CALM_PROJECT_ID` | Project-scoped chains (features list→get, tasks list→get→comments, …) |
|
|
228
|
+
| `describeMutating` | live + `CALM_PROJECT_ID` + `CALM_ALLOW_MUTATIONS=1` | Write tests (every mutation finalises via `try/finally { delete }`) |
|
|
229
|
+
|
|
230
|
+
A quick smoke script lives at `scripts/smoke-sandbox.mjs` — spawns the
|
|
231
|
+
stdio bin, lists tools, calls a handful of read endpoints, and exits
|
|
232
|
+
1 on any non-skip failure.
|
|
210
233
|
|
|
211
234
|
## License
|
|
212
235
|
|
package/dist/bin/stdio.js
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const runStdio_1 = require("../server/runStdio");
|
|
5
|
+
const stderrLogger_1 = require("../server/stderrLogger");
|
|
5
6
|
(0, runStdio_1.runStdio)().catch((err) => {
|
|
7
|
+
// runStdio() may fail before its own logger is wired (config throws,
|
|
8
|
+
// missing env, etc.), so the catch block keeps a separate logger.
|
|
9
|
+
// StderrLogger guarantees we never write to stdout — keeping the
|
|
10
|
+
// MCP-stdio contract intact even on startup failure.
|
|
11
|
+
const logger = new stderrLogger_1.StderrLogger();
|
|
6
12
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (err instanceof Error && err.stack) {
|
|
11
|
-
process.stderr.write(`${err.stack}\n`);
|
|
12
|
-
}
|
|
13
|
+
logger.error(`[calm-mcp] startup failed: ${msg}`, {
|
|
14
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
15
|
+
});
|
|
13
16
|
process.exit(1);
|
|
14
17
|
});
|
|
15
18
|
//# sourceMappingURL=stdio.js.map
|
package/dist/bin/stdio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/bin/stdio.ts"],"names":[],"mappings":";;;AACA,iDAA8C;
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/bin/stdio.ts"],"names":[],"mappings":";;;AACA,iDAA8C;AAC9C,yDAAsD;AAEtD,IAAA,mBAAQ,GAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAChC,qEAAqE;IACrE,kEAAkE;IAClE,iEAAiE;IACjE,qDAAqD;IACrD,MAAM,MAAM,GAAG,IAAI,2BAAY,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,EAAE;QAChD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KACpD,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAU9B;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAYD,wBAAgB,UAAU,IAAI,iBAAiB,CAkC9C"}
|
package/dist/server/config.js
CHANGED
|
@@ -14,10 +14,16 @@ let loaded = false;
|
|
|
14
14
|
function loadEnv() {
|
|
15
15
|
if (loaded)
|
|
16
16
|
return;
|
|
17
|
+
loaded = true;
|
|
18
|
+
// Under Jest, never auto-load a cwd-level .env: unit tests assert on
|
|
19
|
+
// the absence of CALM_* vars, and a developer's local sandbox .env
|
|
20
|
+
// would otherwise leak into that suite and make assertions flaky.
|
|
21
|
+
// Smoke scripts and the stdio bin explicitly call dotenvConfig themselves.
|
|
22
|
+
if (process.env.JEST_WORKER_ID)
|
|
23
|
+
return;
|
|
17
24
|
const path = (0, node_path_1.resolve)(process.cwd(), '.env');
|
|
18
25
|
if ((0, node_fs_1.existsSync)(path))
|
|
19
26
|
(0, dotenv_1.config)({ path });
|
|
20
|
-
loaded = true;
|
|
21
27
|
}
|
|
22
28
|
function required(name) {
|
|
23
29
|
const v = process.env[name];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":";;AAWA,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":";;AAWA,0BAUC;AAwBD,gCAkCC;AA/ED,qCAAqC;AACrC,yCAAoC;AACpC,mCAAgD;AAEhD,IAAI,MAAM,GAAG,KAAK,CAAC;AAEnB;;;;GAIG;AACH,SAAgB,OAAO;IACrB,IAAI,MAAM;QAAE,OAAO;IACnB,MAAM,GAAG,IAAI,CAAC;IACd,qEAAqE;IACrE,mEAAmE;IACnE,kEAAkE;IAClE,2EAA2E;IAC3E,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO;IACvC,MAAM,IAAI,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,IAAA,oBAAU,EAAC,IAAI,CAAC;QAAE,IAAA,eAAY,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAcD,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,6CAA6C,CACxE,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,EAAE,CAAC;IACV,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAElC,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY;QACxC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAClC,CAAC,CAAC,MAAM,CAAC;IAEX,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;YAClC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC;YAChC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC;YAC3C,eAAe,EAAE,QAAQ,CAAC,wBAAwB,CAAC;YACnD,SAAS;SACV,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,IAAI;YACJ,OAAO,EACL,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,qCAAqC;YACpE,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC;YAChC,SAAS;SACV,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,GAAG,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
* builds a `CalmClient`, wires all tool groups onto a
|
|
4
4
|
* `BaseCalmMcpServer`, and binds the server to the stdio transport.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* of a silent hang. On success, stdio takes over — no console output
|
|
9
|
-
* from the server.
|
|
6
|
+
* Logging goes through `StderrLogger` — never stdout — because MCP
|
|
7
|
+
* stdio reserves stdout for the JSON-RPC protocol stream.
|
|
10
8
|
*/
|
|
11
9
|
export declare function runStdio(): Promise<void>;
|
|
12
10
|
//# sourceMappingURL=runStdio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runStdio.d.ts","sourceRoot":"","sources":["../../src/server/runStdio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runStdio.d.ts","sourceRoot":"","sources":["../../src/server/runStdio.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAwC9C"}
|
package/dist/server/runStdio.js
CHANGED
|
@@ -6,35 +6,45 @@ const tools_1 = require("../tools");
|
|
|
6
6
|
const BaseCalmMcpServer_1 = require("./BaseCalmMcpServer");
|
|
7
7
|
const buildClient_1 = require("./buildClient");
|
|
8
8
|
const config_1 = require("./config");
|
|
9
|
+
const stderrLogger_1 = require("./stderrLogger");
|
|
9
10
|
const PACKAGE_NAME = '@mcp-abap-adt/calm-server';
|
|
10
|
-
const PACKAGE_VERSION = '0.0
|
|
11
|
+
const PACKAGE_VERSION = '0.2.0';
|
|
11
12
|
/**
|
|
12
13
|
* Entry point for standalone stdio mode. Reads `.env` + env vars,
|
|
13
14
|
* builds a `CalmClient`, wires all tool groups onto a
|
|
14
15
|
* `BaseCalmMcpServer`, and binds the server to the stdio transport.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* of a silent hang. On success, stdio takes over — no console output
|
|
19
|
-
* from the server.
|
|
17
|
+
* Logging goes through `StderrLogger` — never stdout — because MCP
|
|
18
|
+
* stdio reserves stdout for the JSON-RPC protocol stream.
|
|
20
19
|
*/
|
|
21
20
|
async function runStdio() {
|
|
21
|
+
const logger = new stderrLogger_1.StderrLogger();
|
|
22
22
|
const config = (0, config_1.readConfig)();
|
|
23
23
|
const calm = (0, buildClient_1.buildCalmClient)(config);
|
|
24
24
|
const server = new BaseCalmMcpServer_1.BaseCalmMcpServer({
|
|
25
25
|
name: PACKAGE_NAME,
|
|
26
26
|
version: PACKAGE_VERSION,
|
|
27
27
|
calm,
|
|
28
|
+
logger,
|
|
28
29
|
groups: [...tools_1.ALL_GROUPS],
|
|
29
30
|
});
|
|
31
|
+
logger.info('calm-mcp starting', {
|
|
32
|
+
package: PACKAGE_NAME,
|
|
33
|
+
version: PACKAGE_VERSION,
|
|
34
|
+
mode: config.mode,
|
|
35
|
+
baseUrl: config.baseUrl,
|
|
36
|
+
tools: server.listRegisteredTools().length,
|
|
37
|
+
});
|
|
30
38
|
// Best-effort early token / connectivity probe so misconfiguration
|
|
31
39
|
// surfaces on startup rather than on the first tool call.
|
|
32
40
|
await calm.getConnection().connect();
|
|
33
41
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
34
42
|
await server.connect(transport);
|
|
43
|
+
logger.info('calm-mcp transport bound (stdio)');
|
|
35
44
|
// Graceful shutdown on SIGINT / SIGTERM — ensures stdio is cleanly
|
|
36
45
|
// closed so the host does not see a dangling child process.
|
|
37
46
|
const shutdown = async () => {
|
|
47
|
+
logger.info('calm-mcp shutdown signal received');
|
|
38
48
|
try {
|
|
39
49
|
await server.close();
|
|
40
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runStdio.js","sourceRoot":"","sources":["../../src/server/runStdio.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"runStdio.js","sourceRoot":"","sources":["../../src/server/runStdio.ts"],"names":[],"mappings":";;AAkBA,4BAwCC;AA1DD,wEAAiF;AACjF,oCAAsC;AACtC,2DAAwD;AACxD,+CAAgD;AAChD,qCAAsC;AACtC,iDAA8C;AAE9C,MAAM,YAAY,GAAG,2BAA2B,CAAC;AACjD,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC;;;;;;;GAOG;AACI,KAAK,UAAU,QAAQ;IAC5B,MAAM,MAAM,GAAG,IAAI,2BAAY,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAA,6BAAe,EAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,qCAAiB,CAAC;QACnC,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,eAAe;QACxB,IAAI;QACJ,MAAM;QACN,MAAM,EAAE,CAAC,GAAG,kBAAU,CAAC;KACxB,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;QAC/B,OAAO,EAAE,YAAY;QACrB,OAAO,EAAE,eAAe;QACxB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,mBAAmB,EAAE,CAAC,MAAM;KAC3C,CAAC,CAAC;IAEH,mEAAmE;IACnE,0DAA0D;IAC1D,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;IAErC,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAEhD,mEAAmE;IACnE,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,KAAK,IAAmB,EAAE;QACzC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ILogger } from '@mcp-abap-adt/interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal `ILogger` that writes every level to **stderr only**.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the MCP **stdio** transport reserves stdout for the
|
|
6
|
+
* JSON-RPC protocol stream. Any byte written to stdout that is not a
|
|
7
|
+
* valid MCP frame breaks the connection. Both the family's
|
|
8
|
+
* `DefaultLogger` and `PinoLogger` write `info`/`debug` to stdout by
|
|
9
|
+
* default — using them inside a stdio MCP server would corrupt the
|
|
10
|
+
* stream. This logger sidesteps that by sending every message to
|
|
11
|
+
* fd=2.
|
|
12
|
+
*
|
|
13
|
+
* Library consumers that wire `BaseCalmMcpServer` over a non-stdio
|
|
14
|
+
* transport (HTTP, custom) should bring their own logger — they don't
|
|
15
|
+
* have the stdout-collision concern.
|
|
16
|
+
*/
|
|
17
|
+
export declare class StderrLogger implements ILogger {
|
|
18
|
+
private write;
|
|
19
|
+
info(message: string, meta?: unknown): void;
|
|
20
|
+
warn(message: string, meta?: unknown): void;
|
|
21
|
+
error(message: string, meta?: unknown): void;
|
|
22
|
+
debug(message: string, meta?: unknown): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=stderrLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stderrLogger.d.ts","sourceRoot":"","sources":["../../src/server/stderrLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,OAAO;IAC1C,OAAO,CAAC,KAAK;IAQb,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;CAI7C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StderrLogger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Minimal `ILogger` that writes every level to **stderr only**.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists: the MCP **stdio** transport reserves stdout for the
|
|
8
|
+
* JSON-RPC protocol stream. Any byte written to stdout that is not a
|
|
9
|
+
* valid MCP frame breaks the connection. Both the family's
|
|
10
|
+
* `DefaultLogger` and `PinoLogger` write `info`/`debug` to stdout by
|
|
11
|
+
* default — using them inside a stdio MCP server would corrupt the
|
|
12
|
+
* stream. This logger sidesteps that by sending every message to
|
|
13
|
+
* fd=2.
|
|
14
|
+
*
|
|
15
|
+
* Library consumers that wire `BaseCalmMcpServer` over a non-stdio
|
|
16
|
+
* transport (HTTP, custom) should bring their own logger — they don't
|
|
17
|
+
* have the stdout-collision concern.
|
|
18
|
+
*/
|
|
19
|
+
class StderrLogger {
|
|
20
|
+
write(prefix, message, meta) {
|
|
21
|
+
if (meta !== undefined) {
|
|
22
|
+
process.stderr.write(`${prefix} ${message} ${JSON.stringify(meta)}\n`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
process.stderr.write(`${prefix} ${message}\n`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
info(message, meta) {
|
|
29
|
+
this.write('[INFO]', message, meta);
|
|
30
|
+
}
|
|
31
|
+
warn(message, meta) {
|
|
32
|
+
this.write('[WARN]', message, meta);
|
|
33
|
+
}
|
|
34
|
+
error(message, meta) {
|
|
35
|
+
this.write('[ERROR]', message, meta);
|
|
36
|
+
}
|
|
37
|
+
debug(message, meta) {
|
|
38
|
+
if (process.env.CALM_LOG_LEVEL?.toLowerCase() !== 'debug')
|
|
39
|
+
return;
|
|
40
|
+
this.write('[DEBUG]', message, meta);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.StderrLogger = StderrLogger;
|
|
44
|
+
//# sourceMappingURL=stderrLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stderrLogger.js","sourceRoot":"","sources":["../../src/server/stderrLogger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAa,YAAY;IACf,KAAK,CAAC,MAAc,EAAE,OAAe,EAAE,IAAc;QAC3D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAc;QAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAc;QAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAc;QACnC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAc;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,KAAK,OAAO;YAAE,OAAO;QAClE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;CACF;AAzBD,oCAyBC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ICreateDocumentParams, IDocument } from '@mcp-abap-adt/calm-client';
|
|
2
|
+
import type { ICalmHandlerEntry } from '../../registry/types';
|
|
3
|
+
export type ICreateDocumentArgs = ICreateDocumentParams;
|
|
4
|
+
export declare const createDocumentTool: ICalmHandlerEntry<ICreateDocumentArgs, IDocument>;
|
|
5
|
+
//# sourceMappingURL=createDocument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createDocument.d.ts","sourceRoot":"","sources":["../../../src/tools/documents/createDocument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,SAAS,EACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AA8CxD,eAAO,MAAM,kBAAkB,EAAE,iBAAiB,CAChD,mBAAmB,EACnB,SAAS,CAIV,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDocumentTool = void 0;
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
const definition = {
|
|
6
|
+
name: 'calm_documents_create',
|
|
7
|
+
description: 'Create a new Cloud ALM document. Destructive. Requires `title`; other fields are optional. NOTE the write-side field is `typeCode` (read-side returns `documentTypeCode`). Returns the newly created document.',
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
required: ['title'],
|
|
11
|
+
properties: {
|
|
12
|
+
title: { type: 'string', description: 'Document title.' },
|
|
13
|
+
content: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
description: 'Optional document body (markdown or plain text).',
|
|
16
|
+
},
|
|
17
|
+
projectId: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Optional project scope.',
|
|
20
|
+
},
|
|
21
|
+
typeCode: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'Document type code (write-side spelling).',
|
|
24
|
+
},
|
|
25
|
+
statusCode: { type: 'string', description: 'Optional starting status.' },
|
|
26
|
+
priorityCode: { type: 'string', description: 'Optional priority.' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const handler = async (ctx, args) => {
|
|
31
|
+
if (!args?.title) {
|
|
32
|
+
throw new utils_1.CalmToolError({
|
|
33
|
+
code: 'INVALID_ARGUMENT',
|
|
34
|
+
message: 'title is required',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return await ctx.calm.getDocuments().create(args);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw (0, utils_1.mapCalmErrorForTool)(err);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.createDocumentTool = {
|
|
45
|
+
toolDefinition: definition,
|
|
46
|
+
handler,
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=createDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createDocument.js","sourceRoot":"","sources":["../../../src/tools/documents/createDocument.ts"],"names":[],"mappings":";;;AASA,uCAAiE;AAIjE,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,gNAAgN;IAClN,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;YACzD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kDAAkD;aAChE;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yBAAyB;aACvC;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2CAA2C;aACzD;YACD,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;YACxE,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;SACpE;KACF;CACF,CAAC;AAEF,MAAM,OAAO,GAAoD,KAAK,EACpE,GAAG,EACH,IAAI,EACJ,EAAE;IACF,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,qBAAa,CAAC;YACtB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,mBAAmB;SAC7B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAA,2BAAmB,EAAC,GAAG,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEW,QAAA,kBAAkB,GAG3B;IACF,cAAc,EAAE,UAAU;IAC1B,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ICalmHandlerEntry } from '../../registry/types';
|
|
2
|
+
export interface IDeleteDocumentArgs {
|
|
3
|
+
uuid: string;
|
|
4
|
+
}
|
|
5
|
+
export interface IDeleteDocumentResult {
|
|
6
|
+
deleted: true;
|
|
7
|
+
uuid: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const deleteDocumentTool: ICalmHandlerEntry<IDeleteDocumentArgs, IDeleteDocumentResult>;
|
|
10
|
+
//# sourceMappingURL=deleteDocument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deleteDocument.d.ts","sourceRoot":"","sources":["../../../src/tools/documents/deleteDocument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAiCD,eAAO,MAAM,kBAAkB,EAAE,iBAAiB,CAChD,mBAAmB,EACnB,qBAAqB,CAItB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteDocumentTool = void 0;
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
const definition = {
|
|
6
|
+
name: 'calm_documents_delete',
|
|
7
|
+
description: 'Delete a Cloud ALM document by UUID. Destructive. Returns a confirmation object; raises NOT_FOUND if the document does not exist.',
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
required: ['uuid'],
|
|
11
|
+
properties: {
|
|
12
|
+
uuid: { type: 'string', description: 'Document UUID to delete.' },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
const handler = async (ctx, args) => {
|
|
17
|
+
if (!args?.uuid) {
|
|
18
|
+
throw new utils_1.CalmToolError({
|
|
19
|
+
code: 'INVALID_ARGUMENT',
|
|
20
|
+
message: 'uuid is required',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
await ctx.calm.getDocuments().delete(args.uuid);
|
|
25
|
+
return { deleted: true, uuid: args.uuid };
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
throw (0, utils_1.mapCalmErrorForTool)(err);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports.deleteDocumentTool = {
|
|
32
|
+
toolDefinition: definition,
|
|
33
|
+
handler,
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=deleteDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deleteDocument.js","sourceRoot":"","sources":["../../../src/tools/documents/deleteDocument.ts"],"names":[],"mappings":";;;AAKA,uCAAiE;AAWjE,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,mIAAmI;IACrI,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;SAClE;KACF;CACF,CAAC;AAEF,MAAM,OAAO,GAGT,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACtB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,qBAAa,CAAC;YACtB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,kBAAkB;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAA,2BAAmB,EAAC,GAAG,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEW,QAAA,kBAAkB,GAG3B;IACF,cAAc,EAAE,UAAU;IAC1B,OAAO;CACR,CAAC"}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { HandlerGroup } from '../../registry/HandlerGroup';
|
|
2
2
|
import type { ICalmHandlerEntry } from '../../registry/types';
|
|
3
|
+
export type { ICreateDocumentArgs } from './createDocument';
|
|
4
|
+
export { createDocumentTool } from './createDocument';
|
|
5
|
+
export type { IDeleteDocumentArgs, IDeleteDocumentResult, } from './deleteDocument';
|
|
6
|
+
export { deleteDocumentTool } from './deleteDocument';
|
|
3
7
|
export type { IGetDocumentArgs } from './getDocument';
|
|
4
8
|
export { getDocumentTool } from './getDocument';
|
|
9
|
+
export type { IListDocumentStatusesResult } from './listDocumentStatuses';
|
|
10
|
+
export { listDocumentStatusesTool } from './listDocumentStatuses';
|
|
5
11
|
export type { IListDocumentsArgs } from './listDocuments';
|
|
6
12
|
export { listDocumentsTool } from './listDocuments';
|
|
13
|
+
export type { IListDocumentTypesResult } from './listDocumentTypes';
|
|
14
|
+
export { listDocumentTypesTool } from './listDocumentTypes';
|
|
15
|
+
export type { IUpdateDocumentArgs } from './updateDocument';
|
|
16
|
+
export { updateDocumentTool } from './updateDocument';
|
|
7
17
|
export declare const DOCUMENTS_HANDLERS: readonly ICalmHandlerEntry[];
|
|
8
18
|
export declare const DOCUMENTS_GROUP: HandlerGroup;
|
|
9
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/documents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/documents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAS9D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EACV,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAQ1D,CAAC;AAEF,eAAO,MAAM,eAAe,cAG3B,CAAC"}
|
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DOCUMENTS_GROUP = exports.DOCUMENTS_HANDLERS = exports.listDocumentsTool = exports.getDocumentTool = void 0;
|
|
3
|
+
exports.DOCUMENTS_GROUP = exports.DOCUMENTS_HANDLERS = exports.updateDocumentTool = exports.listDocumentTypesTool = exports.listDocumentsTool = exports.listDocumentStatusesTool = exports.getDocumentTool = exports.deleteDocumentTool = exports.createDocumentTool = void 0;
|
|
4
4
|
const HandlerGroup_1 = require("../../registry/HandlerGroup");
|
|
5
|
+
const createDocument_1 = require("./createDocument");
|
|
6
|
+
const deleteDocument_1 = require("./deleteDocument");
|
|
5
7
|
const getDocument_1 = require("./getDocument");
|
|
8
|
+
const listDocumentStatuses_1 = require("./listDocumentStatuses");
|
|
6
9
|
const listDocuments_1 = require("./listDocuments");
|
|
10
|
+
const listDocumentTypes_1 = require("./listDocumentTypes");
|
|
11
|
+
const updateDocument_1 = require("./updateDocument");
|
|
12
|
+
var createDocument_2 = require("./createDocument");
|
|
13
|
+
Object.defineProperty(exports, "createDocumentTool", { enumerable: true, get: function () { return createDocument_2.createDocumentTool; } });
|
|
14
|
+
var deleteDocument_2 = require("./deleteDocument");
|
|
15
|
+
Object.defineProperty(exports, "deleteDocumentTool", { enumerable: true, get: function () { return deleteDocument_2.deleteDocumentTool; } });
|
|
7
16
|
var getDocument_2 = require("./getDocument");
|
|
8
17
|
Object.defineProperty(exports, "getDocumentTool", { enumerable: true, get: function () { return getDocument_2.getDocumentTool; } });
|
|
18
|
+
var listDocumentStatuses_2 = require("./listDocumentStatuses");
|
|
19
|
+
Object.defineProperty(exports, "listDocumentStatusesTool", { enumerable: true, get: function () { return listDocumentStatuses_2.listDocumentStatusesTool; } });
|
|
9
20
|
var listDocuments_2 = require("./listDocuments");
|
|
10
21
|
Object.defineProperty(exports, "listDocumentsTool", { enumerable: true, get: function () { return listDocuments_2.listDocumentsTool; } });
|
|
22
|
+
var listDocumentTypes_2 = require("./listDocumentTypes");
|
|
23
|
+
Object.defineProperty(exports, "listDocumentTypesTool", { enumerable: true, get: function () { return listDocumentTypes_2.listDocumentTypesTool; } });
|
|
24
|
+
var updateDocument_2 = require("./updateDocument");
|
|
25
|
+
Object.defineProperty(exports, "updateDocumentTool", { enumerable: true, get: function () { return updateDocument_2.updateDocumentTool; } });
|
|
11
26
|
exports.DOCUMENTS_HANDLERS = [
|
|
12
27
|
listDocuments_1.listDocumentsTool,
|
|
13
28
|
getDocument_1.getDocumentTool,
|
|
29
|
+
createDocument_1.createDocumentTool,
|
|
30
|
+
updateDocument_1.updateDocumentTool,
|
|
31
|
+
deleteDocument_1.deleteDocumentTool,
|
|
32
|
+
listDocumentStatuses_1.listDocumentStatusesTool,
|
|
33
|
+
listDocumentTypes_1.listDocumentTypesTool,
|
|
14
34
|
];
|
|
15
35
|
exports.DOCUMENTS_GROUP = new HandlerGroup_1.HandlerGroup('documents', exports.DOCUMENTS_HANDLERS);
|
|
16
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/documents/index.ts"],"names":[],"mappings":";;;AAAA,8DAA2D;AAE3D,+CAAgD;AAChD,mDAAoD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/documents/index.ts"],"names":[],"mappings":";;;AAAA,8DAA2D;AAE3D,qDAAsD;AACtD,qDAAsD;AACtD,+CAAgD;AAChD,iEAAkE;AAClE,mDAAoD;AACpD,2DAA4D;AAC5D,qDAAsD;AAGtD,mDAAsD;AAA7C,oHAAA,kBAAkB,OAAA;AAK3B,mDAAsD;AAA7C,oHAAA,kBAAkB,OAAA;AAE3B,6CAAgD;AAAvC,8GAAA,eAAe,OAAA;AAExB,+DAAkE;AAAzD,gIAAA,wBAAwB,OAAA;AAEjC,iDAAoD;AAA3C,kHAAA,iBAAiB,OAAA;AAE1B,yDAA4D;AAAnD,0HAAA,qBAAqB,OAAA;AAE9B,mDAAsD;AAA7C,oHAAA,kBAAkB,OAAA;AAEd,QAAA,kBAAkB,GAAiC;IAC9D,iCAAiB;IACjB,6BAAe;IACf,mCAAkB;IAClB,mCAAkB;IAClB,mCAAkB;IAClB,+CAAwB;IACxB,yCAAqB;CACtB,CAAC;AAEW,QAAA,eAAe,GAAG,IAAI,2BAAY,CAC7C,WAAW,EACX,0BAAkB,CACnB,CAAC"}
|