@mcp-abap-adt/core 6.11.3 → 7.0.1
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 +10 -0
- package/README.md +5 -4
- package/dist/server/EmbeddableMcpServer.d.ts +7 -6
- package/dist/server/EmbeddableMcpServer.d.ts.map +1 -1
- package/dist/server/EmbeddableMcpServer.js +3 -2
- package/dist/server/EmbeddableMcpServer.js.map +1 -1
- package/docs/user-guide/HANDLERS_MANAGEMENT.md +7 -5
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [7.0.1] - 2026-06-11
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Bumped `@mcp-abap-adt/adt-clients` from `^5.4.2` to `^5.4.4` to pick up the stateful-lock-chain fix. Object writes (e.g. `UpdateClass`) no longer fail with HTTP `423 — not locked (invalid lock handle)` on older ABAP kernels (e.g. BASIS 7.55) over HTTP: the client now keeps the connection stateful for the whole `lock → check → update → unlock` chain across all object types, instead of switching back to stateless before the lock-bound PUT. Newer kernels (758/816) already tolerated the stateless write. No server-side API or tool-schema change. (#106)
|
|
9
|
+
|
|
10
|
+
## [7.0.0] - 2026-05-30
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **BREAKING: `EmbeddableMcpServer` now applies `ReadVsGetDedupStrategy` by default.** Previously the embeddable server defaulted to `NoDedupStrategy`, so exposing `readonly` + `high` together surfaced both `Read<X>` and `Get<X>` for the same operation (e.g. `ReadProgram` + `GetProgram`), leaving tool selection up to the client. Embedders (e.g. cloud-llm-hub) now get the same single-tool-per-operation view as the standalone launcher. Consumers that relied on both variants being exposed must opt out by passing `readOnlyDedupStrategy: new NoDedupStrategy()`. No code-level API change — the difference is the set of tools exposed to clients.
|
|
14
|
+
|
|
5
15
|
## [6.11.3] - 2026-05-30
|
|
6
16
|
|
|
7
17
|
### Removed
|
package/README.md
CHANGED
|
@@ -88,20 +88,21 @@ Embed MCP server into existing applications (e.g., SAP CAP/CDS, Express):
|
|
|
88
88
|
```typescript
|
|
89
89
|
import {
|
|
90
90
|
EmbeddableMcpServer,
|
|
91
|
-
|
|
91
|
+
NoDedupStrategy, // optional: expose both Read<X> and Get<X>
|
|
92
92
|
} from '@mcp-abap-adt/core/server';
|
|
93
93
|
|
|
94
94
|
const server = new EmbeddableMcpServer({
|
|
95
95
|
connection, // Your AbapConnection instance
|
|
96
96
|
logger, // Optional logger
|
|
97
97
|
exposition: ['readonly', 'high'], // Handler groups to expose
|
|
98
|
-
//
|
|
99
|
-
|
|
98
|
+
// Default hides Read<X> when Get<X> is exposed (ReadVsGetDedupStrategy).
|
|
99
|
+
// Pass NoDedupStrategy to expose both variants instead.
|
|
100
|
+
// readOnlyDedupStrategy: new NoDedupStrategy(),
|
|
100
101
|
});
|
|
101
102
|
await server.connect(transport);
|
|
102
103
|
```
|
|
103
104
|
|
|
104
|
-
See [Handlers Management → EmbeddableMcpServer dedup strategies](docs/user-guide/HANDLERS_MANAGEMENT.md#embeddablemcpserver-dedup-strategies) for
|
|
105
|
+
See [Handlers Management → EmbeddableMcpServer dedup strategies](docs/user-guide/HANDLERS_MANAGEMENT.md#embeddablemcpserver-dedup-strategies) for how readonly tools are deduped against high/low/compact, how to opt out with `NoDedupStrategy`, and how to plug a custom `IReadOnlyDedupStrategy` for role-based rules.
|
|
105
106
|
|
|
106
107
|
## Quick Start
|
|
107
108
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AbapConnection } from '@mcp-abap-adt/connection';
|
|
2
2
|
import type { Logger } from '@mcp-abap-adt/logger';
|
|
3
|
-
import type
|
|
3
|
+
import { type IReadOnlyDedupStrategy } from '../lib/handlers/groups/strategies/index.js';
|
|
4
4
|
import type { IHandlersRegistry, SapEnvironment } from '../lib/handlers/interfaces.js';
|
|
5
5
|
import type { IAdtSystemContext } from '../lib/systemContext.js';
|
|
6
6
|
import { BaseMcpServer } from './BaseMcpServer.js';
|
|
@@ -54,11 +54,12 @@ export interface EmbeddableMcpServerOptions {
|
|
|
54
54
|
* Optional strategy that decides which readonly handlers to dedup (hide)
|
|
55
55
|
* when overriding groups (high / low / compact) are also exposed.
|
|
56
56
|
*
|
|
57
|
-
* Default:
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
57
|
+
* Default: `ReadVsGetDedupStrategy` — hides a readonly `Read<X>` handler
|
|
58
|
+
* when a corresponding `Get<X>` is contributed by another group, so a single
|
|
59
|
+
* deterministic tool is exposed per operation (matching the standalone
|
|
60
|
+
* launcher). Pass `new NoDedupStrategy()` (exported from this package) to
|
|
61
|
+
* expose readonly handlers verbatim, or supply a custom implementation for
|
|
62
|
+
* bespoke role-based rules.
|
|
62
63
|
*/
|
|
63
64
|
readOnlyDedupStrategy?: IReadOnlyDedupStrategy;
|
|
64
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddableMcpServer.d.ts","sourceRoot":"","sources":["../../src/server/EmbeddableMcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AASnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"EmbeddableMcpServer.d.ts","sourceRoot":"","sources":["../../src/server/EmbeddableMcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AASnD,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACf,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IAErC;;;OAGG;IACH,UAAU,CAAC,EAAE,CACT,UAAU,GACV,MAAM,GACN,KAAK,GACL,SAAS,GACT,QAAQ,GACR,QAAQ,CACX,EAAE,CAAC;IAEJ;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE3C;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAE5B;;;;;;;;;;OAUG;IACH,qBAAqB,CAAC,EAAE,sBAAsB,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;gBAExC,OAAO,EAAE,0BAA0B;IA0B/C;;;OAGG;cACa,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC;IAIxD;;OAEG;IACH,OAAO,CAAC,qBAAqB;CA6D9B"}
|
|
@@ -8,6 +8,7 @@ const LowLevelHandlersGroup_js_1 = require("../lib/handlers/groups/LowLevelHandl
|
|
|
8
8
|
const ReadOnlyHandlersGroup_js_1 = require("../lib/handlers/groups/ReadOnlyHandlersGroup.js");
|
|
9
9
|
const SearchHandlersGroup_js_1 = require("../lib/handlers/groups/SearchHandlersGroup.js");
|
|
10
10
|
const SystemHandlersGroup_js_1 = require("../lib/handlers/groups/SystemHandlersGroup.js");
|
|
11
|
+
const index_js_1 = require("../lib/handlers/groups/strategies/index.js");
|
|
11
12
|
const CompositeHandlersRegistry_js_1 = require("../lib/handlers/registry/CompositeHandlersRegistry.js");
|
|
12
13
|
const systemContext_js_1 = require("../lib/systemContext.js");
|
|
13
14
|
const BaseMcpServer_js_1 = require("./BaseMcpServer.js");
|
|
@@ -64,7 +65,7 @@ class EmbeddableMcpServer extends BaseMcpServer_js_1.BaseMcpServer {
|
|
|
64
65
|
/**
|
|
65
66
|
* Creates default handlers registry based on exposition levels
|
|
66
67
|
*/
|
|
67
|
-
createDefaultRegistry(exposition, logger, readOnlyDedupStrategy) {
|
|
68
|
+
createDefaultRegistry(exposition, logger, readOnlyDedupStrategy = new index_js_1.ReadVsGetDedupStrategy()) {
|
|
68
69
|
// Dummy context - not actually used because BaseMcpServer.registerHandlers()
|
|
69
70
|
// creates wrapper lambdas that call getConnection() for fresh context
|
|
70
71
|
const dummyContext = {
|
|
@@ -72,7 +73,7 @@ class EmbeddableMcpServer extends BaseMcpServer_js_1.BaseMcpServer {
|
|
|
72
73
|
logger: logger ?? handlerLogger_js_1.noopLogger,
|
|
73
74
|
};
|
|
74
75
|
// Build non-readonly groups first so their tool names can feed the
|
|
75
|
-
// readonly dedup strategy (
|
|
76
|
+
// readonly dedup strategy (defaults to ReadVsGetDedupStrategy).
|
|
76
77
|
const overridingGroups = [];
|
|
77
78
|
if (exposition.includes('high')) {
|
|
78
79
|
overridingGroups.push(new HighLevelHandlersGroup_js_1.HighLevelHandlersGroup(dummyContext));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddableMcpServer.js","sourceRoot":"","sources":["../../src/server/EmbeddableMcpServer.ts"],"names":[],"mappings":";;;AAGA,8DAAqD;AACrD,4FAAsF;AACtF,gGAA0F;AAC1F,8FAAwF;AACxF,8FAAwF;AACxF,0FAAoF;AACpF,0FAAoF;
|
|
1
|
+
{"version":3,"file":"EmbeddableMcpServer.js","sourceRoot":"","sources":["../../src/server/EmbeddableMcpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -109,7 +109,7 @@ Valid combinations: `[readonly]`, `[readonly, high]`, `[readonly, low]`, `[high]
|
|
|
109
109
|
|
|
110
110
|
When both `readonly` and `high` are exposed, `Read<X>` readonly handlers duplicate the corresponding `Get<X>` from the high-level group (e.g. `ReadFunctionModule` vs `GetFunctionModule`). The launcher hides the readonly `Read<X>` variants in this case so that only one tool per operation is visible to the client.
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
`EmbeddableMcpServer` applies the same dedup by default, so embedders see one tool per operation just like the launcher. Consumers that need both variants can opt out by passing `new NoDedupStrategy()` as `readOnlyDedupStrategy`. See [EmbeddableMcpServer dedup strategies](#embeddablemcpserver-dedup-strategies) below.
|
|
113
113
|
|
|
114
114
|
### Config File
|
|
115
115
|
|
|
@@ -280,7 +280,9 @@ import {
|
|
|
280
280
|
const server = new EmbeddableMcpServer({
|
|
281
281
|
connection,
|
|
282
282
|
exposition: ['readonly', 'high'],
|
|
283
|
-
//
|
|
283
|
+
// Default already applies ReadVsGetDedupStrategy — hides ReadFunctionModule
|
|
284
|
+
// when GetFunctionModule is exposed, etc. Pass it explicitly to be explicit,
|
|
285
|
+
// or pass `new NoDedupStrategy()` to expose both variants.
|
|
284
286
|
readOnlyDedupStrategy: new ReadVsGetDedupStrategy(),
|
|
285
287
|
});
|
|
286
288
|
```
|
|
@@ -289,8 +291,8 @@ const server = new EmbeddableMcpServer({
|
|
|
289
291
|
|
|
290
292
|
| Strategy | Behavior |
|
|
291
293
|
|---|---|
|
|
292
|
-
| `NoDedupStrategy`
|
|
293
|
-
| `ReadVsGetDedupStrategy` | Hides a `Read<X>` entry when a corresponding `Get<X>` is contributed by another group. |
|
|
294
|
+
| `NoDedupStrategy` | Never excludes anything — readonly group is exposed as-is (opt-out). |
|
|
295
|
+
| `ReadVsGetDedupStrategy` (default) | Hides a `Read<X>` entry when a corresponding `Get<X>` is contributed by another group. |
|
|
294
296
|
|
|
295
297
|
**Custom strategies**: implement `IReadOnlyDedupStrategy` for role-based or domain-specific rules:
|
|
296
298
|
|
|
@@ -311,4 +313,4 @@ class RoleAwareDedup implements IReadOnlyDedupStrategy {
|
|
|
311
313
|
}
|
|
312
314
|
```
|
|
313
315
|
|
|
314
|
-
The default (
|
|
316
|
+
The default (`ReadVsGetDedupStrategy`) gives embedders the same single-tool-per-operation view as the launcher. Consumers that relied on both `Read<X>` and `Get<X>` being exposed must pass `new NoDedupStrategy()` to keep that behavior.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/core",
|
|
3
3
|
"mcpName": "io.github.fr0ster/mcp-abap-adt",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "7.0.1",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"yaml": "^2.8.1"
|
|
137
137
|
},
|
|
138
138
|
"dependencies": {
|
|
139
|
-
"@mcp-abap-adt/adt-clients": "^5.4.
|
|
139
|
+
"@mcp-abap-adt/adt-clients": "^5.4.4",
|
|
140
140
|
"@mcp-abap-adt/auth-broker": "^1.0.5",
|
|
141
141
|
"@mcp-abap-adt/auth-providers": "^1.0.5",
|
|
142
142
|
"@mcp-abap-adt/auth-stores": "^1.0.4",
|