@futdevpro/nts-dynamo 1.15.58 → 1.15.64
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/.dynamo/logs/cicd-pipeline/output.log +1746 -1819
- package/.dynamo/logs/cicd-pipeline/status.json +37 -37
- package/.github/workflows/main.yml +432 -426
- package/build/_collections/global-settings.const.d.ts.map +1 -1
- package/build/_collections/global-settings.const.js +6 -0
- package/build/_collections/global-settings.const.js.map +1 -1
- package/build/_collections/mongo-reconnect-guard.util.d.ts +74 -0
- package/build/_collections/mongo-reconnect-guard.util.d.ts.map +1 -0
- package/build/_collections/mongo-reconnect-guard.util.js +111 -0
- package/build/_collections/mongo-reconnect-guard.util.js.map +1 -0
- package/build/_models/interfaces/global-settings.interface.d.ts +21 -0
- package/build/_models/interfaces/global-settings.interface.d.ts.map +1 -1
- package/build/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.d.ts.map +1 -1
- package/build/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.js +2 -2
- package/build/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.js.map +1 -1
- package/build/_modules/ai/_services/ai-embedding-mock.service.d.ts +1 -1
- package/build/_modules/ai/_services/ai-embedding-mock.service.d.ts.map +1 -1
- package/build/_modules/ai/_services/ai-embedding-mock.service.js.map +1 -1
- package/build/_modules/ai/_services/ai-embedding-provider.registry.d.ts.map +1 -1
- package/build/_modules/ai/_services/ai-embedding-provider.registry.js.map +1 -1
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.d.ts +1 -1
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.d.ts.map +1 -1
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.js +3 -3
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.js.map +1 -1
- package/build/_modules/ai/index.d.ts +2 -0
- package/build/_modules/ai/index.d.ts.map +1 -1
- package/build/_modules/ai/index.js +4 -0
- package/build/_modules/ai/index.js.map +1 -1
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.d.ts +17 -17
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.d.ts.map +1 -1
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.js +21 -21
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.js.map +1 -1
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.d.ts +4 -4
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.d.ts.map +1 -1
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.js +5 -5
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.js.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.d.ts +4 -4
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.d.ts.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.js +4 -4
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.js.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.d.ts +6 -6
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.d.ts.map +1 -1
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.js +5 -5
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.js.map +1 -1
- package/build/_modules/mcp/_models/interfaces/dynts-mcp.interface.d.ts +1 -1
- package/build/_modules/mcp/_models/interfaces/dynts-mcp.interface.js +1 -1
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.d.ts +4 -4
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.d.ts.map +1 -1
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.js +6 -6
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.js.map +1 -1
- package/build/_modules/mcp/_services/dynts-mcp.adapter.d.ts +11 -11
- package/build/_modules/mcp/_services/dynts-mcp.adapter.d.ts.map +1 -1
- package/build/_modules/mcp/_services/dynts-mcp.adapter.js +16 -11
- package/build/_modules/mcp/_services/dynts-mcp.adapter.js.map +1 -1
- package/build/_modules/mcp/index.js +1 -1
- package/build/_modules/mcp/index.js.map +1 -1
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.d.ts +3 -3
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.d.ts.map +1 -1
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.js +4 -4
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.js.map +1 -1
- package/build/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.d.ts.map +1 -1
- package/build/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.js +9 -0
- package/build/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.js.map +1 -1
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.d.ts +3 -3
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.d.ts.map +1 -1
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.js +1 -1
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.js.map +1 -1
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.d.ts +7 -7
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.d.ts.map +1 -1
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.js +2 -2
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.js.map +1 -1
- package/build/_services/core/global.service.d.ts.map +1 -1
- package/build/_services/core/global.service.js +15 -2
- package/build/_services/core/global.service.js.map +1 -1
- package/build/_services/server/app.server.d.ts.map +1 -1
- package/build/_services/server/app.server.js +21 -0
- package/build/_services/server/app.server.js.map +1 -1
- package/package.json +1 -1
- package/src/_collections/global-settings.const.ts +7 -0
- package/src/_collections/mongo-reconnect-guard.util.spec.ts +52 -0
- package/src/_collections/mongo-reconnect-guard.util.ts +172 -0
- package/src/_models/interfaces/global-settings.interface.ts +22 -0
- package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.ts +39 -7
- package/src/_modules/ai/_services/ai-embedding-mock.service.ts +18 -4
- package/src/_modules/ai/_services/ai-embedding-provider.registry.ts +4 -0
- package/src/_modules/ai/_services/lmstudio-embedding.control-service.ts +26 -5
- package/src/_modules/ai/index.ts +5 -0
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.spec.ts +145 -130
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.ts +131 -120
- package/src/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.ts +6 -5
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.spec.ts +35 -35
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.ts +9 -5
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.spec.ts +11 -11
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.ts +19 -17
- package/src/_modules/mcp/_models/interfaces/dynts-mcp.interface.ts +1 -1
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.spec.ts +123 -114
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.ts +44 -39
- package/src/_modules/mcp/_services/dynts-mcp.adapter.ts +114 -103
- package/src/_modules/mcp/index.ts +1 -1
- package/src/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.ts +5 -4
- package/src/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.ts +0 -2
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.spec.ts +19 -13
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.ts +37 -21
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.spec.ts +11 -6
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.ts +17 -14
- package/src/_services/core/global.service.spec.ts +17 -0
- package/src/_services/core/global.service.ts +19 -5
- package/src/_services/server/app.server.ts +22 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DyNTS_Mcp_Server_ServiceBase } from './dynts-mcp-server.service-base';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
DyNTS_Mcp_CallResult,
|
|
4
|
+
DyNTS_Mcp_ServerInfo,
|
|
5
|
+
DyNTS_Mcp_ToolDefinition
|
|
6
6
|
} from '../_models/interfaces/dynts-mcp.interface';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* CONTRACT — `
|
|
9
|
+
* CONTRACT — `DyNTS_Mcp_Server_ServiceBase` tool-registry + dispatch (BFR-AM-003). A transportot NEM nyitjuk
|
|
10
10
|
* meg (nincs valódi stdio-szerver) — a `build()` + `callTool()` közvetlen dispatch-ét teszteljük,
|
|
11
11
|
* ami UGYANAZ a logika, mint a SDK `tools/call`-ja:
|
|
12
12
|
* - N tool regisztrálása → `getAdvertisedToolNames` PONTOSAN ezeket listázza,
|
|
@@ -15,128 +15,137 @@ import {
|
|
|
15
15
|
* - handler-dobott hiba → `isError:true` fordítás (a payload tartalmazza a message-et),
|
|
16
16
|
* - `isError:true` outcome → `isError:true` call-result.
|
|
17
17
|
*/
|
|
18
|
-
describe('
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
describe('| DyNTS_Mcp_Server_ServiceBase (tool-registry + dispatch, BFR-AM-003)', () => {
|
|
19
|
+
|
|
20
|
+
/** A handler-hívások nyoma (melyik tool, milyen args) — a dispatch-helyesség igazolásához. */
|
|
21
|
+
let calls: { name: string; args: unknown }[];
|
|
22
|
+
|
|
23
|
+
/** Egy teszt-tool-definíció gyára (a handler `data`-ba teszi a tool-nevet + az args-ot). */
|
|
24
|
+
const makeTool = (name: string): DyNTS_Mcp_ToolDefinition => ({
|
|
25
|
+
name: name,
|
|
26
|
+
description: `Test tool ${name}.`,
|
|
27
|
+
inputSchema: { type: 'object', properties: { x: { type: 'string' } } },
|
|
28
|
+
handler: async (args: unknown) => {
|
|
29
|
+
calls.push({ name: name, args: args });
|
|
30
|
+
|
|
31
|
+
return { data: { tool: name, echo: args } };
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/** A teszt-szerver: 3 tool + egy szándékosan dobó tool. */
|
|
36
|
+
class TestServer extends DyNTS_Mcp_Server_ServiceBase {
|
|
37
|
+
protected getServerInfo(): DyNTS_Mcp_ServerInfo {
|
|
38
|
+
return { name: 'test-mcp', version: '0.0.1-spec' };
|
|
39
|
+
}
|
|
40
|
+
protected getTools(): DyNTS_Mcp_ToolDefinition[] {
|
|
41
|
+
return [
|
|
42
|
+
makeTool('alpha'),
|
|
43
|
+
makeTool('beta'),
|
|
44
|
+
{
|
|
45
|
+
name: 'boom',
|
|
46
|
+
description: 'Always throws.',
|
|
47
|
+
inputSchema: { type: 'object' },
|
|
48
|
+
handler: async () => {
|
|
49
|
+
throw new Error('kaboom from handler');
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'structuredError',
|
|
54
|
+
description: 'Returns a structured error outcome.',
|
|
55
|
+
inputSchema: { type: 'object' },
|
|
56
|
+
handler: async () => ({ data: { reason: 'nope' }, isError: true }),
|
|
31
57
|
},
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let server: TestServer;
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
calls = [];
|
|
66
|
+
server = new TestServer();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
/** A `content[0].text` JSON-payload kiparse-olása (a transport text-JSON shape-je). */
|
|
70
|
+
const payloadOf = (result: DyNTS_Mcp_CallResult): { [key: string]: unknown } =>
|
|
71
|
+
JSON.parse(result.content[0].text) as { [key: string]: unknown };
|
|
72
|
+
|
|
73
|
+
describe('| registry — getTools → advertised', () => {
|
|
74
|
+
it('| a deklarált tool-okat hirdeti build ELŐTT is (determinisztikus)', () => {
|
|
75
|
+
expect(server.getAdvertisedToolNames().sort())
|
|
76
|
+
.toEqual([ 'alpha', 'beta', 'boom', 'structuredError' ]);
|
|
32
77
|
});
|
|
33
78
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
name: 'boom',
|
|
45
|
-
description: 'Always throws.',
|
|
46
|
-
inputSchema: { type: 'object' },
|
|
47
|
-
handler: async () => {
|
|
48
|
-
throw new Error('kaboom from handler');
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
name: 'structuredError',
|
|
53
|
-
description: 'Returns a structured error outcome.',
|
|
54
|
-
inputSchema: { type: 'object' },
|
|
55
|
-
handler: async () => ({ data: { reason: 'nope' }, isError: true }),
|
|
56
|
-
},
|
|
57
|
-
];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
79
|
+
it('| build() után UGYANAZOK a hirdetett tool-ok (idempotens build)', () => {
|
|
80
|
+
const adapter1 = server.build();
|
|
81
|
+
const adapter2 = server.build();
|
|
82
|
+
|
|
83
|
+
expect(adapter1).toBe(adapter2);
|
|
84
|
+
expect(adapter1.getAdvertisedToolNames().sort())
|
|
85
|
+
.toEqual([ 'alpha', 'beta', 'boom', 'structuredError' ]);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
60
88
|
|
|
61
|
-
|
|
89
|
+
describe('| dispatch — callTool a megfelelő handler-re route-ol', () => {
|
|
90
|
+
it('| alpha → az alpha handler fut (a data a tool-nevet + az args-ot adja)', async () => {
|
|
91
|
+
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'alpha', arguments: { x: '1' } });
|
|
62
92
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
93
|
+
expect(result.isError).toBe(false);
|
|
94
|
+
expect(calls).toEqual([{ name: 'alpha', args: { x: '1' } }]);
|
|
95
|
+
expect(payloadOf(result)).toEqual({ tool: 'alpha', echo: { x: '1' } });
|
|
66
96
|
});
|
|
67
97
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
98
|
+
it('| beta → a beta handler fut (a dispatch a `name` szerint választ)', async () => {
|
|
99
|
+
await server.callTool({ name: 'beta', arguments: { x: '2' } });
|
|
100
|
+
expect(calls).toEqual([{ name: 'beta', args: { x: '2' } }]);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('| strukturált hiba (no-silent-failure)', () => {
|
|
105
|
+
it('| ismeretlen tool → isError:true + advertised-lista a message-ben (NEM néma/crash)', async () => {
|
|
106
|
+
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'does_not_exist' });
|
|
71
107
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const adapter2 = server.build();
|
|
81
|
-
expect(adapter1).toBe(adapter2);
|
|
82
|
-
expect(adapter1.getAdvertisedToolNames().sort())
|
|
83
|
-
.toEqual(['alpha', 'beta', 'boom', 'structuredError']);
|
|
84
|
-
});
|
|
108
|
+
expect(result.isError).toBe(true);
|
|
109
|
+
const payload = payloadOf(result) as { ok: boolean; error: { message: string } };
|
|
110
|
+
|
|
111
|
+
expect(payload.ok).toBe(false);
|
|
112
|
+
expect(payload.error.message).toContain('does_not_exist');
|
|
113
|
+
expect(payload.error.message).toContain('alpha');
|
|
114
|
+
// egyetlen ismeretlen tool sem futtatott handlert.
|
|
115
|
+
expect(calls.length).toBe(0);
|
|
85
116
|
});
|
|
86
117
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
it('beta → a beta handler fut (a dispatch a `name` szerint választ)', async () => {
|
|
96
|
-
await server.callTool({ name: 'beta', arguments: { x: '2' } });
|
|
97
|
-
expect(calls).toEqual([{ name: 'beta', args: { x: '2' } }]);
|
|
98
|
-
});
|
|
118
|
+
it('| handler-dobott hiba → isError:true + a hiba message-e a payload-ban (NEM crash)', async () => {
|
|
119
|
+
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'boom' });
|
|
120
|
+
|
|
121
|
+
expect(result.isError).toBe(true);
|
|
122
|
+
const payload = payloadOf(result) as { ok: boolean; error: { message: string } };
|
|
123
|
+
|
|
124
|
+
expect(payload.ok).toBe(false);
|
|
125
|
+
expect(payload.error.message).toContain('kaboom from handler');
|
|
99
126
|
});
|
|
100
127
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
expect(payload.ok).toBe(false);
|
|
107
|
-
expect(payload.error.message).toContain('does_not_exist');
|
|
108
|
-
expect(payload.error.message).toContain('alpha');
|
|
109
|
-
// egyetlen ismeretlen tool sem futtatott handlert.
|
|
110
|
-
expect(calls.length).toBe(0);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('handler-dobott hiba → isError:true + a hiba message-e a payload-ban (NEM crash)', async () => {
|
|
114
|
-
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'boom' });
|
|
115
|
-
expect(result.isError).toBe(true);
|
|
116
|
-
const payload = payloadOf(result) as { ok: boolean; error: { message: string } };
|
|
117
|
-
expect(payload.ok).toBe(false);
|
|
118
|
-
expect(payload.error.message).toContain('kaboom from handler');
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('isError:true outcome → isError:true call-result (a strukturált hiba átmegy)', async () => {
|
|
122
|
-
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'structuredError' });
|
|
123
|
-
expect(result.isError).toBe(true);
|
|
124
|
-
expect(payloadOf(result)).toEqual({ reason: 'nope' });
|
|
125
|
-
});
|
|
128
|
+
it('| isError:true outcome → isError:true call-result (a strukturált hiba átmegy)', async () => {
|
|
129
|
+
const result: DyNTS_Mcp_CallResult = await server.callTool({ name: 'structuredError' });
|
|
130
|
+
|
|
131
|
+
expect(result.isError).toBe(true);
|
|
132
|
+
expect(payloadOf(result)).toEqual({ reason: 'nope' });
|
|
126
133
|
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('| start — transport-választás', () => {
|
|
137
|
+
it('| ismeretlen transport → dob (exhaustiveness-guard); stdio nem nyílik a spec-ben', async () => {
|
|
138
|
+
let thrown: unknown;
|
|
127
139
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
expect(thrown).toBeDefined();
|
|
139
|
-
expect((thrown as Error).message).toContain('Unsupported MCP transport');
|
|
140
|
-
});
|
|
140
|
+
try {
|
|
141
|
+
// Szándékosan érvénytelen transport (a típus-szűkítés megkerülésével) — a guard-ágat teszteli,
|
|
142
|
+
// valódi stdio-szervert NEM indítunk.
|
|
143
|
+
await server.start({ transport: 'http' as never });
|
|
144
|
+
} catch (error) {
|
|
145
|
+
thrown = error;
|
|
146
|
+
}
|
|
147
|
+
expect(thrown).toBeDefined();
|
|
148
|
+
expect((thrown as Error).message).toContain('Unsupported MCP transport');
|
|
141
149
|
});
|
|
150
|
+
});
|
|
142
151
|
});
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
DyNTS_Mcp_CallResult,
|
|
5
|
+
DyNTS_Mcp_ServerInfo,
|
|
6
|
+
DyNTS_Mcp_StartOptions,
|
|
7
|
+
DyNTS_Mcp_ToolDefinition
|
|
8
8
|
} from '../_models/interfaces/dynts-mcp.interface';
|
|
9
9
|
import { DyNTS_Mcp_Adapter } from './dynts-mcp.adapter';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* `
|
|
12
|
+
* `DyNTS_Mcp_Server_ServiceBase` (BFR-AM-003) — a **domain-agnosztikus** MCP-szerver-base. Egy bedrock-réteg
|
|
13
13
|
* a hivatalos `@modelcontextprotocol/sdk` fölött: a server-base felel a tool-registry-ért, a
|
|
14
14
|
* `tools/list`/`tools/call` dispatch-ért (az adaptoron át) + a transport-indításért — a SDK KIZÁRÓLAG
|
|
15
15
|
* a `DyNTS_Mcp_Adapter` mögött él (egy jövőbeli transport-/SDK-csere NON-breaking).
|
|
16
16
|
*
|
|
17
|
-
* **Használat (consumer):** a consumer leszármazik (`extends
|
|
17
|
+
* **Használat (consumer):** a consumer leszármazik (`extends DyNTS_Mcp_Server_ServiceBase`) + implementálja a
|
|
18
18
|
* `getServerInfo()` (név/verzió) és `getTools()` (a SAJÁT tool-jai) abstract metódusokat. A bedrock
|
|
19
19
|
* SEMMILYEN domain-tool-t NEM definiál — csak a server-base + a transport + a registry. (Pl. a FAM a
|
|
20
20
|
* `read`/`write`/`capabilities` tool-jait itt regisztrálja, a bedrock-on kívül.)
|
|
21
21
|
*
|
|
22
22
|
* ```ts
|
|
23
|
-
* class My_McpServer extends
|
|
23
|
+
* class My_McpServer extends DyNTS_Mcp_Server_ServiceBase {
|
|
24
24
|
* protected getServerInfo() { return { name: 'my-app', version: '1.0.0' }; }
|
|
25
25
|
* protected getTools() { return [readTool, writeTool]; }
|
|
26
26
|
* }
|
|
@@ -30,10 +30,10 @@ import { DyNTS_Mcp_Adapter } from './dynts-mcp.adapter';
|
|
|
30
30
|
* **stdio-konvenció:** a stdout a JSON-RPC csatorna — a boot-üzenet + minden log a stderr-re megy (a
|
|
31
31
|
* hívó App a `DyFM_Log`-ot stdio-módban stderr-re konfigurálja).
|
|
32
32
|
*/
|
|
33
|
-
export abstract class
|
|
33
|
+
export abstract class DyNTS_Mcp_Server_ServiceBase {
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
/** Az MCP-adaptor (a regisztrált tool-ok + a transport mögötti SDK-réteg). Lazy a `build()`-ben. */
|
|
36
|
+
private adapter: DyNTS_Mcp_Adapter | null = null;
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* A szerver identitása (név/verzió) — a consumer adja. A SDK `serverInfo`-jaként hirdetődik.
|
|
@@ -52,15 +52,17 @@ export abstract class DyNTS_Mcp_ServerBase {
|
|
|
52
52
|
* hirdeti, transport nélkül). Idempotens: ismételt hívás ugyanazt az adaptort adja vissza.
|
|
53
53
|
*/
|
|
54
54
|
public build(): DyNTS_Mcp_Adapter {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
if (this.adapter) {
|
|
56
|
+
return this.adapter;
|
|
57
|
+
}
|
|
58
|
+
const adapter: DyNTS_Mcp_Adapter = new DyNTS_Mcp_Adapter(this.getServerInfo());
|
|
59
|
+
|
|
60
|
+
for (const tool of this.getTools()) {
|
|
61
|
+
adapter.registerTool(tool);
|
|
62
|
+
}
|
|
63
|
+
this.adapter = adapter;
|
|
64
|
+
|
|
65
|
+
return adapter;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
/**
|
|
@@ -69,12 +71,13 @@ export abstract class DyNTS_Mcp_ServerBase {
|
|
|
69
71
|
* a `tools/call` route-ol. A boot-üzenet a stderr-en.
|
|
70
72
|
*/
|
|
71
73
|
public async start(options?: DyNTS_Mcp_StartOptions): Promise<void> {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const transport: 'stdio' = options?.transport ?? 'stdio';
|
|
75
|
+
const adapter: DyNTS_Mcp_Adapter = this.build();
|
|
76
|
+
const info: DyNTS_Mcp_ServerInfo = this.getServerInfo();
|
|
77
|
+
|
|
78
|
+
DyFM_Log.testInfo(`[DyNTS MCP] ${transport} server starting (${info.name} v${info.version}); `
|
|
76
79
|
+ `advertised tools: ${adapter.getAdvertisedToolNames().join(', ')}`);
|
|
77
|
-
|
|
80
|
+
await this.startTransport(adapter, transport);
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
/**
|
|
@@ -82,9 +85,9 @@ export abstract class DyNTS_Mcp_ServerBase {
|
|
|
82
85
|
* neveit adja (transport nélkül is determinisztikus).
|
|
83
86
|
*/
|
|
84
87
|
public getAdvertisedToolNames(): string[] {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
return this.adapter
|
|
89
|
+
? this.adapter.getAdvertisedToolNames()
|
|
90
|
+
: this.getTools().map((tool) => tool.name);
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
/**
|
|
@@ -93,14 +96,14 @@ export abstract class DyNTS_Mcp_ServerBase {
|
|
|
93
96
|
* tool → strukturált hiba; handler-hiba → `isError:true`).
|
|
94
97
|
*/
|
|
95
98
|
public async callTool(set: { name: string; arguments?: unknown }): Promise<DyNTS_Mcp_CallResult> {
|
|
96
|
-
|
|
99
|
+
return this.build().dispatchToolCall(set);
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
/** A szerver leállítása (graceful close — teszt-/shutdown-úthoz). */
|
|
100
103
|
public async close(): Promise<void> {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
if (this.adapter) {
|
|
105
|
+
await this.adapter.close();
|
|
106
|
+
}
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/**
|
|
@@ -108,13 +111,15 @@ export abstract class DyNTS_Mcp_ServerBase {
|
|
|
108
111
|
* módon bővíthető legyen (a `start()` + a registry változatlan). MVP: csak `stdio`.
|
|
109
112
|
*/
|
|
110
113
|
private async startTransport(adapter: DyNTS_Mcp_Adapter, transport: 'stdio'): Promise<void> {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
switch (transport) {
|
|
115
|
+
case 'stdio':
|
|
116
|
+
await adapter.startStdio();
|
|
117
|
+
|
|
118
|
+
return;
|
|
119
|
+
|
|
120
|
+
default:
|
|
121
|
+
// Exhaustiveness-guard: a `DyNTS_Mcp_TransportKind` bővülésekor itt fordítási hibát kapunk.
|
|
122
|
+
throw new Error(`Unsupported MCP transport: '${transport as string}'.`);
|
|
123
|
+
}
|
|
119
124
|
}
|
|
120
125
|
}
|