@oneentry/mcp-platform-server 0.1.1 → 0.1.3
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/LICENSE +21 -0
- package/README.md +62 -61
- package/dist/api/audit.d.ts +0 -11
- package/dist/api/audit.js +0 -10
- package/dist/api/auth.d.ts +0 -18
- package/dist/api/auth.js +0 -20
- package/dist/api/build-catalog.d.ts +0 -14
- package/dist/api/build-catalog.js +7 -77
- package/dist/api/catalog.d.ts +0 -26
- package/dist/api/catalog.js +3 -30
- package/dist/api/client.d.ts +0 -24
- package/dist/api/client.js +6 -28
- package/dist/api/normalize-schema.d.ts +0 -11
- package/dist/api/normalize-schema.js +0 -18
- package/dist/api/policy.d.ts +0 -23
- package/dist/api/policy.js +0 -0
- package/dist/api/shape.d.ts +0 -13
- package/dist/api/shape.js +0 -21
- package/dist/api/swagger-source.d.ts +1 -12
- package/dist/api/swagger-source.js +2 -20
- package/dist/api/types.d.ts +0 -34
- package/dist/api/types.js +0 -1
- package/dist/bin/cli.d.ts +0 -1
- package/dist/bin/cli.js +1 -5
- package/dist/config/config.d.ts +0 -54
- package/dist/config/config.js +0 -60
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- package/dist/knowledge/chunk.d.ts +0 -15
- package/dist/knowledge/chunk.js +0 -16
- package/dist/knowledge/github.d.ts +0 -25
- package/dist/knowledge/github.js +0 -40
- package/dist/knowledge/loader.d.ts +0 -28
- package/dist/knowledge/loader.js +0 -26
- package/dist/knowledge/search.d.ts +0 -22
- package/dist/knowledge/search.js +0 -34
- package/dist/knowledge/tar.d.ts +0 -15
- package/dist/knowledge/tar.js +0 -33
- package/dist/knowledge/types.d.ts +0 -35
- package/dist/knowledge/types.js +0 -1
- package/dist/server.d.ts +0 -12
- package/dist/server.js +10 -14
- package/dist/session.d.ts +0 -23
- package/dist/session.js +0 -18
- package/dist/tools/api-call.d.ts +0 -2
- package/dist/tools/api-call.js +0 -23
- package/dist/tools/api-discovery.d.ts +0 -2
- package/dist/tools/api-discovery.js +2 -5
- package/dist/tools/docs.d.ts +0 -2
- package/dist/tools/docs.js +1 -5
- package/dist/tools/guide.d.ts +0 -7
- package/dist/tools/guide.js +2 -9
- package/dist/tools/result.d.ts +0 -8
- package/dist/tools/result.js +0 -7
- package/dist/tools/whoami.d.ts +0 -2
- package/dist/tools/whoami.js +1 -3
- package/dist/transports/http.d.ts +0 -6
- package/dist/transports/http.js +0 -26
- package/dist/transports/stdio.d.ts +0 -6
- package/dist/transports/stdio.js +0 -6
- package/knowledge/operating-rules.md +70 -125
- package/package.json +18 -5
- package/dist/api/audit.d.ts.map +0 -1
- package/dist/api/audit.js.map +0 -1
- package/dist/api/auth.d.ts.map +0 -1
- package/dist/api/auth.js.map +0 -1
- package/dist/api/build-catalog.d.ts.map +0 -1
- package/dist/api/build-catalog.js.map +0 -1
- package/dist/api/catalog.d.ts.map +0 -1
- package/dist/api/catalog.js.map +0 -1
- package/dist/api/client.d.ts.map +0 -1
- package/dist/api/client.js.map +0 -1
- package/dist/api/normalize-schema.d.ts.map +0 -1
- package/dist/api/normalize-schema.js.map +0 -1
- package/dist/api/policy.d.ts.map +0 -1
- package/dist/api/policy.js.map +0 -1
- package/dist/api/shape.d.ts.map +0 -1
- package/dist/api/shape.js.map +0 -1
- package/dist/api/swagger-source.d.ts.map +0 -1
- package/dist/api/swagger-source.js.map +0 -1
- package/dist/api/types.d.ts.map +0 -1
- package/dist/api/types.js.map +0 -1
- package/dist/bin/cli.d.ts.map +0 -1
- package/dist/bin/cli.js.map +0 -1
- package/dist/config/config.d.ts.map +0 -1
- package/dist/config/config.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/knowledge/chunk.d.ts.map +0 -1
- package/dist/knowledge/chunk.js.map +0 -1
- package/dist/knowledge/github.d.ts.map +0 -1
- package/dist/knowledge/github.js.map +0 -1
- package/dist/knowledge/loader.d.ts.map +0 -1
- package/dist/knowledge/loader.js.map +0 -1
- package/dist/knowledge/search.d.ts.map +0 -1
- package/dist/knowledge/search.js.map +0 -1
- package/dist/knowledge/tar.d.ts.map +0 -1
- package/dist/knowledge/tar.js.map +0 -1
- package/dist/knowledge/types.d.ts.map +0 -1
- package/dist/knowledge/types.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js.map +0 -1
- package/dist/tools/api-call.d.ts.map +0 -1
- package/dist/tools/api-call.js.map +0 -1
- package/dist/tools/api-discovery.d.ts.map +0 -1
- package/dist/tools/api-discovery.js.map +0 -1
- package/dist/tools/docs.d.ts.map +0 -1
- package/dist/tools/docs.js.map +0 -1
- package/dist/tools/guide.d.ts.map +0 -1
- package/dist/tools/guide.js.map +0 -1
- package/dist/tools/result.d.ts.map +0 -1
- package/dist/tools/result.js.map +0 -1
- package/dist/tools/whoami.d.ts.map +0 -1
- package/dist/tools/whoami.js.map +0 -1
- package/dist/transports/http.d.ts.map +0 -1
- package/dist/transports/http.js.map +0 -1
- package/dist/transports/stdio.d.ts.map +0 -1
- package/dist/transports/stdio.js.map +0 -1
package/dist/tools/api-call.js
CHANGED
|
@@ -4,9 +4,7 @@ import { buildUrl, normalizeBody, RequestBuildError } from '../api/client.js';
|
|
|
4
4
|
import { checkLevel, decide } from '../api/policy.js';
|
|
5
5
|
import { shapeResponse, summarizeTarget } from '../api/shape.js';
|
|
6
6
|
import { errorResult, jsonResult } from './result.js';
|
|
7
|
-
/** Ограничение на показ тела в плане dry-run. */
|
|
8
7
|
const PLAN_BODY_LIMIT = 2_000;
|
|
9
|
-
/** Регистрирует `cms_api_call`. */
|
|
10
8
|
export const registerApiCall = (server, getSession) => {
|
|
11
9
|
server.registerTool('cms_api_call', {
|
|
12
10
|
title: 'Call an Admin API operation',
|
|
@@ -42,11 +40,6 @@ export const registerApiCall = (server, getSession) => {
|
|
|
42
40
|
hint: 'Operation ids come from cms_api_search — do not construct them by hand.',
|
|
43
41
|
});
|
|
44
42
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Тело нормализуется до всего остального: и хэш аудита, и токен подтверждения
|
|
47
|
-
* привязываются именно к отправляемым аргументам, иначе подтверждение,
|
|
48
|
-
* выданное на dry-run, не совпало бы с реальным вызовом.
|
|
49
|
-
*/
|
|
50
43
|
const normalizedBody = normalizeBody(body);
|
|
51
44
|
const args = {
|
|
52
45
|
...(path ? { path } : {}),
|
|
@@ -60,24 +53,15 @@ export const registerApiCall = (server, getSession) => {
|
|
|
60
53
|
path: operation.path,
|
|
61
54
|
argsHash,
|
|
62
55
|
};
|
|
63
|
-
/**
|
|
64
|
-
* Уровень доступа проверяется до аутентификации: иначе отказ read-only режима
|
|
65
|
-
* всё равно сходил бы в сеть за токеном, и обещание «no request was sent» было бы ложью.
|
|
66
|
-
*/
|
|
67
56
|
const levelDenial = checkLevel(operation, config.allow);
|
|
68
57
|
if (levelDenial) {
|
|
69
58
|
audit.record({ ...auditBase, outcome: 'denied' });
|
|
70
59
|
return errorResult(levelDenial.reason, { opId, policy: config.allow, risk: operation.risk });
|
|
71
60
|
}
|
|
72
|
-
/** Личность нужна только там, где операция объявляет требуемое право. */
|
|
73
61
|
const identity = operation.permission ? await session.identity() : undefined;
|
|
74
62
|
if (identity) {
|
|
75
63
|
Object.assign(auditBase, { adminId: identity.id });
|
|
76
64
|
}
|
|
77
|
-
/**
|
|
78
|
-
* Негодный токен — отдельная ошибка, а не «просто нет подтверждения»:
|
|
79
|
-
* иначе агент получал бы в ответ новый токен и не понимал, что предыдущий не подошёл.
|
|
80
|
-
*/
|
|
81
65
|
const confirmValid = confirm !== undefined && session.confirms.verify(confirm, opId, args);
|
|
82
66
|
if (confirm !== undefined && !confirmValid) {
|
|
83
67
|
return errorResult('Confirm token is expired, already used, or does not match these arguments. Re-run with dryRun: true to get a fresh one.', { opId });
|
|
@@ -94,7 +78,6 @@ export const registerApiCall = (server, getSession) => {
|
|
|
94
78
|
}
|
|
95
79
|
return errorResult(decision.reason, { opId, policy: config.allow, risk: operation.risk });
|
|
96
80
|
}
|
|
97
|
-
/** Разрешение по уровню и правам получено — можно строить сам запрос. */
|
|
98
81
|
let url;
|
|
99
82
|
try {
|
|
100
83
|
url = buildUrl(config.baseUrl, operation, args);
|
|
@@ -134,10 +117,6 @@ export const registerApiCall = (server, getSession) => {
|
|
|
134
117
|
target: summarizeTarget(target),
|
|
135
118
|
});
|
|
136
119
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Токен гасится только здесь, перед самой отправкой: если бы он расходовался
|
|
139
|
-
* при проверке политики, отказ по другой причине заставлял бы подтверждать заново.
|
|
140
|
-
*/
|
|
141
120
|
if (confirm !== undefined && !session.confirms.consume(confirm, opId, args)) {
|
|
142
121
|
return errorResult('Confirm token was consumed concurrently. Re-run with dryRun: true to get a fresh one.', { opId });
|
|
143
122
|
}
|
|
@@ -154,7 +133,6 @@ export const registerApiCall = (server, getSession) => {
|
|
|
154
133
|
opId,
|
|
155
134
|
status: result.error.status,
|
|
156
135
|
...(result.error.hint ? { hint: result.error.hint } : {}),
|
|
157
|
-
docs: operation.docLinks,
|
|
158
136
|
});
|
|
159
137
|
}
|
|
160
138
|
const shaped = shapeResponse(result.body, config.maxResponseBytes);
|
|
@@ -166,4 +144,3 @@ export const registerApiCall = (server, getSession) => {
|
|
|
166
144
|
});
|
|
167
145
|
});
|
|
168
146
|
};
|
|
169
|
-
//# sourceMappingURL=api-call.js.map
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { SharedDeps } from '../session.js';
|
|
3
|
-
/** Регистрирует `cms_api_search` и `cms_api_describe`. */
|
|
4
3
|
export declare const registerApiDiscovery: (server: McpServer, deps: SharedDeps) => void;
|
|
5
|
-
//# sourceMappingURL=api-discovery.d.ts.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { errorResult, jsonResult } from './result.js';
|
|
3
|
-
/** Регистрирует `cms_api_search` и `cms_api_describe`. */
|
|
4
3
|
export const registerApiDiscovery = (server, deps) => {
|
|
5
4
|
const { catalog } = deps;
|
|
6
5
|
server.registerTool('cms_api_search', {
|
|
@@ -36,7 +35,7 @@ export const registerApiDiscovery = (server, deps) => {
|
|
|
36
35
|
});
|
|
37
36
|
server.registerTool('cms_api_describe', {
|
|
38
37
|
title: 'Describe an Admin API operation',
|
|
39
|
-
description: 'Full detail for one operation: path and query parameters, request-body schema, required permission, risk level, and
|
|
38
|
+
description: 'Full detail for one operation: path and query parameters, request-body schema, required permission, risk level, and whether it is permanently confirm-gated. Fields marked "x-loose": true could not be converted to a JSON Schema type — trust their example, not their type.',
|
|
40
39
|
inputSchema: {
|
|
41
40
|
opId: z.string().min(1).describe('Operation id from cms_api_search, e.g. "AdminPagesController_findAllRoot".'),
|
|
42
41
|
},
|
|
@@ -70,11 +69,9 @@ export const registerApiDiscovery = (server, deps) => {
|
|
|
70
69
|
body: operation.body ?? null,
|
|
71
70
|
looseFields: loose,
|
|
72
71
|
responseSummary: operation.responseSummary ?? null,
|
|
73
|
-
docs: operation.docLinks,
|
|
74
72
|
next: operation.risk === 'read'
|
|
75
73
|
? 'Call it with cms_api_call { opId, path, query }.'
|
|
76
|
-
: '
|
|
74
|
+
: 'Search the knowledge base with cms_docs_search for this entity, then call cms_api_call with dryRun: true first.',
|
|
77
75
|
});
|
|
78
76
|
});
|
|
79
77
|
};
|
|
80
|
-
//# sourceMappingURL=api-discovery.js.map
|
package/dist/tools/docs.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { SharedDeps } from '../session.js';
|
|
3
|
-
/** Регистрирует `cms_docs_search` и `cms_docs_read`. */
|
|
4
3
|
export declare const registerDocs: (server: McpServer, deps: SharedDeps) => void;
|
|
5
|
-
//# sourceMappingURL=docs.d.ts.map
|
package/dist/tools/docs.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { errorResult, jsonResult } from './result.js';
|
|
3
|
-
/** Предел размера одного раздела, отдаваемого модели. */
|
|
4
3
|
const MAX_SECTION_BYTES = 12_288;
|
|
5
|
-
/** Регистрирует `cms_docs_search` и `cms_docs_read`. */
|
|
6
4
|
export const registerDocs = (server, deps) => {
|
|
7
5
|
const { knowledge } = deps;
|
|
8
6
|
server.registerTool('cms_docs_search', {
|
|
@@ -37,7 +35,7 @@ export const registerDocs = (server, deps) => {
|
|
|
37
35
|
title: 'Read a CMS knowledge section',
|
|
38
36
|
description: 'Read one section of a knowledge document. Omit the anchor to get the document preamble plus its section list, then page through the sections you need.',
|
|
39
37
|
inputSchema: {
|
|
40
|
-
docId: z.string().min(1).describe('Document id, e.g. "
|
|
38
|
+
docId: z.string().min(1).describe('Document id, e.g. "mcp/docs/api/orders" or "mcp/operating-rules".'),
|
|
41
39
|
anchor: z.string().optional().describe('Section anchor from cms_docs_search; omit for the preamble.'),
|
|
42
40
|
},
|
|
43
41
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
@@ -73,7 +71,6 @@ export const registerDocs = (server, deps) => {
|
|
|
73
71
|
sections: doc.anchors.map((a) => ({ anchor: a.anchor, title: a.title, bytes: a.bytes })),
|
|
74
72
|
});
|
|
75
73
|
});
|
|
76
|
-
/** Ресурсы дублируют два самых нужных документа, чтобы клиент мог их закрепить. */
|
|
77
74
|
server.registerResource('operating-rules', 'oneentry://knowledge/mcp/operating-rules', {
|
|
78
75
|
title: 'OneEntry CMS operating rules',
|
|
79
76
|
description: 'The payload and safety rules an agent must follow before writing to this CMS.',
|
|
@@ -110,4 +107,3 @@ export const registerDocs = (server, deps) => {
|
|
|
110
107
|
],
|
|
111
108
|
}));
|
|
112
109
|
};
|
|
113
|
-
//# sourceMappingURL=docs.js.map
|
package/dist/tools/guide.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { SharedDeps } from '../session.js';
|
|
3
|
-
/**
|
|
4
|
-
* Собирает краткое руководство: режим, политика, карта тегов и порядок работы.
|
|
5
|
-
* Генерируется, а не хранится текстом, потому что половина содержимого —
|
|
6
|
-
* фактическое состояние сервера, и расхождение здесь дороже дублирования.
|
|
7
|
-
*/
|
|
8
3
|
export declare const renderGuide: (deps: SharedDeps) => string;
|
|
9
|
-
/** Регистрирует `cms_guide`. */
|
|
10
4
|
export declare const registerGuide: (server: McpServer, deps: SharedDeps) => void;
|
|
11
|
-
//# sourceMappingURL=guide.d.ts.map
|
package/dist/tools/guide.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { textResult } from './result.js';
|
|
2
|
-
/** Сколько тегов показывать в карте API. */
|
|
3
2
|
const TAG_LIMIT = 24;
|
|
4
|
-
/**
|
|
5
|
-
* Собирает краткое руководство: режим, политика, карта тегов и порядок работы.
|
|
6
|
-
* Генерируется, а не хранится текстом, потому что половина содержимого —
|
|
7
|
-
* фактическое состояние сервера, и расхождение здесь дороже дублирования.
|
|
8
|
-
*/
|
|
9
3
|
export const renderGuide = (deps) => {
|
|
10
4
|
const { config, catalog, knowledge } = deps;
|
|
11
5
|
const counts = new Map();
|
|
@@ -42,7 +36,8 @@ export const renderGuide = (deps) => {
|
|
|
42
36
|
' payload rules (locale-keyed `localizeInfos`, attribute-set-driven `attributesSets`,',
|
|
43
37
|
' lexorank vs numeric `position`, eventual consistency) that make the difference between',
|
|
44
38
|
' a 400 and a correct call.',
|
|
45
|
-
'2. `cms_docs_search` — find the reference doc for the entity you are touching
|
|
39
|
+
'2. `cms_docs_search` — find the reference doc for the entity you are touching;',
|
|
40
|
+
' `mcp/docs/server/doc-map` lists every document with a one-line "read this when".',
|
|
46
41
|
'3. `cms_api_search` → `cms_api_describe` — get the real operation and its payload shape.',
|
|
47
42
|
'4. `cms_api_call` — `dryRun: true` first for anything that mutates.',
|
|
48
43
|
'',
|
|
@@ -63,7 +58,6 @@ export const renderGuide = (deps) => {
|
|
|
63
58
|
: []),
|
|
64
59
|
].join('\n');
|
|
65
60
|
};
|
|
66
|
-
/** Регистрирует `cms_guide`. */
|
|
67
61
|
export const registerGuide = (server, deps) => {
|
|
68
62
|
server.registerTool('cms_guide', {
|
|
69
63
|
title: 'CMS guide',
|
|
@@ -71,4 +65,3 @@ export const registerGuide = (server, deps) => {
|
|
|
71
65
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
72
66
|
}, () => textResult(renderGuide(deps)));
|
|
73
67
|
};
|
|
74
|
-
//# sourceMappingURL=guide.js.map
|
package/dist/tools/result.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Форма результата вызова инструмента MCP. */
|
|
2
1
|
export interface ToolResult {
|
|
3
2
|
content: Array<{
|
|
4
3
|
type: 'text';
|
|
@@ -7,13 +6,6 @@ export interface ToolResult {
|
|
|
7
6
|
isError?: boolean;
|
|
8
7
|
[key: string]: unknown;
|
|
9
8
|
}
|
|
10
|
-
/** Успешный результат-JSON. */
|
|
11
9
|
export declare const jsonResult: (payload: unknown) => ToolResult;
|
|
12
|
-
/** Успешный результат-текст (для человекочитаемых руководств). */
|
|
13
10
|
export declare const textResult: (text: string) => ToolResult;
|
|
14
|
-
/**
|
|
15
|
-
* Ошибка инструмента. Возвращаем её как isError, а не бросаем исключение:
|
|
16
|
-
* модель должна увидеть текст и исправиться, а не получить обрыв сессии.
|
|
17
|
-
*/
|
|
18
11
|
export declare const errorResult: (message: string, extra?: Record<string, unknown>) => ToolResult;
|
|
19
|
-
//# sourceMappingURL=result.d.ts.map
|
package/dist/tools/result.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
/** Успешный результат-JSON. */
|
|
2
1
|
export const jsonResult = (payload) => ({
|
|
3
2
|
content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }],
|
|
4
3
|
});
|
|
5
|
-
/** Успешный результат-текст (для человекочитаемых руководств). */
|
|
6
4
|
export const textResult = (text) => ({
|
|
7
5
|
content: [{ type: 'text', text }],
|
|
8
6
|
});
|
|
9
|
-
/**
|
|
10
|
-
* Ошибка инструмента. Возвращаем её как isError, а не бросаем исключение:
|
|
11
|
-
* модель должна увидеть текст и исправиться, а не получить обрыв сессии.
|
|
12
|
-
*/
|
|
13
7
|
export const errorResult = (message, extra) => ({
|
|
14
8
|
content: [
|
|
15
9
|
{ type: 'text', text: JSON.stringify({ error: message, ...(extra ?? {}) }, null, 2) },
|
|
16
10
|
],
|
|
17
11
|
isError: true,
|
|
18
12
|
});
|
|
19
|
-
//# sourceMappingURL=result.js.map
|
package/dist/tools/whoami.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { Session } from '../session.js';
|
|
3
|
-
/** Регистрирует `cms_whoami` — состояние сервера и подключённого админа. */
|
|
4
3
|
export declare const registerWhoami: (server: McpServer, getSession: () => Session) => void;
|
|
5
|
-
//# sourceMappingURL=whoami.d.ts.map
|
package/dist/tools/whoami.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsonResult } from './result.js';
|
|
2
|
-
/** Регистрирует `cms_whoami` — состояние сервера и подключённого админа. */
|
|
3
2
|
export const registerWhoami = (server, getSession) => {
|
|
4
3
|
server.registerTool('cms_whoami', {
|
|
5
4
|
title: 'Who am I',
|
|
@@ -19,7 +18,7 @@ export const registerWhoami = (server, getSession) => {
|
|
|
19
18
|
: {
|
|
20
19
|
admin: null,
|
|
21
20
|
hint: session.isConfigured
|
|
22
|
-
? 'Credentials are configured but authentication failed — check ONEENTRY_CMS_LOGIN / ONEENTRY_CMS_PASSWORD and that the
|
|
21
|
+
? 'Credentials are configured but authentication failed — check ONEENTRY_CMS_LOGIN / ONEENTRY_CMS_PASSWORD and that the instance is reachable.'
|
|
23
22
|
: 'No credentials configured. Set ONEENTRY_CMS_LOGIN + ONEENTRY_CMS_PASSWORD (or ONEENTRY_CMS_TOKEN).',
|
|
24
23
|
}),
|
|
25
24
|
catalog: {
|
|
@@ -43,4 +42,3 @@ export const registerWhoami = (server, getSession) => {
|
|
|
43
42
|
});
|
|
44
43
|
});
|
|
45
44
|
};
|
|
46
|
-
//# sourceMappingURL=whoami.js.map
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { Config } from '../config/config.js';
|
|
2
|
-
/**
|
|
3
|
-
* Запускает сервер поверх Streamable HTTP — remote-режим.
|
|
4
|
-
* На каждое MCP-подключение создаётся своя `Session` со своими токенами
|
|
5
|
-
* и своими подтверждениями; общий каталог и знания строятся один раз.
|
|
6
|
-
*/
|
|
7
2
|
export declare const runHttp: (config: Config) => Promise<{
|
|
8
3
|
close: () => Promise<void>;
|
|
9
4
|
}>;
|
|
10
|
-
//# sourceMappingURL=http.d.ts.map
|
package/dist/transports/http.js
CHANGED
|
@@ -5,7 +5,6 @@ import express from 'express';
|
|
|
5
5
|
import { OperationCatalog } from '../api/catalog.js';
|
|
6
6
|
import { createServer, createSharedDeps } from '../server.js';
|
|
7
7
|
import { Session } from '../session.js';
|
|
8
|
-
/** Заголовки, которыми клиент передаёт свои учётные данные CMS. */
|
|
9
8
|
const HEADER_TOKEN = 'x-cms-token';
|
|
10
9
|
const HEADER_LOGIN = 'x-cms-login';
|
|
11
10
|
const HEADER_PASSWORD = 'x-cms-password';
|
|
@@ -14,11 +13,6 @@ const headerValue = (request, name) => {
|
|
|
14
13
|
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
15
14
|
return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
|
|
16
15
|
};
|
|
17
|
-
/**
|
|
18
|
-
* Читает учётные данные сессии из заголовков подключения.
|
|
19
|
-
* Только отсюда и из конфигурации сервера — никогда из аргументов инструмента:
|
|
20
|
-
* иначе внедрённая в текст инструкция могла бы подменить личность.
|
|
21
|
-
*/
|
|
22
16
|
const credentialsFromRequest = (request) => {
|
|
23
17
|
const token = headerValue(request, HEADER_TOKEN);
|
|
24
18
|
if (token) {
|
|
@@ -31,10 +25,6 @@ const credentialsFromRequest = (request) => {
|
|
|
31
25
|
}
|
|
32
26
|
return undefined;
|
|
33
27
|
};
|
|
34
|
-
/**
|
|
35
|
-
* Проверка Origin. Транспорт SDK умеет это сам, но помечает как deprecated
|
|
36
|
-
* в пользу внешней middleware — делаем внешнюю.
|
|
37
|
-
*/
|
|
38
28
|
const originGuard = (allowedOrigins) => (request, response, next) => {
|
|
39
29
|
const origin = headerValue(request, 'origin');
|
|
40
30
|
if (!origin) {
|
|
@@ -49,14 +39,6 @@ const originGuard = (allowedOrigins) => (request, response, next) => {
|
|
|
49
39
|
error: `Origin "${origin}" is not allowed. Start the server with --allowed-origins to permit it.`,
|
|
50
40
|
});
|
|
51
41
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Достраивает пустой каталог по учётным данным подключившейся сессии.
|
|
54
|
-
* Процесс поднимается раньше, чем появляется первая сессия, и в remote-режиме
|
|
55
|
-
* своих учётных данных у него может не быть вовсе. Если при этом стенд отдаёт
|
|
56
|
-
* swagger только авторизованным, каталог при старте выходит пустым — и первая
|
|
57
|
-
* же сессия с токеном является единственной возможностью его получить.
|
|
58
|
-
* Делается один раз и молча: это оптимизация, а не часть контракта запроса.
|
|
59
|
-
*/
|
|
60
42
|
const fillCatalog = async (deps, session) => {
|
|
61
43
|
if (!deps.catalog.isEmpty || !session.isConfigured) {
|
|
62
44
|
return;
|
|
@@ -69,14 +51,8 @@ const fillCatalog = async (deps, session) => {
|
|
|
69
51
|
}
|
|
70
52
|
}
|
|
71
53
|
catch {
|
|
72
|
-
/** Каталог остаётся пустым, и его warnings уже объясняют почему. */
|
|
73
54
|
}
|
|
74
55
|
};
|
|
75
|
-
/**
|
|
76
|
-
* Запускает сервер поверх Streamable HTTP — remote-режим.
|
|
77
|
-
* На каждое MCP-подключение создаётся своя `Session` со своими токенами
|
|
78
|
-
* и своими подтверждениями; общий каталог и знания строятся один раз.
|
|
79
|
-
*/
|
|
80
56
|
export const runHttp = async (config) => {
|
|
81
57
|
const deps = await createSharedDeps(config);
|
|
82
58
|
const sessions = new Map();
|
|
@@ -119,7 +95,6 @@ export const runHttp = async (config) => {
|
|
|
119
95
|
await server.connect(transport);
|
|
120
96
|
await transport.handleRequest(request, response, request.body);
|
|
121
97
|
});
|
|
122
|
-
/** GET открывает SSE-поток, DELETE закрывает сессию — обе требуют существующей сессии. */
|
|
123
98
|
const requireSession = async (request, response) => {
|
|
124
99
|
const sessionId = headerValue(request, 'mcp-session-id');
|
|
125
100
|
const managed = sessionId ? sessions.get(sessionId) : undefined;
|
|
@@ -148,4 +123,3 @@ export const runHttp = async (config) => {
|
|
|
148
123
|
},
|
|
149
124
|
};
|
|
150
125
|
};
|
|
151
|
-
//# sourceMappingURL=http.js.map
|
|
@@ -1,8 +1,2 @@
|
|
|
1
1
|
import type { Config } from '../config/config.js';
|
|
2
|
-
/**
|
|
3
|
-
* Запускает сервер поверх stdio — local-режим.
|
|
4
|
-
* Сессия одна на процесс: клиент сам порождает процесс на подключение,
|
|
5
|
-
* поэтому изоляция обеспечивается операционной системой, а не нашим кодом.
|
|
6
|
-
*/
|
|
7
2
|
export declare const runStdio: (config: Config) => Promise<void>;
|
|
8
|
-
//# sourceMappingURL=stdio.d.ts.map
|
package/dist/transports/stdio.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
2
|
import { createServer, createSharedDeps } from '../server.js';
|
|
3
3
|
import { Session } from '../session.js';
|
|
4
|
-
/**
|
|
5
|
-
* Запускает сервер поверх stdio — local-режим.
|
|
6
|
-
* Сессия одна на процесс: клиент сам порождает процесс на подключение,
|
|
7
|
-
* поэтому изоляция обеспечивается операционной системой, а не нашим кодом.
|
|
8
|
-
*/
|
|
9
4
|
export const runStdio = async (config) => {
|
|
10
5
|
const deps = await createSharedDeps(config);
|
|
11
6
|
const session = new Session(deps);
|
|
12
7
|
const server = createServer(deps, () => session);
|
|
13
8
|
await server.connect(new StdioServerTransport());
|
|
14
9
|
};
|
|
15
|
-
//# sourceMappingURL=stdio.js.map
|