@softacus-software/elwis-docs-mcp 0.1.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.
@@ -0,0 +1,119 @@
1
+ const METHODS = ['get', 'post', 'put', 'patch', 'delete'];
2
+ function RefName(ref) {
3
+ return ref.split('/').pop();
4
+ }
5
+ export class DataStore {
6
+ spec;
7
+ index;
8
+ opIndex = new Map();
9
+ constructor(spec, index) {
10
+ this.spec = spec;
11
+ this.index = index;
12
+ for (const path of Object.keys(spec.paths ?? {}))
13
+ for (const method of METHODS) {
14
+ const op = spec.paths[path][method];
15
+ if (op?.operationId)
16
+ this.opIndex.set(op.operationId, { method: method.toUpperCase(), path, op });
17
+ }
18
+ }
19
+ GetEndpoint(operationId) {
20
+ const entry = this.opIndex.get(operationId);
21
+ if (!entry)
22
+ return undefined;
23
+ const op = entry.op;
24
+ const parameters = (op.parameters ?? []).map((p) => ({
25
+ name: p.name, in: p.in, required: !!p.required, type: p.schema?.type ?? (p.schema?.$ref ? RefName(p.schema.$ref) : 'unknown'),
26
+ }));
27
+ const auth = [];
28
+ for (const s of op.security ?? [])
29
+ for (const k of Object.keys(s))
30
+ auth.push(k);
31
+ const content = op.requestBody?.content ?? {};
32
+ const requestContentType = content['application/json'] ? 'application/json' : Object.keys(content)[0];
33
+ const reqSchema = requestContentType ? content[requestContentType]?.schema : undefined;
34
+ const responses = Object.keys(op.responses ?? {}).map(status => {
35
+ const sc = op.responses[status]?.content?.['application/json']?.schema;
36
+ return { status, schema: sc?.$ref ? RefName(sc.$ref) : undefined };
37
+ });
38
+ return {
39
+ operationId, method: entry.method, path: entry.path,
40
+ summary: op.summary ?? '', description: op.description ?? '',
41
+ parameters, auth,
42
+ requestContentType,
43
+ requestSchema: reqSchema?.$ref ? RefName(reqSchema.$ref) : undefined,
44
+ responses,
45
+ };
46
+ }
47
+ GetSchema(name, maxDepth) {
48
+ const schemas = this.spec.components?.schemas ?? {};
49
+ if (!schemas[name])
50
+ return undefined;
51
+ const BYTE_BUDGET = 24000;
52
+ const attempt = (depthLimit) => {
53
+ const truncatedRefs = [];
54
+ const missingRefs = [];
55
+ const inline = (node, depth, seen) => {
56
+ if (Array.isArray(node))
57
+ return node.map(n => inline(n, depth, seen));
58
+ if (node && typeof node === 'object') {
59
+ if (typeof node.$ref === 'string') {
60
+ const refName = RefName(node.$ref);
61
+ if (!schemas[refName]) {
62
+ if (!missingRefs.includes(refName))
63
+ missingRefs.push(refName);
64
+ return { $ref: refName };
65
+ }
66
+ if (seen.has(refName) || depth >= depthLimit) {
67
+ if (!truncatedRefs.includes(refName))
68
+ truncatedRefs.push(refName);
69
+ return { $ref: refName };
70
+ }
71
+ return inline(schemas[refName], depth + 1, new Set(seen).add(refName));
72
+ }
73
+ const out = {};
74
+ for (const k of Object.keys(node))
75
+ out[k] = inline(node[k], depth, seen);
76
+ return out;
77
+ }
78
+ return node;
79
+ };
80
+ const schema = inline(schemas[name], 0, new Set([name]));
81
+ return { name, schema, depthUsed: depthLimit, requestedDepth: maxDepth, truncatedRefs, missingRefs };
82
+ };
83
+ for (let depth = maxDepth; depth > 0; depth--) {
84
+ const result = attempt(depth);
85
+ if (JSON.stringify(result.schema).length <= BYTE_BUDGET)
86
+ return result;
87
+ }
88
+ return attempt(0);
89
+ }
90
+ GetExamples(operationId) {
91
+ const entry = this.opIndex.get(operationId);
92
+ if (!entry)
93
+ return undefined;
94
+ const op = entry.op;
95
+ const requestExamples = Object.entries(op.requestBody?.content?.['application/json']?.examples ?? {})
96
+ .map(([name, ex]) => ({ name, value: ex.value }));
97
+ const responseExamples = [];
98
+ for (const status of Object.keys(op.responses ?? {})) {
99
+ const ct = op.responses[status]?.content?.['application/json'] ?? {};
100
+ for (const [name, ex] of Object.entries(ct.examples ?? {}))
101
+ responseExamples.push({ status, name, value: ex.value });
102
+ if (ct.example !== undefined && !Object.keys(ct.examples ?? {}).length)
103
+ responseExamples.push({ status, name: 'default', value: ct.example });
104
+ const schemaEx = ct.schema?.example ?? ct.schema?.allOf?.[0]?.example;
105
+ if (schemaEx !== undefined && !responseExamples.some(r => r.status === status))
106
+ responseExamples.push({ status, name: 'default', value: schemaEx });
107
+ }
108
+ const scenarios = [];
109
+ for (const sc of this.spec['x-elwis-scenarios'] ?? [])
110
+ for (const step of sc.steps ?? [])
111
+ if (step.operationId === operationId)
112
+ scenarios.push({ scenarioId: sc.id, step });
113
+ return { operationId, requestExamples, responseExamples, scenarios };
114
+ }
115
+ ListGroups() {
116
+ return this.index.groups;
117
+ }
118
+ }
119
+ //# sourceMappingURL=data-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-store.js","sourceRoot":"","sources":["../src/data-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { WalkOperations } from './spec-walk.js';
5
+ export function Tokenize(input) {
6
+ const spaced = input.replace(/([a-z0-9])([A-Z])/g, '$1 $2');
7
+ const raw = spaced.toLowerCase().split(/[^a-z0-9]+/);
8
+ return Array.from(new Set(raw.filter(t => t.length > 1)));
9
+ }
10
+ export function BuildSearchIndex(spec) {
11
+ const ops = WalkOperations(spec).sort((a, b) => a.operationId.localeCompare(b.operationId));
12
+ const operations = ops.map(op => ({
13
+ ...op,
14
+ keywords: Tokenize([op.operationId, op.path, op.tag, op.summary].join(' ')),
15
+ }));
16
+ const groupMap = new Map();
17
+ for (const op of ops)
18
+ groupMap.set(op.tag, (groupMap.get(op.tag) ?? 0) + 1);
19
+ const tagDescriptions = {};
20
+ for (const tag of spec.tags ?? [])
21
+ tagDescriptions[tag.name] = tag.description ?? '';
22
+ const groups = Array.from(groupMap.entries())
23
+ .sort((a, b) => a[0].localeCompare(b[0]))
24
+ .map(([tag, operationCount]) => ({ tag, description: tagDescriptions[tag] ?? '', operationCount }));
25
+ return { version: spec.info?.version ?? '0.0.0', operations, groups };
26
+ }
27
+ function StableSort(value) {
28
+ if (Array.isArray(value))
29
+ return value.map(StableSort);
30
+ if (value && typeof value === 'object') {
31
+ const out = {};
32
+ for (const key of Object.keys(value).sort())
33
+ out[key] = StableSort(value[key]);
34
+ return out;
35
+ }
36
+ return value;
37
+ }
38
+ function Main() {
39
+ const specPath = resolve(process.argv[2] ?? 'data/openapi.json');
40
+ const dataDir = dirname(specPath);
41
+ const spec = JSON.parse(readFileSync(specPath, 'utf8'));
42
+ const index = BuildSearchIndex(spec);
43
+ writeFileSync(resolve(dataDir, 'search-index.json'), JSON.stringify(StableSort(index), null, 2) + '\n');
44
+ writeFileSync(specPath, JSON.stringify(StableSort(spec), null, 2) + '\n');
45
+ console.log(`Indexed ${index.operations.length} operations into ${dataDir}/search-index.json`);
46
+ }
47
+ if (import.meta.url === `file://${process.argv[1]}` || fileURLToPath(import.meta.url) === process.argv[1])
48
+ Main();
49
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAS;IACxC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5F,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAChC,GAAG,EAAE;QACL,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAC5E,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,KAAK,MAAM,EAAE,IAAI,GAAG;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,eAAe,GAA2B,EAAE,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE;QAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IACrF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;SAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IACtG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE;YACpE,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,IAAI;IACX,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,UAAU,CAAC,MAAM,oBAAoB,OAAO,oBAAoB,CAAC,CAAC;AACjG,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAAE,IAAI,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { BuildServer } from './server.js';
4
+ async function Main() {
5
+ const server = BuildServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ }
9
+ Main().catch(e => {
10
+ console.error(e);
11
+ process.exit(1);
12
+ });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/search.js ADDED
@@ -0,0 +1,54 @@
1
+ function QueryTokens(query) {
2
+ const spaced = query.replace(/([a-z0-9])([A-Z])/g, '$1 $2');
3
+ return [...new Set(spaced.toLowerCase().split(/[^a-z0-9]+/).filter(t => t.length > 1))];
4
+ }
5
+ function TokenMatch(token, keyword) {
6
+ if (keyword === token)
7
+ return 2;
8
+ if (token.endsWith('s') && keyword === token.slice(0, -1))
9
+ return 2;
10
+ if (keyword.endsWith('s') && token === keyword.slice(0, -1))
11
+ return 2;
12
+ if (keyword.startsWith(token) || (keyword.length > 2 && token.startsWith(keyword)))
13
+ return 1;
14
+ return 0;
15
+ }
16
+ function PrimaryResource(path) {
17
+ const segments = path.split('/').filter(s => s && s !== 'api' && !s.startsWith('{'));
18
+ if (segments.length > 1 && (segments[0] === 'tenant' || segments[0] === 'system' || segments[0] === 'internal'))
19
+ return segments[1];
20
+ return segments[0] ?? '';
21
+ }
22
+ export function SearchOperations(index, query, group, limit) {
23
+ const tokens = QueryTokens(query);
24
+ const pool = group ? index.operations.filter(o => o.tag === group) : index.operations;
25
+ const perOp = pool.map(op => ({
26
+ op,
27
+ resource: PrimaryResource(op.path),
28
+ matched: tokens.map(t => op.keywords.reduce((best, k) => Math.max(best, TokenMatch(t, k)), 0)),
29
+ }));
30
+ const poolSize = pool.length || 1;
31
+ const idf = tokens.map((_, i) => {
32
+ const df = perOp.reduce((n, x) => n + (x.matched[i] > 0 ? 1 : 0), 0);
33
+ return df > 0 ? Math.log(1 + poolSize / df) : 0;
34
+ });
35
+ const scored = perOp.map(({ op, resource, matched }) => {
36
+ let score = 0;
37
+ matched.forEach((m, i) => {
38
+ if (m === 0)
39
+ return;
40
+ score += m * idf[i];
41
+ if (TokenMatch(tokens[i], resource) === 2)
42
+ score += 2 * idf[i];
43
+ });
44
+ return { op, score };
45
+ });
46
+ const matches = scored
47
+ .filter(s => tokens.length === 0 || s.score > 0)
48
+ .sort((a, b) => b.score - a.score || a.op.operationId.localeCompare(b.op.operationId));
49
+ const results = matches
50
+ .slice(0, limit)
51
+ .map(s => ({ operationId: s.op.operationId, method: s.op.method, path: s.op.path, tag: s.op.tag, summary: s.op.summary }));
52
+ return { results, total: matches.length, returned: results.length, hasMore: matches.length > results.length };
53
+ }
54
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
package/dist/server.js ADDED
@@ -0,0 +1,72 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { z } from 'zod';
6
+ import { DataStore } from './data-store.js';
7
+ import { SearchOperations } from './search.js';
8
+ function PackageRoot() {
9
+ return resolve(dirname(fileURLToPath(import.meta.url)), '..');
10
+ }
11
+ function Text(value) {
12
+ return { content: [{ type: 'text', text: JSON.stringify(value) }] };
13
+ }
14
+ function ErrorText(message) {
15
+ return { content: [{ type: 'text', text: JSON.stringify({ error: message }) }], isError: true };
16
+ }
17
+ const READ_ONLY = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
18
+ export function BuildServer() {
19
+ const root = PackageRoot();
20
+ const pkg = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8'));
21
+ const spec = JSON.parse(readFileSync(resolve(root, 'data', 'openapi.json'), 'utf8'));
22
+ const index = JSON.parse(readFileSync(resolve(root, 'data', 'search-index.json'), 'utf8'));
23
+ const store = new DataStore(spec, index);
24
+ const server = new McpServer({ name: 'elwis-docs-mcp', version: pkg.version });
25
+ server.registerTool('search_elwis_api', {
26
+ title: 'Search ELWIS API operations',
27
+ description: 'Search ELWIS API operations by keyword. Returns compact summaries with total/hasMore metadata. Start here; never guess endpoint paths.',
28
+ inputSchema: {
29
+ query: z.string().describe('Keywords to match against operation names, paths and tags'),
30
+ group: z.string().optional().describe('Restrict to one API group tag (see list_elwis_api_groups)'),
31
+ limit: z.number().int().positive().max(50).optional().describe('Maximum results to return (default 10)'),
32
+ },
33
+ annotations: READ_ONLY,
34
+ }, async ({ query, group, limit }) => Text(SearchOperations(index, query, group, limit ?? 10)));
35
+ server.registerTool('list_elwis_api_groups', {
36
+ title: 'List ELWIS API groups',
37
+ description: 'List ELWIS API groups (tags) with operation counts.',
38
+ annotations: READ_ONLY,
39
+ }, async () => Text(store.ListGroups()));
40
+ server.registerTool('get_elwis_endpoint', {
41
+ title: 'Get ELWIS endpoint details',
42
+ description: 'Get details for one operation: method, path, params, auth, request content type and request/response schema names.',
43
+ inputSchema: { operationId: z.string().describe('Operation id from search_elwis_api results') },
44
+ annotations: READ_ONLY,
45
+ }, async ({ operationId }) => {
46
+ const d = store.GetEndpoint(operationId);
47
+ return d ? Text(d) : ErrorText(`Unknown operationId: ${operationId}`);
48
+ });
49
+ server.registerTool('get_elwis_schema', {
50
+ title: 'Get ELWIS schema',
51
+ description: 'Get one resolved JSON schema by component name. Refs are inlined up to maxDepth and the response is byte-bounded: depthUsed reports the depth actually served, truncatedRefs lists branches you can expand with another call, missingRefs lists refs absent from the spec.',
52
+ inputSchema: {
53
+ name: z.string().describe('Schema component name, e.g. from an endpoint requestSchema field'),
54
+ maxDepth: z.number().int().positive().max(6).optional().describe('Ref inlining depth to attempt (default 3); the server lowers it if the response would be too large'),
55
+ },
56
+ annotations: READ_ONLY,
57
+ }, async ({ name, maxDepth }) => {
58
+ const r = store.GetSchema(name, maxDepth ?? 3);
59
+ return r ? Text(r) : ErrorText(`Unknown schema: ${name}`);
60
+ });
61
+ server.registerTool('get_elwis_examples', {
62
+ title: 'Get ELWIS endpoint examples',
63
+ description: 'Get request/response examples and scenario steps for one operation.',
64
+ inputSchema: { operationId: z.string().describe('Operation id from search_elwis_api results') },
65
+ annotations: READ_ONLY,
66
+ }, async ({ operationId }) => {
67
+ const e = store.GetExamples(operationId);
68
+ return e ? Text(e) : ErrorText(`Unknown operationId: ${operationId}`);
69
+ });
70
+ return server;
71
+ }
72
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ const METHODS = ['get', 'post', 'put', 'patch', 'delete'];
2
+ export function WalkOperations(spec) {
3
+ const out = [];
4
+ const paths = spec.paths ?? {};
5
+ for (const path of Object.keys(paths)) {
6
+ for (const method of METHODS) {
7
+ const op = paths[path][method];
8
+ if (!op || !op.operationId)
9
+ continue;
10
+ out.push({
11
+ operationId: op.operationId,
12
+ method: method.toUpperCase(),
13
+ path,
14
+ tag: Array.isArray(op.tags) && op.tags.length > 0 ? op.tags[0] : 'untagged',
15
+ summary: op.summary ?? '',
16
+ });
17
+ }
18
+ }
19
+ return out;
20
+ }
21
+ //# sourceMappingURL=spec-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-walk.js","sourceRoot":"","sources":["../src/spec-walk.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAE1D,MAAM,UAAU,cAAc,CAAC,IAAS;IACtC,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,WAAW;gBAAE,SAAS;YACrC,GAAG,CAAC,IAAI,CAAC;gBACP,WAAW,EAAE,EAAE,CAAC,WAAW;gBAC3B,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;gBAC5B,IAAI;gBACJ,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;gBAC3E,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE;aAC1B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@softacus-software/elwis-docs-mcp",
3
+ "version": "0.1.1",
4
+ "description": "Read-only Model Context Protocol server for the ELWIS API documentation, generated from the OpenAPI specification.",
5
+ "type": "module",
6
+ "bin": {
7
+ "elwis-docs-mcp": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "data",
12
+ "README.md",
13
+ "CHANGELOG.md",
14
+ "LICENSE"
15
+ ],
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
19
+ "scripts": {
20
+ "build": "shx rm -rf dist && tsc && shx chmod +x dist/index.js",
21
+ "prepare": "npm run build",
22
+ "watch": "tsc --watch",
23
+ "lint": "eslint .",
24
+ "export-spec": "tsx scripts/export-spec.ts",
25
+ "generate": "tsx src/generate.ts data/openapi.json",
26
+ "refresh": "npm run export-spec && npm run generate",
27
+ "check-drift": "tsx scripts/check-drift.ts",
28
+ "start": "node dist/index.js",
29
+ "dev": "tsx src/index.ts",
30
+ "test": "tsx --test test/*.test.ts",
31
+ "prepack": "npm run build"
32
+ },
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.29.0",
35
+ "zod": "^4.4.3"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/js": "^10.0.1",
39
+ "@types/node": "^26.0.1",
40
+ "eslint": "^10.6.0",
41
+ "shx": "^0.4.0",
42
+ "tsx": "^4.22.4",
43
+ "typescript": "^6.0.3",
44
+ "typescript-eslint": "^8.62.1"
45
+ },
46
+ "publishConfig": {
47
+ "access": "restricted"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://git.softacus.com/elwis/readonly-mcp.git"
52
+ },
53
+ "bugs": {
54
+ "url": "https://git.softacus.com/elwis/readonly-mcp/-/issues"
55
+ },
56
+ "homepage": "https://git.softacus.com/elwis/readonly-mcp#readme",
57
+ "keywords": [
58
+ "modelcontextprotocol",
59
+ "mcp",
60
+ "elwis",
61
+ "softacus",
62
+ "openapi",
63
+ "api-documentation"
64
+ ],
65
+ "license": "UNLICENSED"
66
+ }