@runcontext/mcp 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,423 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/server.ts
2
+ var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
3
+ var _zod = require('zod');
4
+
5
+ // src/resources/manifest.ts
6
+ function readManifest(manifest) {
7
+ return {
8
+ contents: [
9
+ {
10
+ uri: "context://manifest",
11
+ mimeType: "application/json",
12
+ text: JSON.stringify(manifest, null, 2)
13
+ }
14
+ ]
15
+ };
16
+ }
17
+
18
+ // src/resources/concept.ts
19
+ function readConcept(manifest, id) {
20
+ const concept = manifest.concepts.find((c) => c.id === id);
21
+ if (!concept) {
22
+ return {
23
+ contents: [
24
+ {
25
+ uri: `context://concept/${id}`,
26
+ mimeType: "application/json",
27
+ text: JSON.stringify({ error: `Concept not found: ${id}` })
28
+ }
29
+ ]
30
+ };
31
+ }
32
+ return {
33
+ contents: [
34
+ {
35
+ uri: `context://concept/${id}`,
36
+ mimeType: "application/json",
37
+ text: JSON.stringify(concept, null, 2)
38
+ }
39
+ ]
40
+ };
41
+ }
42
+ function listConcepts(manifest) {
43
+ return {
44
+ resources: manifest.concepts.map((c) => ({
45
+ uri: `context://concept/${c.id}`,
46
+ name: c.id,
47
+ description: c.definition,
48
+ mimeType: "application/json"
49
+ }))
50
+ };
51
+ }
52
+
53
+ // src/resources/product.ts
54
+ function readProduct(manifest, id) {
55
+ const product = manifest.products.find((p) => p.id === id);
56
+ if (!product) {
57
+ return {
58
+ contents: [
59
+ {
60
+ uri: `context://product/${id}`,
61
+ mimeType: "application/json",
62
+ text: JSON.stringify({ error: `Product not found: ${id}` })
63
+ }
64
+ ]
65
+ };
66
+ }
67
+ return {
68
+ contents: [
69
+ {
70
+ uri: `context://product/${id}`,
71
+ mimeType: "application/json",
72
+ text: JSON.stringify(product, null, 2)
73
+ }
74
+ ]
75
+ };
76
+ }
77
+ function listProducts(manifest) {
78
+ return {
79
+ resources: manifest.products.map((p) => ({
80
+ uri: `context://product/${p.id}`,
81
+ name: p.id,
82
+ description: p.description,
83
+ mimeType: "application/json"
84
+ }))
85
+ };
86
+ }
87
+
88
+ // src/resources/policy.ts
89
+ function readPolicy(manifest, id) {
90
+ const policy = manifest.policies.find((p) => p.id === id);
91
+ if (!policy) {
92
+ return {
93
+ contents: [
94
+ {
95
+ uri: `context://policy/${id}`,
96
+ mimeType: "application/json",
97
+ text: JSON.stringify({ error: `Policy not found: ${id}` })
98
+ }
99
+ ]
100
+ };
101
+ }
102
+ return {
103
+ contents: [
104
+ {
105
+ uri: `context://policy/${id}`,
106
+ mimeType: "application/json",
107
+ text: JSON.stringify(policy, null, 2)
108
+ }
109
+ ]
110
+ };
111
+ }
112
+ function listPolicies(manifest) {
113
+ return {
114
+ resources: manifest.policies.map((p) => ({
115
+ uri: `context://policy/${p.id}`,
116
+ name: p.id,
117
+ description: p.description,
118
+ mimeType: "application/json"
119
+ }))
120
+ };
121
+ }
122
+
123
+ // src/resources/glossary.ts
124
+ function readGlossary(manifest) {
125
+ const glossary = manifest.terms.map((t) => ({
126
+ id: t.id,
127
+ definition: t.definition,
128
+ synonyms: _nullishCoalesce(t.synonyms, () => ( [])),
129
+ mapsTo: _nullishCoalesce(t.mapsTo, () => ( []))
130
+ }));
131
+ return {
132
+ contents: [
133
+ {
134
+ uri: "context://glossary",
135
+ mimeType: "application/json",
136
+ text: JSON.stringify(glossary, null, 2)
137
+ }
138
+ ]
139
+ };
140
+ }
141
+
142
+ // src/tools/search.ts
143
+ function searchContext(manifest, query) {
144
+ const q = query.toLowerCase();
145
+ const items = [
146
+ ...manifest.concepts.map((c) => ({
147
+ kind: "concept",
148
+ id: c.id,
149
+ definition: c.definition,
150
+ tags: c.tags
151
+ })),
152
+ ...manifest.products.map((p) => ({
153
+ kind: "product",
154
+ id: p.id,
155
+ description: p.description,
156
+ tags: p.tags
157
+ })),
158
+ ...manifest.policies.map((p) => ({
159
+ kind: "policy",
160
+ id: p.id,
161
+ description: p.description,
162
+ tags: p.tags
163
+ })),
164
+ ...manifest.entities.map((e) => ({
165
+ kind: "entity",
166
+ id: e.id,
167
+ definition: e.definition,
168
+ tags: e.tags
169
+ })),
170
+ ...manifest.terms.map((t) => ({
171
+ kind: "term",
172
+ id: t.id,
173
+ definition: t.definition,
174
+ tags: t.tags
175
+ }))
176
+ ];
177
+ const matches = items.filter((item) => {
178
+ if (item.id.toLowerCase().includes(q)) return true;
179
+ if (item.definition && item.definition.toLowerCase().includes(q)) return true;
180
+ if (item.description && item.description.toLowerCase().includes(q)) return true;
181
+ if (item.tags && item.tags.some((tag) => tag.toLowerCase().includes(q))) return true;
182
+ return false;
183
+ });
184
+ return {
185
+ content: [
186
+ {
187
+ type: "text",
188
+ text: JSON.stringify({ query, resultCount: matches.length, results: matches }, null, 2)
189
+ }
190
+ ]
191
+ };
192
+ }
193
+
194
+ // src/tools/explain.ts
195
+ function explainNode(manifest, id) {
196
+ const index = manifest.indexes.byId[id];
197
+ if (!index) {
198
+ return {
199
+ content: [
200
+ {
201
+ type: "text",
202
+ text: JSON.stringify({ error: `Node not found: ${id}` }, null, 2)
203
+ }
204
+ ]
205
+ };
206
+ }
207
+ let node;
208
+ switch (index.kind) {
209
+ case "concept":
210
+ node = manifest.concepts[index.index];
211
+ break;
212
+ case "product":
213
+ node = manifest.products[index.index];
214
+ break;
215
+ case "policy":
216
+ node = manifest.policies[index.index];
217
+ break;
218
+ case "entity":
219
+ node = manifest.entities[index.index];
220
+ break;
221
+ case "term":
222
+ node = manifest.terms[index.index];
223
+ break;
224
+ case "owner":
225
+ node = manifest.owners[index.index];
226
+ break;
227
+ }
228
+ if (!node) {
229
+ return {
230
+ content: [
231
+ {
232
+ type: "text",
233
+ text: JSON.stringify({ error: `Node data not found for: ${id}` }, null, 2)
234
+ }
235
+ ]
236
+ };
237
+ }
238
+ const dependencies = [];
239
+ const dependsOn = node.dependsOn;
240
+ if (dependsOn) {
241
+ for (const depId of dependsOn) {
242
+ const depIndex = manifest.indexes.byId[depId];
243
+ if (depIndex) {
244
+ dependencies.push({ id: depId, kind: depIndex.kind });
245
+ }
246
+ }
247
+ }
248
+ const dependents = [];
249
+ for (const concept of manifest.concepts) {
250
+ if (_optionalChain([concept, 'access', _ => _.dependsOn, 'optionalAccess', _2 => _2.includes, 'call', _3 => _3(id)])) {
251
+ dependents.push({ id: concept.id, kind: "concept" });
252
+ }
253
+ }
254
+ const applicablePolicies = [];
255
+ const nodeTags = _nullishCoalesce(node.tags, () => ( []));
256
+ for (const policy of manifest.policies) {
257
+ const applies = policy.rules.some((rule) => {
258
+ if (_optionalChain([rule, 'access', _4 => _4.when, 'access', _5 => _5.conceptIds, 'optionalAccess', _6 => _6.includes, 'call', _7 => _7(id)])) return true;
259
+ if (_optionalChain([rule, 'access', _8 => _8.when, 'access', _9 => _9.tagsAny, 'optionalAccess', _10 => _10.some, 'call', _11 => _11((tag) => nodeTags.includes(tag))])) return true;
260
+ return false;
261
+ });
262
+ if (applies) {
263
+ applicablePolicies.push({ id: policy.id, description: policy.description });
264
+ }
265
+ }
266
+ let ownerInfo;
267
+ const ownerId = node.owner;
268
+ if (ownerId) {
269
+ ownerInfo = manifest.owners.find((o) => o.id === ownerId);
270
+ }
271
+ const result = {
272
+ kind: index.kind,
273
+ node,
274
+ dependencies,
275
+ dependents,
276
+ applicablePolicies,
277
+ owner: _nullishCoalesce(ownerInfo, () => ( null))
278
+ };
279
+ return {
280
+ content: [
281
+ {
282
+ type: "text",
283
+ text: JSON.stringify(result, null, 2)
284
+ }
285
+ ]
286
+ };
287
+ }
288
+
289
+ // src/tools/validate.ts
290
+ async function validateContext(rootDir) {
291
+ try {
292
+ const { compile, LintEngine, ALL_RULES } = await Promise.resolve().then(() => _interopRequireWildcard(require("@runcontext/core")));
293
+ const contextDir = _nullishCoalesce(rootDir, () => ( process.cwd()));
294
+ const compileResult = await compile({
295
+ contextDir,
296
+ config: {}
297
+ });
298
+ const engine = new LintEngine();
299
+ for (const rule of ALL_RULES) {
300
+ engine.register(rule);
301
+ }
302
+ const lintDiagnostics = engine.run(compileResult.graph);
303
+ const allDiagnostics = [...compileResult.diagnostics, ...lintDiagnostics];
304
+ const summary = {
305
+ contextDir,
306
+ compileDiagnostics: compileResult.diagnostics.length,
307
+ lintDiagnostics: lintDiagnostics.length,
308
+ totalDiagnostics: allDiagnostics.length,
309
+ errors: allDiagnostics.filter((d) => d.severity === "error").length,
310
+ warnings: allDiagnostics.filter((d) => d.severity === "warning").length,
311
+ diagnostics: allDiagnostics
312
+ };
313
+ return {
314
+ content: [
315
+ {
316
+ type: "text",
317
+ text: JSON.stringify(summary, null, 2)
318
+ }
319
+ ]
320
+ };
321
+ } catch (err) {
322
+ const message = err instanceof Error ? err.message : String(err);
323
+ return {
324
+ content: [
325
+ {
326
+ type: "text",
327
+ text: JSON.stringify({ error: `Validation failed: ${message}` }, null, 2)
328
+ }
329
+ ],
330
+ isError: true
331
+ };
332
+ }
333
+ }
334
+
335
+ // src/server.ts
336
+ function createContextMcpServer(manifest) {
337
+ const server = new (0, _mcpjs.McpServer)(
338
+ {
339
+ name: "contextkit",
340
+ version: "0.1.0"
341
+ },
342
+ {
343
+ capabilities: {
344
+ resources: {},
345
+ tools: {}
346
+ }
347
+ }
348
+ );
349
+ server.resource(
350
+ "manifest",
351
+ "context://manifest",
352
+ { description: "The full ContextKit manifest", mimeType: "application/json" },
353
+ () => readManifest(manifest)
354
+ );
355
+ server.resource(
356
+ "glossary",
357
+ "context://glossary",
358
+ { description: "Glossary of all terms", mimeType: "application/json" },
359
+ () => readGlossary(manifest)
360
+ );
361
+ server.resource(
362
+ "concept",
363
+ new (0, _mcpjs.ResourceTemplate)("context://concept/{id}", {
364
+ list: () => listConcepts(manifest)
365
+ }),
366
+ { description: "A single concept by ID", mimeType: "application/json" },
367
+ (uri, variables) => readConcept(manifest, String(variables.id))
368
+ );
369
+ server.resource(
370
+ "product",
371
+ new (0, _mcpjs.ResourceTemplate)("context://product/{id}", {
372
+ list: () => listProducts(manifest)
373
+ }),
374
+ { description: "A single product by ID", mimeType: "application/json" },
375
+ (uri, variables) => readProduct(manifest, String(variables.id))
376
+ );
377
+ server.resource(
378
+ "policy",
379
+ new (0, _mcpjs.ResourceTemplate)("context://policy/{id}", {
380
+ list: () => listPolicies(manifest)
381
+ }),
382
+ { description: "A single policy by ID", mimeType: "application/json" },
383
+ (uri, variables) => readPolicy(manifest, String(variables.id))
384
+ );
385
+ server.tool(
386
+ "context_search",
387
+ "Search across all concepts, products, policies, entities, and terms",
388
+ { query: _zod.z.string().describe("The search query (case-insensitive substring match)") },
389
+ ({ query }) => searchContext(manifest, query)
390
+ );
391
+ server.tool(
392
+ "context_explain",
393
+ "Get comprehensive info about a node: the node itself, dependencies, dependents, applicable policies, and owner",
394
+ { id: _zod.z.string().describe("The ID of the node to explain") },
395
+ ({ id }) => explainNode(manifest, id)
396
+ );
397
+ server.tool(
398
+ "context_validate",
399
+ "Run compile and lint validation on the context directory and return diagnostics",
400
+ { rootDir: _zod.z.string().optional().describe("Root directory to validate (defaults to cwd)") },
401
+ async ({ rootDir }) => validateContext(rootDir)
402
+ );
403
+ return server;
404
+ }
405
+
406
+ // src/index.ts
407
+ var MCP_VERSION = "0.1.0";
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+ exports.MCP_VERSION = MCP_VERSION; exports.createContextMcpServer = createContextMcpServer; exports.explainNode = explainNode; exports.listConcepts = listConcepts; exports.listPolicies = listPolicies; exports.listProducts = listProducts; exports.readConcept = readConcept; exports.readGlossary = readGlossary; exports.readManifest = readManifest; exports.readPolicy = readPolicy; exports.readProduct = readProduct; exports.searchContext = searchContext; exports.validateContext = validateContext;
423
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/erickittelson/Desktop/ContextKit/packages/mcp/dist/index.cjs","../src/server.ts","../src/resources/manifest.ts","../src/resources/concept.ts","../src/resources/product.ts","../src/resources/policy.ts","../src/resources/glossary.ts","../src/tools/search.ts","../src/tools/explain.ts","../src/tools/validate.ts","../src/index.ts"],"names":[],"mappings":"AAAA;ACAA,gEAA4C;AAC5C,0BAAkB;ADElB;AACA;AEEO,SAAS,YAAA,CAAa,QAAA,EAAwC;AACnE,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR;AAAA,QACE,GAAA,EAAK,oBAAA;AAAA,QACL,QAAA,EAAU,kBAAA;AAAA,QACV,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF,CAAA;AACF;AFAA;AACA;AGXO,SAAS,WAAA,CAAY,QAAA,EAAoB,EAAA,EAAgC;AAC9E,EAAA,MAAM,QAAA,EAAuC,QAAA,CAAS,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAA,GAAM,CAAA,CAAE,GAAA,IAAO,EAAE,CAAA;AACtF,EAAA,GAAA,CAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO;AAAA,MACL,QAAA,EAAU;AAAA,QACR;AAAA,UACE,GAAA,EAAK,CAAA,kBAAA,EAAqB,EAAE,CAAA,CAAA;AAClB,UAAA;AACa,UAAA;AACzB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACO,EAAA;AACK,IAAA;AACR,MAAA;AAC8B,QAAA;AAClB,QAAA;AACoB,QAAA;AAChC,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAKiD;AACxC,EAAA;AAC6B,IAAA;AACF,MAAA;AACtB,MAAA;AACO,MAAA;AACL,MAAA;AACV,IAAA;AACJ,EAAA;AACF;AHSuC;AACA;AI9CyC;AACf,EAAA;AACjD,EAAA;AACL,IAAA;AACK,MAAA;AACR,QAAA;AAC8B,UAAA;AAClB,UAAA;AACa,UAAA;AACzB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACO,EAAA;AACK,IAAA;AACR,MAAA;AAC8B,QAAA;AAClB,QAAA;AACoB,QAAA;AAChC,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAKiD;AACxC,EAAA;AAC6B,IAAA;AACF,MAAA;AACtB,MAAA;AACO,MAAA;AACL,MAAA;AACV,IAAA;AACJ,EAAA;AACF;AJ4CuC;AACA;AKjFwC;AAChB,EAAA;AAChD,EAAA;AACJ,IAAA;AACK,MAAA;AACR,QAAA;AAC6B,UAAA;AACjB,UAAA;AACa,UAAA;AACzB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACO,EAAA;AACK,IAAA;AACR,MAAA;AAC6B,QAAA;AACjB,QAAA;AACmB,QAAA;AAC/B,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAKiD;AACxC,EAAA;AAC6B,IAAA;AACH,MAAA;AACrB,MAAA;AACO,MAAA;AACL,MAAA;AACV,IAAA;AACJ,EAAA;AACF;AL+EuC;AACA;AMpH8B;AAC9B,EAAA;AAC7B,IAAA;AACQ,IAAA;AACW,IAAA;AACJ,IAAA;AACrB,EAAA;AAEK,EAAA;AACK,IAAA;AACR,MAAA;AACO,QAAA;AACK,QAAA;AACqB,QAAA;AACjC,MAAA;AACF,IAAA;AACF,EAAA;AACF;ANqHuC;AACA;AO7HW;AACpB,EAAA;AAEI,EAAA;AACG,IAAA;AACzB,MAAA;AACA,MAAA;AACQ,MAAA;AACN,MAAA;AACR,IAAA;AAC+B,IAAA;AACzB,MAAA;AACA,MAAA;AACS,MAAA;AACP,MAAA;AACR,IAAA;AAC+B,IAAA;AACzB,MAAA;AACA,MAAA;AACS,MAAA;AACP,MAAA;AACR,IAAA;AAC+B,IAAA;AACzB,MAAA;AACA,MAAA;AACQ,MAAA;AACN,MAAA;AACR,IAAA;AAC4B,IAAA;AACtB,MAAA;AACA,MAAA;AACQ,MAAA;AACN,MAAA;AACR,IAAA;AACJ,EAAA;AAE8B,EAAA;AACO,IAAA;AACP,IAAA;AACC,IAAA;AACI,IAAA;AAC1B,IAAA;AACR,EAAA;AAEM,EAAA;AACI,IAAA;AACP,MAAA;AACQ,QAAA;AACwB,QAAA;AAChC,MAAA;AACF,IAAA;AACF,EAAA;AACF;AP4HuC;AACA;AQzLqC;AACtC,EAAA;AACxB,EAAA;AACH,IAAA;AACI,MAAA;AACP,QAAA;AACQ,UAAA;AACiB,UAAA;AACzB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAGI,EAAA;AACgB,EAAA;AACb,IAAA;AAC4B,MAAA;AAC/B,MAAA;AACG,IAAA;AAC4B,MAAA;AAC/B,MAAA;AACG,IAAA;AAC4B,MAAA;AAC/B,MAAA;AACG,IAAA;AAC4B,MAAA;AAC/B,MAAA;AACG,IAAA;AAC8B,MAAA;AACjC,MAAA;AACG,IAAA;AAC0B,MAAA;AAC7B,MAAA;AACJ,EAAA;AAEW,EAAA;AACF,IAAA;AACI,MAAA;AACP,QAAA;AACQ,UAAA;AACiB,UAAA;AACzB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAG2D,EAAA;AACN,EAAA;AACtC,EAAA;AACkB,IAAA;AACH,MAAA;AACZ,MAAA;AACmB,QAAA;AACjC,MAAA;AACF,IAAA;AACF,EAAA;AAGyD,EAAA;AAC1B,EAAA;AACK,IAAA;AACF,MAAA;AAChC,IAAA;AACF,EAAA;AAGwE,EAAA;AAChB,EAAA;AAC1B,EAAA;AACO,IAAA;AACP,MAAA;AACG,MAAA;AACtB,MAAA;AACR,IAAA;AACY,IAAA;AACmB,MAAA;AAChC,IAAA;AACF,EAAA;AAGI,EAAA;AACyC,EAAA;AAChC,EAAA;AACuB,IAAA;AACpC,EAAA;AAEe,EAAA;AACD,IAAA;AACZ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACoB,IAAA;AACtB,EAAA;AAEO,EAAA;AACI,IAAA;AACP,MAAA;AACQ,QAAA;AACuB,QAAA;AAC/B,MAAA;AACF,IAAA;AACF,EAAA;AACF;AR8KuC;AACA;AS3RD;AAChC,EAAA;AAE2B,IAAA;AAEC,IAAA;AAGF,IAAA;AAC1B,MAAA;AACS,MAAA;AACV,IAAA;AAG6B,IAAA;AACA,IAAA;AACR,MAAA;AACtB,IAAA;AACmC,IAAA;AAGR,IAAA;AAEX,IAAA;AACd,MAAA;AACoB,MAAA;AACa,MAAA;AACA,MAAA;AACF,MAAA;AACE,MAAA;AACpB,MAAA;AACf,IAAA;AAEO,IAAA;AACI,MAAA;AACP,QAAA;AACQ,UAAA;AACe,UAAA;AACvB,QAAA;AACF,MAAA;AACF,IAAA;AACY,EAAA;AACmB,IAAA;AACxB,IAAA;AACI,MAAA;AACP,QAAA;AACQ,UAAA;AACiB,UAAA;AACzB,QAAA;AACF,MAAA;AACS,MAAA;AACX,IAAA;AACF,EAAA;AACF;ATmRuC;AACA;AC9TA;AAClB,EAAA;AACjB,IAAA;AACQ,MAAA;AACG,MAAA;AACX,IAAA;AACA,IAAA;AACgB,MAAA;AACA,QAAA;AACJ,QAAA;AACV,MAAA;AACF,IAAA;AACF,EAAA;AAKO,EAAA;AACL,IAAA;AACA,IAAA;AACe,IAAA;AACY,IAAA;AAC7B,EAAA;AAGO,EAAA;AACL,IAAA;AACA,IAAA;AACe,IAAA;AACY,IAAA;AAC7B,EAAA;AAKO,EAAA;AACL,IAAA;AACqB,IAAA;AACc,MAAA;AAClC,IAAA;AACc,IAAA;AACiB,IAAA;AAClC,EAAA;AAGO,EAAA;AACL,IAAA;AACqB,IAAA;AACc,MAAA;AAClC,IAAA;AACc,IAAA;AACiB,IAAA;AAClC,EAAA;AAGO,EAAA;AACL,IAAA;AACqB,IAAA;AACc,MAAA;AAClC,IAAA;AACc,IAAA;AACgB,IAAA;AACjC,EAAA;AAKO,EAAA;AACL,IAAA;AACA,IAAA;AAC6B,IAAA;AACA,IAAA;AAC/B,EAAA;AAGO,EAAA;AACL,IAAA;AACA,IAAA;AAC0B,IAAA;AACQ,IAAA;AACpC,EAAA;AAGO,EAAA;AACL,IAAA;AACA,IAAA;AACiC,IAAA;AACV,IAAA;AACzB,EAAA;AAEO,EAAA;AACT;ADySuC;AACA;AUrZZ;AVuZY;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/erickittelson/Desktop/ContextKit/packages/mcp/dist/index.cjs","sourcesContent":[null,"import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { Manifest } from '@runcontext/core';\n\nimport { readManifest } from './resources/manifest.js';\nimport { readConcept, listConcepts } from './resources/concept.js';\nimport { readProduct, listProducts } from './resources/product.js';\nimport { readPolicy, listPolicies } from './resources/policy.js';\nimport { readGlossary } from './resources/glossary.js';\nimport { searchContext } from './tools/search.js';\nimport { explainNode } from './tools/explain.js';\nimport { validateContext } from './tools/validate.js';\n\n/**\n * Creates an MCP server wired up with all ContextKit resources and tools.\n */\nexport function createContextMcpServer(manifest: Manifest): McpServer {\n const server = new McpServer(\n {\n name: 'contextkit',\n version: '0.1.0',\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n },\n );\n\n // ── Static Resources ──────────────────────────────────────────────\n\n // context://manifest — full manifest\n server.resource(\n 'manifest',\n 'context://manifest',\n { description: 'The full ContextKit manifest', mimeType: 'application/json' },\n () => readManifest(manifest),\n );\n\n // context://glossary — all terms\n server.resource(\n 'glossary',\n 'context://glossary',\n { description: 'Glossary of all terms', mimeType: 'application/json' },\n () => readGlossary(manifest),\n );\n\n // ── Template Resources ────────────────────────────────────────────\n\n // context://concept/{id}\n server.resource(\n 'concept',\n new ResourceTemplate('context://concept/{id}', {\n list: () => listConcepts(manifest),\n }),\n { description: 'A single concept by ID', mimeType: 'application/json' },\n (uri, variables) => readConcept(manifest, String(variables.id)),\n );\n\n // context://product/{id}\n server.resource(\n 'product',\n new ResourceTemplate('context://product/{id}', {\n list: () => listProducts(manifest),\n }),\n { description: 'A single product by ID', mimeType: 'application/json' },\n (uri, variables) => readProduct(manifest, String(variables.id)),\n );\n\n // context://policy/{id}\n server.resource(\n 'policy',\n new ResourceTemplate('context://policy/{id}', {\n list: () => listPolicies(manifest),\n }),\n { description: 'A single policy by ID', mimeType: 'application/json' },\n (uri, variables) => readPolicy(manifest, String(variables.id)),\n );\n\n // ── Tools ─────────────────────────────────────────────────────────\n\n // context_search — search across all nodes\n server.tool(\n 'context_search',\n 'Search across all concepts, products, policies, entities, and terms',\n { query: z.string().describe('The search query (case-insensitive substring match)') },\n ({ query }) => searchContext(manifest, query),\n );\n\n // context_explain — explain a node by ID\n server.tool(\n 'context_explain',\n 'Get comprehensive info about a node: the node itself, dependencies, dependents, applicable policies, and owner',\n { id: z.string().describe('The ID of the node to explain') },\n ({ id }) => explainNode(manifest, id),\n );\n\n // context_validate — run compile + lint\n server.tool(\n 'context_validate',\n 'Run compile and lint validation on the context directory and return diagnostics',\n { rootDir: z.string().optional().describe('Root directory to validate (defaults to cwd)') },\n async ({ rootDir }) => validateContext(rootDir),\n );\n\n return server;\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns the full manifest as a JSON resource.\n */\nexport function readManifest(manifest: Manifest): ReadResourceResult {\n return {\n contents: [\n {\n uri: 'context://manifest',\n mimeType: 'application/json',\n text: JSON.stringify(manifest, null, 2),\n },\n ],\n };\n}\n","import type { Manifest, ManifestConcept } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single concept by ID from the manifest.\n */\nexport function readConcept(manifest: Manifest, id: string): ReadResourceResult {\n const concept: ManifestConcept | undefined = manifest.concepts.find((c) => c.id === id);\n if (!concept) {\n return {\n contents: [\n {\n uri: `context://concept/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Concept not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://concept/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(concept, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all concepts as resources.\n */\nexport function listConcepts(manifest: Manifest) {\n return {\n resources: manifest.concepts.map((c) => ({\n uri: `context://concept/${c.id}`,\n name: c.id,\n description: c.definition,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest, ManifestProduct } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single product by ID from the manifest.\n */\nexport function readProduct(manifest: Manifest, id: string): ReadResourceResult {\n const product: ManifestProduct | undefined = manifest.products.find((p) => p.id === id);\n if (!product) {\n return {\n contents: [\n {\n uri: `context://product/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Product not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://product/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(product, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all products as resources.\n */\nexport function listProducts(manifest: Manifest) {\n return {\n resources: manifest.products.map((p) => ({\n uri: `context://product/${p.id}`,\n name: p.id,\n description: p.description,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest, ManifestPolicy } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single policy by ID from the manifest.\n */\nexport function readPolicy(manifest: Manifest, id: string): ReadResourceResult {\n const policy: ManifestPolicy | undefined = manifest.policies.find((p) => p.id === id);\n if (!policy) {\n return {\n contents: [\n {\n uri: `context://policy/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Policy not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://policy/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(policy, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all policies as resources.\n */\nexport function listPolicies(manifest: Manifest) {\n return {\n resources: manifest.policies.map((p) => ({\n uri: `context://policy/${p.id}`,\n name: p.id,\n description: p.description,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns all terms as a glossary JSON resource.\n */\nexport function readGlossary(manifest: Manifest): ReadResourceResult {\n const glossary = manifest.terms.map((t) => ({\n id: t.id,\n definition: t.definition,\n synonyms: t.synonyms ?? [],\n mapsTo: t.mapsTo ?? [],\n }));\n\n return {\n contents: [\n {\n uri: 'context://glossary',\n mimeType: 'application/json',\n text: JSON.stringify(glossary, null, 2),\n },\n ],\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\ninterface SearchableItem {\n kind: string;\n id: string;\n definition?: string;\n description?: string;\n tags?: string[];\n}\n\n/**\n * Searches across all concepts, products, policies, entities, and terms\n * in the manifest. Matches case-insensitively on id, definition/description,\n * and tags.\n */\nexport function searchContext(manifest: Manifest, query: string): CallToolResult {\n const q = query.toLowerCase();\n\n const items: SearchableItem[] = [\n ...manifest.concepts.map((c) => ({\n kind: 'concept' as const,\n id: c.id,\n definition: c.definition,\n tags: c.tags,\n })),\n ...manifest.products.map((p) => ({\n kind: 'product' as const,\n id: p.id,\n description: p.description,\n tags: p.tags,\n })),\n ...manifest.policies.map((p) => ({\n kind: 'policy' as const,\n id: p.id,\n description: p.description,\n tags: p.tags,\n })),\n ...manifest.entities.map((e) => ({\n kind: 'entity' as const,\n id: e.id,\n definition: e.definition,\n tags: e.tags,\n })),\n ...manifest.terms.map((t) => ({\n kind: 'term' as const,\n id: t.id,\n definition: t.definition,\n tags: t.tags,\n })),\n ];\n\n const matches = items.filter((item) => {\n if (item.id.toLowerCase().includes(q)) return true;\n if (item.definition && item.definition.toLowerCase().includes(q)) return true;\n if (item.description && item.description.toLowerCase().includes(q)) return true;\n if (item.tags && item.tags.some((tag) => tag.toLowerCase().includes(q))) return true;\n return false;\n });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ query, resultCount: matches.length, results: matches }, null, 2),\n },\n ],\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Finds a node by ID in the manifest and returns comprehensive info:\n * the node itself, its dependencies, dependents, applicable policies,\n * and owner info.\n */\nexport function explainNode(manifest: Manifest, id: string): CallToolResult {\n const index = manifest.indexes.byId[id];\n if (!index) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Node not found: ${id}` }, null, 2),\n },\n ],\n };\n }\n\n // Retrieve the node from the appropriate collection\n let node: Record<string, unknown> | undefined;\n switch (index.kind) {\n case 'concept':\n node = manifest.concepts[index.index] as unknown as Record<string, unknown>;\n break;\n case 'product':\n node = manifest.products[index.index] as unknown as Record<string, unknown>;\n break;\n case 'policy':\n node = manifest.policies[index.index] as unknown as Record<string, unknown>;\n break;\n case 'entity':\n node = manifest.entities[index.index] as unknown as Record<string, unknown>;\n break;\n case 'term':\n node = manifest.terms[index.index] as unknown as Record<string, unknown>;\n break;\n case 'owner':\n node = manifest.owners[index.index] as unknown as Record<string, unknown>;\n break;\n }\n\n if (!node) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Node data not found for: ${id}` }, null, 2),\n },\n ],\n };\n }\n\n // Find dependencies (concepts that this node dependsOn)\n const dependencies: Array<{ id: string; kind: string }> = [];\n const dependsOn = (node as { dependsOn?: string[] }).dependsOn;\n if (dependsOn) {\n for (const depId of dependsOn) {\n const depIndex = manifest.indexes.byId[depId];\n if (depIndex) {\n dependencies.push({ id: depId, kind: depIndex.kind });\n }\n }\n }\n\n // Find dependents (concepts that depend on this node)\n const dependents: Array<{ id: string; kind: string }> = [];\n for (const concept of manifest.concepts) {\n if (concept.dependsOn?.includes(id)) {\n dependents.push({ id: concept.id, kind: 'concept' });\n }\n }\n\n // Find applicable policies (policies whose rules reference this node's tags or ID)\n const applicablePolicies: Array<{ id: string; description: string }> = [];\n const nodeTags = (node as { tags?: string[] }).tags ?? [];\n for (const policy of manifest.policies) {\n const applies = policy.rules.some((rule) => {\n if (rule.when.conceptIds?.includes(id)) return true;\n if (rule.when.tagsAny?.some((tag) => nodeTags.includes(tag))) return true;\n return false;\n });\n if (applies) {\n applicablePolicies.push({ id: policy.id, description: policy.description });\n }\n }\n\n // Find owner info\n let ownerInfo: Record<string, unknown> | undefined;\n const ownerId = (node as { owner?: string }).owner;\n if (ownerId) {\n ownerInfo = manifest.owners.find((o) => o.id === ownerId) as unknown as Record<string, unknown>;\n }\n\n const result = {\n kind: index.kind,\n node,\n dependencies,\n dependents,\n applicablePolicies,\n owner: ownerInfo ?? null,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Runs the compile + lint pipeline on a context directory and returns diagnostics.\n */\nexport async function validateContext(rootDir?: string): Promise<CallToolResult> {\n try {\n // Dynamic import to avoid circular dependency issues at load time\n const { compile, LintEngine, ALL_RULES } = await import('@runcontext/core');\n\n const contextDir = rootDir ?? process.cwd();\n\n // Run the compiler pipeline\n const compileResult = await compile({\n contextDir,\n config: {},\n });\n\n // Run the linter\n const engine = new LintEngine();\n for (const rule of ALL_RULES) {\n engine.register(rule);\n }\n const lintDiagnostics = engine.run(compileResult.graph);\n\n // Combine diagnostics\n const allDiagnostics = [...compileResult.diagnostics, ...lintDiagnostics];\n\n const summary = {\n contextDir,\n compileDiagnostics: compileResult.diagnostics.length,\n lintDiagnostics: lintDiagnostics.length,\n totalDiagnostics: allDiagnostics.length,\n errors: allDiagnostics.filter((d) => d.severity === 'error').length,\n warnings: allDiagnostics.filter((d) => d.severity === 'warning').length,\n diagnostics: allDiagnostics,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Validation failed: ${message}` }, null, 2),\n },\n ],\n isError: true,\n };\n }\n}\n","export const MCP_VERSION = '0.1.0';\n\nexport { createContextMcpServer } from './server.js';\n\n// Re-export resource handlers for direct testing / reuse\nexport { readManifest } from './resources/manifest.js';\nexport { readConcept, listConcepts } from './resources/concept.js';\nexport { readProduct, listProducts } from './resources/product.js';\nexport { readPolicy, listPolicies } from './resources/policy.js';\nexport { readGlossary } from './resources/glossary.js';\n\n// Re-export tool handlers for direct testing / reuse\nexport { searchContext } from './tools/search.js';\nexport { explainNode } from './tools/explain.js';\nexport { validateContext } from './tools/validate.js';\n"]}
@@ -0,0 +1,89 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { Manifest } from '@runcontext/core';
3
+ import { ReadResourceResult, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
4
+
5
+ /**
6
+ * Creates an MCP server wired up with all ContextKit resources and tools.
7
+ */
8
+ declare function createContextMcpServer(manifest: Manifest): McpServer;
9
+
10
+ /**
11
+ * Returns the full manifest as a JSON resource.
12
+ */
13
+ declare function readManifest(manifest: Manifest): ReadResourceResult;
14
+
15
+ /**
16
+ * Returns a single concept by ID from the manifest.
17
+ */
18
+ declare function readConcept(manifest: Manifest, id: string): ReadResourceResult;
19
+ /**
20
+ * Lists all concepts as resources.
21
+ */
22
+ declare function listConcepts(manifest: Manifest): {
23
+ resources: {
24
+ uri: string;
25
+ name: string;
26
+ description: string;
27
+ mimeType: "application/json";
28
+ }[];
29
+ };
30
+
31
+ /**
32
+ * Returns a single product by ID from the manifest.
33
+ */
34
+ declare function readProduct(manifest: Manifest, id: string): ReadResourceResult;
35
+ /**
36
+ * Lists all products as resources.
37
+ */
38
+ declare function listProducts(manifest: Manifest): {
39
+ resources: {
40
+ uri: string;
41
+ name: string;
42
+ description: string;
43
+ mimeType: "application/json";
44
+ }[];
45
+ };
46
+
47
+ /**
48
+ * Returns a single policy by ID from the manifest.
49
+ */
50
+ declare function readPolicy(manifest: Manifest, id: string): ReadResourceResult;
51
+ /**
52
+ * Lists all policies as resources.
53
+ */
54
+ declare function listPolicies(manifest: Manifest): {
55
+ resources: {
56
+ uri: string;
57
+ name: string;
58
+ description: string;
59
+ mimeType: "application/json";
60
+ }[];
61
+ };
62
+
63
+ /**
64
+ * Returns all terms as a glossary JSON resource.
65
+ */
66
+ declare function readGlossary(manifest: Manifest): ReadResourceResult;
67
+
68
+ /**
69
+ * Searches across all concepts, products, policies, entities, and terms
70
+ * in the manifest. Matches case-insensitively on id, definition/description,
71
+ * and tags.
72
+ */
73
+ declare function searchContext(manifest: Manifest, query: string): CallToolResult;
74
+
75
+ /**
76
+ * Finds a node by ID in the manifest and returns comprehensive info:
77
+ * the node itself, its dependencies, dependents, applicable policies,
78
+ * and owner info.
79
+ */
80
+ declare function explainNode(manifest: Manifest, id: string): CallToolResult;
81
+
82
+ /**
83
+ * Runs the compile + lint pipeline on a context directory and returns diagnostics.
84
+ */
85
+ declare function validateContext(rootDir?: string): Promise<CallToolResult>;
86
+
87
+ declare const MCP_VERSION = "0.1.0";
88
+
89
+ export { MCP_VERSION, createContextMcpServer, explainNode, listConcepts, listPolicies, listProducts, readConcept, readGlossary, readManifest, readPolicy, readProduct, searchContext, validateContext };
@@ -0,0 +1,89 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { Manifest } from '@runcontext/core';
3
+ import { ReadResourceResult, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
4
+
5
+ /**
6
+ * Creates an MCP server wired up with all ContextKit resources and tools.
7
+ */
8
+ declare function createContextMcpServer(manifest: Manifest): McpServer;
9
+
10
+ /**
11
+ * Returns the full manifest as a JSON resource.
12
+ */
13
+ declare function readManifest(manifest: Manifest): ReadResourceResult;
14
+
15
+ /**
16
+ * Returns a single concept by ID from the manifest.
17
+ */
18
+ declare function readConcept(manifest: Manifest, id: string): ReadResourceResult;
19
+ /**
20
+ * Lists all concepts as resources.
21
+ */
22
+ declare function listConcepts(manifest: Manifest): {
23
+ resources: {
24
+ uri: string;
25
+ name: string;
26
+ description: string;
27
+ mimeType: "application/json";
28
+ }[];
29
+ };
30
+
31
+ /**
32
+ * Returns a single product by ID from the manifest.
33
+ */
34
+ declare function readProduct(manifest: Manifest, id: string): ReadResourceResult;
35
+ /**
36
+ * Lists all products as resources.
37
+ */
38
+ declare function listProducts(manifest: Manifest): {
39
+ resources: {
40
+ uri: string;
41
+ name: string;
42
+ description: string;
43
+ mimeType: "application/json";
44
+ }[];
45
+ };
46
+
47
+ /**
48
+ * Returns a single policy by ID from the manifest.
49
+ */
50
+ declare function readPolicy(manifest: Manifest, id: string): ReadResourceResult;
51
+ /**
52
+ * Lists all policies as resources.
53
+ */
54
+ declare function listPolicies(manifest: Manifest): {
55
+ resources: {
56
+ uri: string;
57
+ name: string;
58
+ description: string;
59
+ mimeType: "application/json";
60
+ }[];
61
+ };
62
+
63
+ /**
64
+ * Returns all terms as a glossary JSON resource.
65
+ */
66
+ declare function readGlossary(manifest: Manifest): ReadResourceResult;
67
+
68
+ /**
69
+ * Searches across all concepts, products, policies, entities, and terms
70
+ * in the manifest. Matches case-insensitively on id, definition/description,
71
+ * and tags.
72
+ */
73
+ declare function searchContext(manifest: Manifest, query: string): CallToolResult;
74
+
75
+ /**
76
+ * Finds a node by ID in the manifest and returns comprehensive info:
77
+ * the node itself, its dependencies, dependents, applicable policies,
78
+ * and owner info.
79
+ */
80
+ declare function explainNode(manifest: Manifest, id: string): CallToolResult;
81
+
82
+ /**
83
+ * Runs the compile + lint pipeline on a context directory and returns diagnostics.
84
+ */
85
+ declare function validateContext(rootDir?: string): Promise<CallToolResult>;
86
+
87
+ declare const MCP_VERSION = "0.1.0";
88
+
89
+ export { MCP_VERSION, createContextMcpServer, explainNode, listConcepts, listPolicies, listProducts, readConcept, readGlossary, readManifest, readPolicy, readProduct, searchContext, validateContext };
package/dist/index.mjs ADDED
@@ -0,0 +1,423 @@
1
+ // src/server.ts
2
+ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { z } from "zod";
4
+
5
+ // src/resources/manifest.ts
6
+ function readManifest(manifest) {
7
+ return {
8
+ contents: [
9
+ {
10
+ uri: "context://manifest",
11
+ mimeType: "application/json",
12
+ text: JSON.stringify(manifest, null, 2)
13
+ }
14
+ ]
15
+ };
16
+ }
17
+
18
+ // src/resources/concept.ts
19
+ function readConcept(manifest, id) {
20
+ const concept = manifest.concepts.find((c) => c.id === id);
21
+ if (!concept) {
22
+ return {
23
+ contents: [
24
+ {
25
+ uri: `context://concept/${id}`,
26
+ mimeType: "application/json",
27
+ text: JSON.stringify({ error: `Concept not found: ${id}` })
28
+ }
29
+ ]
30
+ };
31
+ }
32
+ return {
33
+ contents: [
34
+ {
35
+ uri: `context://concept/${id}`,
36
+ mimeType: "application/json",
37
+ text: JSON.stringify(concept, null, 2)
38
+ }
39
+ ]
40
+ };
41
+ }
42
+ function listConcepts(manifest) {
43
+ return {
44
+ resources: manifest.concepts.map((c) => ({
45
+ uri: `context://concept/${c.id}`,
46
+ name: c.id,
47
+ description: c.definition,
48
+ mimeType: "application/json"
49
+ }))
50
+ };
51
+ }
52
+
53
+ // src/resources/product.ts
54
+ function readProduct(manifest, id) {
55
+ const product = manifest.products.find((p) => p.id === id);
56
+ if (!product) {
57
+ return {
58
+ contents: [
59
+ {
60
+ uri: `context://product/${id}`,
61
+ mimeType: "application/json",
62
+ text: JSON.stringify({ error: `Product not found: ${id}` })
63
+ }
64
+ ]
65
+ };
66
+ }
67
+ return {
68
+ contents: [
69
+ {
70
+ uri: `context://product/${id}`,
71
+ mimeType: "application/json",
72
+ text: JSON.stringify(product, null, 2)
73
+ }
74
+ ]
75
+ };
76
+ }
77
+ function listProducts(manifest) {
78
+ return {
79
+ resources: manifest.products.map((p) => ({
80
+ uri: `context://product/${p.id}`,
81
+ name: p.id,
82
+ description: p.description,
83
+ mimeType: "application/json"
84
+ }))
85
+ };
86
+ }
87
+
88
+ // src/resources/policy.ts
89
+ function readPolicy(manifest, id) {
90
+ const policy = manifest.policies.find((p) => p.id === id);
91
+ if (!policy) {
92
+ return {
93
+ contents: [
94
+ {
95
+ uri: `context://policy/${id}`,
96
+ mimeType: "application/json",
97
+ text: JSON.stringify({ error: `Policy not found: ${id}` })
98
+ }
99
+ ]
100
+ };
101
+ }
102
+ return {
103
+ contents: [
104
+ {
105
+ uri: `context://policy/${id}`,
106
+ mimeType: "application/json",
107
+ text: JSON.stringify(policy, null, 2)
108
+ }
109
+ ]
110
+ };
111
+ }
112
+ function listPolicies(manifest) {
113
+ return {
114
+ resources: manifest.policies.map((p) => ({
115
+ uri: `context://policy/${p.id}`,
116
+ name: p.id,
117
+ description: p.description,
118
+ mimeType: "application/json"
119
+ }))
120
+ };
121
+ }
122
+
123
+ // src/resources/glossary.ts
124
+ function readGlossary(manifest) {
125
+ const glossary = manifest.terms.map((t) => ({
126
+ id: t.id,
127
+ definition: t.definition,
128
+ synonyms: t.synonyms ?? [],
129
+ mapsTo: t.mapsTo ?? []
130
+ }));
131
+ return {
132
+ contents: [
133
+ {
134
+ uri: "context://glossary",
135
+ mimeType: "application/json",
136
+ text: JSON.stringify(glossary, null, 2)
137
+ }
138
+ ]
139
+ };
140
+ }
141
+
142
+ // src/tools/search.ts
143
+ function searchContext(manifest, query) {
144
+ const q = query.toLowerCase();
145
+ const items = [
146
+ ...manifest.concepts.map((c) => ({
147
+ kind: "concept",
148
+ id: c.id,
149
+ definition: c.definition,
150
+ tags: c.tags
151
+ })),
152
+ ...manifest.products.map((p) => ({
153
+ kind: "product",
154
+ id: p.id,
155
+ description: p.description,
156
+ tags: p.tags
157
+ })),
158
+ ...manifest.policies.map((p) => ({
159
+ kind: "policy",
160
+ id: p.id,
161
+ description: p.description,
162
+ tags: p.tags
163
+ })),
164
+ ...manifest.entities.map((e) => ({
165
+ kind: "entity",
166
+ id: e.id,
167
+ definition: e.definition,
168
+ tags: e.tags
169
+ })),
170
+ ...manifest.terms.map((t) => ({
171
+ kind: "term",
172
+ id: t.id,
173
+ definition: t.definition,
174
+ tags: t.tags
175
+ }))
176
+ ];
177
+ const matches = items.filter((item) => {
178
+ if (item.id.toLowerCase().includes(q)) return true;
179
+ if (item.definition && item.definition.toLowerCase().includes(q)) return true;
180
+ if (item.description && item.description.toLowerCase().includes(q)) return true;
181
+ if (item.tags && item.tags.some((tag) => tag.toLowerCase().includes(q))) return true;
182
+ return false;
183
+ });
184
+ return {
185
+ content: [
186
+ {
187
+ type: "text",
188
+ text: JSON.stringify({ query, resultCount: matches.length, results: matches }, null, 2)
189
+ }
190
+ ]
191
+ };
192
+ }
193
+
194
+ // src/tools/explain.ts
195
+ function explainNode(manifest, id) {
196
+ const index = manifest.indexes.byId[id];
197
+ if (!index) {
198
+ return {
199
+ content: [
200
+ {
201
+ type: "text",
202
+ text: JSON.stringify({ error: `Node not found: ${id}` }, null, 2)
203
+ }
204
+ ]
205
+ };
206
+ }
207
+ let node;
208
+ switch (index.kind) {
209
+ case "concept":
210
+ node = manifest.concepts[index.index];
211
+ break;
212
+ case "product":
213
+ node = manifest.products[index.index];
214
+ break;
215
+ case "policy":
216
+ node = manifest.policies[index.index];
217
+ break;
218
+ case "entity":
219
+ node = manifest.entities[index.index];
220
+ break;
221
+ case "term":
222
+ node = manifest.terms[index.index];
223
+ break;
224
+ case "owner":
225
+ node = manifest.owners[index.index];
226
+ break;
227
+ }
228
+ if (!node) {
229
+ return {
230
+ content: [
231
+ {
232
+ type: "text",
233
+ text: JSON.stringify({ error: `Node data not found for: ${id}` }, null, 2)
234
+ }
235
+ ]
236
+ };
237
+ }
238
+ const dependencies = [];
239
+ const dependsOn = node.dependsOn;
240
+ if (dependsOn) {
241
+ for (const depId of dependsOn) {
242
+ const depIndex = manifest.indexes.byId[depId];
243
+ if (depIndex) {
244
+ dependencies.push({ id: depId, kind: depIndex.kind });
245
+ }
246
+ }
247
+ }
248
+ const dependents = [];
249
+ for (const concept of manifest.concepts) {
250
+ if (concept.dependsOn?.includes(id)) {
251
+ dependents.push({ id: concept.id, kind: "concept" });
252
+ }
253
+ }
254
+ const applicablePolicies = [];
255
+ const nodeTags = node.tags ?? [];
256
+ for (const policy of manifest.policies) {
257
+ const applies = policy.rules.some((rule) => {
258
+ if (rule.when.conceptIds?.includes(id)) return true;
259
+ if (rule.when.tagsAny?.some((tag) => nodeTags.includes(tag))) return true;
260
+ return false;
261
+ });
262
+ if (applies) {
263
+ applicablePolicies.push({ id: policy.id, description: policy.description });
264
+ }
265
+ }
266
+ let ownerInfo;
267
+ const ownerId = node.owner;
268
+ if (ownerId) {
269
+ ownerInfo = manifest.owners.find((o) => o.id === ownerId);
270
+ }
271
+ const result = {
272
+ kind: index.kind,
273
+ node,
274
+ dependencies,
275
+ dependents,
276
+ applicablePolicies,
277
+ owner: ownerInfo ?? null
278
+ };
279
+ return {
280
+ content: [
281
+ {
282
+ type: "text",
283
+ text: JSON.stringify(result, null, 2)
284
+ }
285
+ ]
286
+ };
287
+ }
288
+
289
+ // src/tools/validate.ts
290
+ async function validateContext(rootDir) {
291
+ try {
292
+ const { compile, LintEngine, ALL_RULES } = await import("@runcontext/core");
293
+ const contextDir = rootDir ?? process.cwd();
294
+ const compileResult = await compile({
295
+ contextDir,
296
+ config: {}
297
+ });
298
+ const engine = new LintEngine();
299
+ for (const rule of ALL_RULES) {
300
+ engine.register(rule);
301
+ }
302
+ const lintDiagnostics = engine.run(compileResult.graph);
303
+ const allDiagnostics = [...compileResult.diagnostics, ...lintDiagnostics];
304
+ const summary = {
305
+ contextDir,
306
+ compileDiagnostics: compileResult.diagnostics.length,
307
+ lintDiagnostics: lintDiagnostics.length,
308
+ totalDiagnostics: allDiagnostics.length,
309
+ errors: allDiagnostics.filter((d) => d.severity === "error").length,
310
+ warnings: allDiagnostics.filter((d) => d.severity === "warning").length,
311
+ diagnostics: allDiagnostics
312
+ };
313
+ return {
314
+ content: [
315
+ {
316
+ type: "text",
317
+ text: JSON.stringify(summary, null, 2)
318
+ }
319
+ ]
320
+ };
321
+ } catch (err) {
322
+ const message = err instanceof Error ? err.message : String(err);
323
+ return {
324
+ content: [
325
+ {
326
+ type: "text",
327
+ text: JSON.stringify({ error: `Validation failed: ${message}` }, null, 2)
328
+ }
329
+ ],
330
+ isError: true
331
+ };
332
+ }
333
+ }
334
+
335
+ // src/server.ts
336
+ function createContextMcpServer(manifest) {
337
+ const server = new McpServer(
338
+ {
339
+ name: "contextkit",
340
+ version: "0.1.0"
341
+ },
342
+ {
343
+ capabilities: {
344
+ resources: {},
345
+ tools: {}
346
+ }
347
+ }
348
+ );
349
+ server.resource(
350
+ "manifest",
351
+ "context://manifest",
352
+ { description: "The full ContextKit manifest", mimeType: "application/json" },
353
+ () => readManifest(manifest)
354
+ );
355
+ server.resource(
356
+ "glossary",
357
+ "context://glossary",
358
+ { description: "Glossary of all terms", mimeType: "application/json" },
359
+ () => readGlossary(manifest)
360
+ );
361
+ server.resource(
362
+ "concept",
363
+ new ResourceTemplate("context://concept/{id}", {
364
+ list: () => listConcepts(manifest)
365
+ }),
366
+ { description: "A single concept by ID", mimeType: "application/json" },
367
+ (uri, variables) => readConcept(manifest, String(variables.id))
368
+ );
369
+ server.resource(
370
+ "product",
371
+ new ResourceTemplate("context://product/{id}", {
372
+ list: () => listProducts(manifest)
373
+ }),
374
+ { description: "A single product by ID", mimeType: "application/json" },
375
+ (uri, variables) => readProduct(manifest, String(variables.id))
376
+ );
377
+ server.resource(
378
+ "policy",
379
+ new ResourceTemplate("context://policy/{id}", {
380
+ list: () => listPolicies(manifest)
381
+ }),
382
+ { description: "A single policy by ID", mimeType: "application/json" },
383
+ (uri, variables) => readPolicy(manifest, String(variables.id))
384
+ );
385
+ server.tool(
386
+ "context_search",
387
+ "Search across all concepts, products, policies, entities, and terms",
388
+ { query: z.string().describe("The search query (case-insensitive substring match)") },
389
+ ({ query }) => searchContext(manifest, query)
390
+ );
391
+ server.tool(
392
+ "context_explain",
393
+ "Get comprehensive info about a node: the node itself, dependencies, dependents, applicable policies, and owner",
394
+ { id: z.string().describe("The ID of the node to explain") },
395
+ ({ id }) => explainNode(manifest, id)
396
+ );
397
+ server.tool(
398
+ "context_validate",
399
+ "Run compile and lint validation on the context directory and return diagnostics",
400
+ { rootDir: z.string().optional().describe("Root directory to validate (defaults to cwd)") },
401
+ async ({ rootDir }) => validateContext(rootDir)
402
+ );
403
+ return server;
404
+ }
405
+
406
+ // src/index.ts
407
+ var MCP_VERSION = "0.1.0";
408
+ export {
409
+ MCP_VERSION,
410
+ createContextMcpServer,
411
+ explainNode,
412
+ listConcepts,
413
+ listPolicies,
414
+ listProducts,
415
+ readConcept,
416
+ readGlossary,
417
+ readManifest,
418
+ readPolicy,
419
+ readProduct,
420
+ searchContext,
421
+ validateContext
422
+ };
423
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/resources/manifest.ts","../src/resources/concept.ts","../src/resources/product.ts","../src/resources/policy.ts","../src/resources/glossary.ts","../src/tools/search.ts","../src/tools/explain.ts","../src/tools/validate.ts","../src/index.ts"],"sourcesContent":["import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { Manifest } from '@runcontext/core';\n\nimport { readManifest } from './resources/manifest.js';\nimport { readConcept, listConcepts } from './resources/concept.js';\nimport { readProduct, listProducts } from './resources/product.js';\nimport { readPolicy, listPolicies } from './resources/policy.js';\nimport { readGlossary } from './resources/glossary.js';\nimport { searchContext } from './tools/search.js';\nimport { explainNode } from './tools/explain.js';\nimport { validateContext } from './tools/validate.js';\n\n/**\n * Creates an MCP server wired up with all ContextKit resources and tools.\n */\nexport function createContextMcpServer(manifest: Manifest): McpServer {\n const server = new McpServer(\n {\n name: 'contextkit',\n version: '0.1.0',\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n },\n );\n\n // ── Static Resources ──────────────────────────────────────────────\n\n // context://manifest — full manifest\n server.resource(\n 'manifest',\n 'context://manifest',\n { description: 'The full ContextKit manifest', mimeType: 'application/json' },\n () => readManifest(manifest),\n );\n\n // context://glossary — all terms\n server.resource(\n 'glossary',\n 'context://glossary',\n { description: 'Glossary of all terms', mimeType: 'application/json' },\n () => readGlossary(manifest),\n );\n\n // ── Template Resources ────────────────────────────────────────────\n\n // context://concept/{id}\n server.resource(\n 'concept',\n new ResourceTemplate('context://concept/{id}', {\n list: () => listConcepts(manifest),\n }),\n { description: 'A single concept by ID', mimeType: 'application/json' },\n (uri, variables) => readConcept(manifest, String(variables.id)),\n );\n\n // context://product/{id}\n server.resource(\n 'product',\n new ResourceTemplate('context://product/{id}', {\n list: () => listProducts(manifest),\n }),\n { description: 'A single product by ID', mimeType: 'application/json' },\n (uri, variables) => readProduct(manifest, String(variables.id)),\n );\n\n // context://policy/{id}\n server.resource(\n 'policy',\n new ResourceTemplate('context://policy/{id}', {\n list: () => listPolicies(manifest),\n }),\n { description: 'A single policy by ID', mimeType: 'application/json' },\n (uri, variables) => readPolicy(manifest, String(variables.id)),\n );\n\n // ── Tools ─────────────────────────────────────────────────────────\n\n // context_search — search across all nodes\n server.tool(\n 'context_search',\n 'Search across all concepts, products, policies, entities, and terms',\n { query: z.string().describe('The search query (case-insensitive substring match)') },\n ({ query }) => searchContext(manifest, query),\n );\n\n // context_explain — explain a node by ID\n server.tool(\n 'context_explain',\n 'Get comprehensive info about a node: the node itself, dependencies, dependents, applicable policies, and owner',\n { id: z.string().describe('The ID of the node to explain') },\n ({ id }) => explainNode(manifest, id),\n );\n\n // context_validate — run compile + lint\n server.tool(\n 'context_validate',\n 'Run compile and lint validation on the context directory and return diagnostics',\n { rootDir: z.string().optional().describe('Root directory to validate (defaults to cwd)') },\n async ({ rootDir }) => validateContext(rootDir),\n );\n\n return server;\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns the full manifest as a JSON resource.\n */\nexport function readManifest(manifest: Manifest): ReadResourceResult {\n return {\n contents: [\n {\n uri: 'context://manifest',\n mimeType: 'application/json',\n text: JSON.stringify(manifest, null, 2),\n },\n ],\n };\n}\n","import type { Manifest, ManifestConcept } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single concept by ID from the manifest.\n */\nexport function readConcept(manifest: Manifest, id: string): ReadResourceResult {\n const concept: ManifestConcept | undefined = manifest.concepts.find((c) => c.id === id);\n if (!concept) {\n return {\n contents: [\n {\n uri: `context://concept/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Concept not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://concept/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(concept, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all concepts as resources.\n */\nexport function listConcepts(manifest: Manifest) {\n return {\n resources: manifest.concepts.map((c) => ({\n uri: `context://concept/${c.id}`,\n name: c.id,\n description: c.definition,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest, ManifestProduct } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single product by ID from the manifest.\n */\nexport function readProduct(manifest: Manifest, id: string): ReadResourceResult {\n const product: ManifestProduct | undefined = manifest.products.find((p) => p.id === id);\n if (!product) {\n return {\n contents: [\n {\n uri: `context://product/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Product not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://product/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(product, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all products as resources.\n */\nexport function listProducts(manifest: Manifest) {\n return {\n resources: manifest.products.map((p) => ({\n uri: `context://product/${p.id}`,\n name: p.id,\n description: p.description,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest, ManifestPolicy } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns a single policy by ID from the manifest.\n */\nexport function readPolicy(manifest: Manifest, id: string): ReadResourceResult {\n const policy: ManifestPolicy | undefined = manifest.policies.find((p) => p.id === id);\n if (!policy) {\n return {\n contents: [\n {\n uri: `context://policy/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Policy not found: ${id}` }),\n },\n ],\n };\n }\n return {\n contents: [\n {\n uri: `context://policy/${id}`,\n mimeType: 'application/json',\n text: JSON.stringify(policy, null, 2),\n },\n ],\n };\n}\n\n/**\n * Lists all policies as resources.\n */\nexport function listPolicies(manifest: Manifest) {\n return {\n resources: manifest.policies.map((p) => ({\n uri: `context://policy/${p.id}`,\n name: p.id,\n description: p.description,\n mimeType: 'application/json' as const,\n })),\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Returns all terms as a glossary JSON resource.\n */\nexport function readGlossary(manifest: Manifest): ReadResourceResult {\n const glossary = manifest.terms.map((t) => ({\n id: t.id,\n definition: t.definition,\n synonyms: t.synonyms ?? [],\n mapsTo: t.mapsTo ?? [],\n }));\n\n return {\n contents: [\n {\n uri: 'context://glossary',\n mimeType: 'application/json',\n text: JSON.stringify(glossary, null, 2),\n },\n ],\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\ninterface SearchableItem {\n kind: string;\n id: string;\n definition?: string;\n description?: string;\n tags?: string[];\n}\n\n/**\n * Searches across all concepts, products, policies, entities, and terms\n * in the manifest. Matches case-insensitively on id, definition/description,\n * and tags.\n */\nexport function searchContext(manifest: Manifest, query: string): CallToolResult {\n const q = query.toLowerCase();\n\n const items: SearchableItem[] = [\n ...manifest.concepts.map((c) => ({\n kind: 'concept' as const,\n id: c.id,\n definition: c.definition,\n tags: c.tags,\n })),\n ...manifest.products.map((p) => ({\n kind: 'product' as const,\n id: p.id,\n description: p.description,\n tags: p.tags,\n })),\n ...manifest.policies.map((p) => ({\n kind: 'policy' as const,\n id: p.id,\n description: p.description,\n tags: p.tags,\n })),\n ...manifest.entities.map((e) => ({\n kind: 'entity' as const,\n id: e.id,\n definition: e.definition,\n tags: e.tags,\n })),\n ...manifest.terms.map((t) => ({\n kind: 'term' as const,\n id: t.id,\n definition: t.definition,\n tags: t.tags,\n })),\n ];\n\n const matches = items.filter((item) => {\n if (item.id.toLowerCase().includes(q)) return true;\n if (item.definition && item.definition.toLowerCase().includes(q)) return true;\n if (item.description && item.description.toLowerCase().includes(q)) return true;\n if (item.tags && item.tags.some((tag) => tag.toLowerCase().includes(q))) return true;\n return false;\n });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ query, resultCount: matches.length, results: matches }, null, 2),\n },\n ],\n };\n}\n","import type { Manifest } from '@runcontext/core';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Finds a node by ID in the manifest and returns comprehensive info:\n * the node itself, its dependencies, dependents, applicable policies,\n * and owner info.\n */\nexport function explainNode(manifest: Manifest, id: string): CallToolResult {\n const index = manifest.indexes.byId[id];\n if (!index) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Node not found: ${id}` }, null, 2),\n },\n ],\n };\n }\n\n // Retrieve the node from the appropriate collection\n let node: Record<string, unknown> | undefined;\n switch (index.kind) {\n case 'concept':\n node = manifest.concepts[index.index] as unknown as Record<string, unknown>;\n break;\n case 'product':\n node = manifest.products[index.index] as unknown as Record<string, unknown>;\n break;\n case 'policy':\n node = manifest.policies[index.index] as unknown as Record<string, unknown>;\n break;\n case 'entity':\n node = manifest.entities[index.index] as unknown as Record<string, unknown>;\n break;\n case 'term':\n node = manifest.terms[index.index] as unknown as Record<string, unknown>;\n break;\n case 'owner':\n node = manifest.owners[index.index] as unknown as Record<string, unknown>;\n break;\n }\n\n if (!node) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Node data not found for: ${id}` }, null, 2),\n },\n ],\n };\n }\n\n // Find dependencies (concepts that this node dependsOn)\n const dependencies: Array<{ id: string; kind: string }> = [];\n const dependsOn = (node as { dependsOn?: string[] }).dependsOn;\n if (dependsOn) {\n for (const depId of dependsOn) {\n const depIndex = manifest.indexes.byId[depId];\n if (depIndex) {\n dependencies.push({ id: depId, kind: depIndex.kind });\n }\n }\n }\n\n // Find dependents (concepts that depend on this node)\n const dependents: Array<{ id: string; kind: string }> = [];\n for (const concept of manifest.concepts) {\n if (concept.dependsOn?.includes(id)) {\n dependents.push({ id: concept.id, kind: 'concept' });\n }\n }\n\n // Find applicable policies (policies whose rules reference this node's tags or ID)\n const applicablePolicies: Array<{ id: string; description: string }> = [];\n const nodeTags = (node as { tags?: string[] }).tags ?? [];\n for (const policy of manifest.policies) {\n const applies = policy.rules.some((rule) => {\n if (rule.when.conceptIds?.includes(id)) return true;\n if (rule.when.tagsAny?.some((tag) => nodeTags.includes(tag))) return true;\n return false;\n });\n if (applies) {\n applicablePolicies.push({ id: policy.id, description: policy.description });\n }\n }\n\n // Find owner info\n let ownerInfo: Record<string, unknown> | undefined;\n const ownerId = (node as { owner?: string }).owner;\n if (ownerId) {\n ownerInfo = manifest.owners.find((o) => o.id === ownerId) as unknown as Record<string, unknown>;\n }\n\n const result = {\n kind: index.kind,\n node,\n dependencies,\n dependents,\n applicablePolicies,\n owner: ownerInfo ?? null,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Runs the compile + lint pipeline on a context directory and returns diagnostics.\n */\nexport async function validateContext(rootDir?: string): Promise<CallToolResult> {\n try {\n // Dynamic import to avoid circular dependency issues at load time\n const { compile, LintEngine, ALL_RULES } = await import('@runcontext/core');\n\n const contextDir = rootDir ?? process.cwd();\n\n // Run the compiler pipeline\n const compileResult = await compile({\n contextDir,\n config: {},\n });\n\n // Run the linter\n const engine = new LintEngine();\n for (const rule of ALL_RULES) {\n engine.register(rule);\n }\n const lintDiagnostics = engine.run(compileResult.graph);\n\n // Combine diagnostics\n const allDiagnostics = [...compileResult.diagnostics, ...lintDiagnostics];\n\n const summary = {\n contextDir,\n compileDiagnostics: compileResult.diagnostics.length,\n lintDiagnostics: lintDiagnostics.length,\n totalDiagnostics: allDiagnostics.length,\n errors: allDiagnostics.filter((d) => d.severity === 'error').length,\n warnings: allDiagnostics.filter((d) => d.severity === 'warning').length,\n diagnostics: allDiagnostics,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ error: `Validation failed: ${message}` }, null, 2),\n },\n ],\n isError: true,\n };\n }\n}\n","export const MCP_VERSION = '0.1.0';\n\nexport { createContextMcpServer } from './server.js';\n\n// Re-export resource handlers for direct testing / reuse\nexport { readManifest } from './resources/manifest.js';\nexport { readConcept, listConcepts } from './resources/concept.js';\nexport { readProduct, listProducts } from './resources/product.js';\nexport { readPolicy, listPolicies } from './resources/policy.js';\nexport { readGlossary } from './resources/glossary.js';\n\n// Re-export tool handlers for direct testing / reuse\nexport { searchContext } from './tools/search.js';\nexport { explainNode } from './tools/explain.js';\nexport { validateContext } from './tools/validate.js';\n"],"mappings":";AAAA,SAAS,WAAW,wBAAwB;AAC5C,SAAS,SAAS;;;ACKX,SAAS,aAAa,UAAwC;AACnE,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;;;ACVO,SAAS,YAAY,UAAoB,IAAgC;AAC9E,QAAM,UAAuC,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACtF,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,UAAU;AAAA,QACR;AAAA,UACE,KAAK,qBAAqB,EAAE;AAAA,UAC5B,UAAU;AAAA,UACV,MAAM,KAAK,UAAU,EAAE,OAAO,sBAAsB,EAAE,GAAG,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,QACE,KAAK,qBAAqB,EAAE;AAAA,QAC5B,UAAU;AAAA,QACV,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,aAAa,UAAoB;AAC/C,SAAO;AAAA,IACL,WAAW,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MACvC,KAAK,qBAAqB,EAAE,EAAE;AAAA,MAC9B,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,UAAU;AAAA,IACZ,EAAE;AAAA,EACJ;AACF;;;ACpCO,SAAS,YAAY,UAAoB,IAAgC;AAC9E,QAAM,UAAuC,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACtF,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,UAAU;AAAA,QACR;AAAA,UACE,KAAK,qBAAqB,EAAE;AAAA,UAC5B,UAAU;AAAA,UACV,MAAM,KAAK,UAAU,EAAE,OAAO,sBAAsB,EAAE,GAAG,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,QACE,KAAK,qBAAqB,EAAE;AAAA,QAC5B,UAAU;AAAA,QACV,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,aAAa,UAAoB;AAC/C,SAAO;AAAA,IACL,WAAW,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MACvC,KAAK,qBAAqB,EAAE,EAAE;AAAA,MAC9B,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,UAAU;AAAA,IACZ,EAAE;AAAA,EACJ;AACF;;;ACpCO,SAAS,WAAW,UAAoB,IAAgC;AAC7E,QAAM,SAAqC,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACpF,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,UAAU;AAAA,QACR;AAAA,UACE,KAAK,oBAAoB,EAAE;AAAA,UAC3B,UAAU;AAAA,UACV,MAAM,KAAK,UAAU,EAAE,OAAO,qBAAqB,EAAE,GAAG,CAAC;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,QACE,KAAK,oBAAoB,EAAE;AAAA,QAC3B,UAAU;AAAA,QACV,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,aAAa,UAAoB;AAC/C,SAAO;AAAA,IACL,WAAW,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MACvC,KAAK,oBAAoB,EAAE,EAAE;AAAA,MAC7B,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,UAAU;AAAA,IACZ,EAAE;AAAA,EACJ;AACF;;;ACpCO,SAAS,aAAa,UAAwC;AACnE,QAAM,WAAW,SAAS,MAAM,IAAI,CAAC,OAAO;AAAA,IAC1C,IAAI,EAAE;AAAA,IACN,YAAY,EAAE;AAAA,IACd,UAAU,EAAE,YAAY,CAAC;AAAA,IACzB,QAAQ,EAAE,UAAU,CAAC;AAAA,EACvB,EAAE;AAEF,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;;;ACPO,SAAS,cAAc,UAAoB,OAA+B;AAC/E,QAAM,IAAI,MAAM,YAAY;AAE5B,QAAM,QAA0B;AAAA,IAC9B,GAAG,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MAC/B,MAAM;AAAA,MACN,IAAI,EAAE;AAAA,MACN,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,IACF,GAAG,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MAC/B,MAAM;AAAA,MACN,IAAI,EAAE;AAAA,MACN,aAAa,EAAE;AAAA,MACf,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,IACF,GAAG,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MAC/B,MAAM;AAAA,MACN,IAAI,EAAE;AAAA,MACN,aAAa,EAAE;AAAA,MACf,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,IACF,GAAG,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MAC/B,MAAM;AAAA,MACN,IAAI,EAAE;AAAA,MACN,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,IACF,GAAG,SAAS,MAAM,IAAI,CAAC,OAAO;AAAA,MAC5B,MAAM;AAAA,MACN,IAAI,EAAE;AAAA,MACN,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACJ;AAEA,QAAM,UAAU,MAAM,OAAO,CAAC,SAAS;AACrC,QAAI,KAAK,GAAG,YAAY,EAAE,SAAS,CAAC,EAAG,QAAO;AAC9C,QAAI,KAAK,cAAc,KAAK,WAAW,YAAY,EAAE,SAAS,CAAC,EAAG,QAAO;AACzE,QAAI,KAAK,eAAe,KAAK,YAAY,YAAY,EAAE,SAAS,CAAC,EAAG,QAAO;AAC3E,QAAI,KAAK,QAAQ,KAAK,KAAK,KAAK,CAAC,QAAQ,IAAI,YAAY,EAAE,SAAS,CAAC,CAAC,EAAG,QAAO;AAChF,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,EAAE,OAAO,aAAa,QAAQ,QAAQ,SAAS,QAAQ,GAAG,MAAM,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AACF;;;AC5DO,SAAS,YAAY,UAAoB,IAA4B;AAC1E,QAAM,QAAQ,SAAS,QAAQ,KAAK,EAAE;AACtC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,OAAO,mBAAmB,EAAE,GAAG,GAAG,MAAM,CAAC;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACJ,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,SAAS,SAAS,MAAM,KAAK;AACpC;AAAA,IACF,KAAK;AACH,aAAO,SAAS,SAAS,MAAM,KAAK;AACpC;AAAA,IACF,KAAK;AACH,aAAO,SAAS,SAAS,MAAM,KAAK;AACpC;AAAA,IACF,KAAK;AACH,aAAO,SAAS,SAAS,MAAM,KAAK;AACpC;AAAA,IACF,KAAK;AACH,aAAO,SAAS,MAAM,MAAM,KAAK;AACjC;AAAA,IACF,KAAK;AACH,aAAO,SAAS,OAAO,MAAM,KAAK;AAClC;AAAA,EACJ;AAEA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,OAAO,4BAA4B,EAAE,GAAG,GAAG,MAAM,CAAC;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAoD,CAAC;AAC3D,QAAM,YAAa,KAAkC;AACrD,MAAI,WAAW;AACb,eAAW,SAAS,WAAW;AAC7B,YAAM,WAAW,SAAS,QAAQ,KAAK,KAAK;AAC5C,UAAI,UAAU;AACZ,qBAAa,KAAK,EAAE,IAAI,OAAO,MAAM,SAAS,KAAK,CAAC;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAkD,CAAC;AACzD,aAAW,WAAW,SAAS,UAAU;AACvC,QAAI,QAAQ,WAAW,SAAS,EAAE,GAAG;AACnC,iBAAW,KAAK,EAAE,IAAI,QAAQ,IAAI,MAAM,UAAU,CAAC;AAAA,IACrD;AAAA,EACF;AAGA,QAAM,qBAAiE,CAAC;AACxE,QAAM,WAAY,KAA6B,QAAQ,CAAC;AACxD,aAAW,UAAU,SAAS,UAAU;AACtC,UAAM,UAAU,OAAO,MAAM,KAAK,CAAC,SAAS;AAC1C,UAAI,KAAK,KAAK,YAAY,SAAS,EAAE,EAAG,QAAO;AAC/C,UAAI,KAAK,KAAK,SAAS,KAAK,CAAC,QAAQ,SAAS,SAAS,GAAG,CAAC,EAAG,QAAO;AACrE,aAAO;AAAA,IACT,CAAC;AACD,QAAI,SAAS;AACX,yBAAmB,KAAK,EAAE,IAAI,OAAO,IAAI,aAAa,OAAO,YAAY,CAAC;AAAA,IAC5E;AAAA,EACF;AAGA,MAAI;AACJ,QAAM,UAAW,KAA4B;AAC7C,MAAI,SAAS;AACX,gBAAY,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AAAA,EAC1D;AAEA,QAAM,SAAS;AAAA,IACb,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,aAAa;AAAA,EACtB;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACF;;;AC5GA,eAAsB,gBAAgB,SAA2C;AAC/E,MAAI;AAEF,UAAM,EAAE,SAAS,YAAY,UAAU,IAAI,MAAM,OAAO,kBAAkB;AAE1E,UAAM,aAAa,WAAW,QAAQ,IAAI;AAG1C,UAAM,gBAAgB,MAAM,QAAQ;AAAA,MAClC;AAAA,MACA,QAAQ,CAAC;AAAA,IACX,CAAC;AAGD,UAAM,SAAS,IAAI,WAAW;AAC9B,eAAW,QAAQ,WAAW;AAC5B,aAAO,SAAS,IAAI;AAAA,IACtB;AACA,UAAM,kBAAkB,OAAO,IAAI,cAAc,KAAK;AAGtD,UAAM,iBAAiB,CAAC,GAAG,cAAc,aAAa,GAAG,eAAe;AAExE,UAAM,UAAU;AAAA,MACd;AAAA,MACA,oBAAoB,cAAc,YAAY;AAAA,MAC9C,iBAAiB,gBAAgB;AAAA,MACjC,kBAAkB,eAAe;AAAA,MACjC,QAAQ,eAAe,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO,EAAE;AAAA,MAC7D,UAAU,eAAe,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS,EAAE;AAAA,MACjE,aAAa;AAAA,IACf;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,OAAO,sBAAsB,OAAO,GAAG,GAAG,MAAM,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AACF;;;AR1CO,SAAS,uBAAuB,UAA+B;AACpE,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,cAAc;AAAA,QACZ,WAAW,CAAC;AAAA,QACZ,OAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAKA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,aAAa,gCAAgC,UAAU,mBAAmB;AAAA,IAC5E,MAAM,aAAa,QAAQ;AAAA,EAC7B;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,aAAa,yBAAyB,UAAU,mBAAmB;AAAA,IACrE,MAAM,aAAa,QAAQ;AAAA,EAC7B;AAKA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,0BAA0B;AAAA,MAC7C,MAAM,MAAM,aAAa,QAAQ;AAAA,IACnC,CAAC;AAAA,IACD,EAAE,aAAa,0BAA0B,UAAU,mBAAmB;AAAA,IACtE,CAAC,KAAK,cAAc,YAAY,UAAU,OAAO,UAAU,EAAE,CAAC;AAAA,EAChE;AAGA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,0BAA0B;AAAA,MAC7C,MAAM,MAAM,aAAa,QAAQ;AAAA,IACnC,CAAC;AAAA,IACD,EAAE,aAAa,0BAA0B,UAAU,mBAAmB;AAAA,IACtE,CAAC,KAAK,cAAc,YAAY,UAAU,OAAO,UAAU,EAAE,CAAC;AAAA,EAChE;AAGA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,yBAAyB;AAAA,MAC5C,MAAM,MAAM,aAAa,QAAQ;AAAA,IACnC,CAAC;AAAA,IACD,EAAE,aAAa,yBAAyB,UAAU,mBAAmB;AAAA,IACrE,CAAC,KAAK,cAAc,WAAW,UAAU,OAAO,UAAU,EAAE,CAAC;AAAA,EAC/D;AAKA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,qDAAqD,EAAE;AAAA,IACpF,CAAC,EAAE,MAAM,MAAM,cAAc,UAAU,KAAK;AAAA,EAC9C;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,+BAA+B,EAAE;AAAA,IAC3D,CAAC,EAAE,GAAG,MAAM,YAAY,UAAU,EAAE;AAAA,EACtC;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C,EAAE;AAAA,IAC1F,OAAO,EAAE,QAAQ,MAAM,gBAAgB,OAAO;AAAA,EAChD;AAEA,SAAO;AACT;;;AS3GO,IAAM,cAAc;","names":[]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@runcontext/mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for exposing ContextKit context to AI agents",
5
+ "license": "MIT",
6
+ "author": "Eric Kittelson",
7
+ "homepage": "https://github.com/erickittelson/ContextKit",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/erickittelson/ContextKit.git",
11
+ "directory": "packages/mcp"
12
+ },
13
+ "keywords": ["contextkit", "mcp", "model-context-protocol", "ai", "llm"],
14
+ "type": "module",
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/index.mjs"
23
+ },
24
+ "require": {
25
+ "types": "./dist/index.d.cts",
26
+ "default": "./dist/index.cjs"
27
+ }
28
+ }
29
+ },
30
+ "files": ["dist"],
31
+ "scripts": {
32
+ "build": "tsup",
33
+ "clean": "rm -rf dist"
34
+ },
35
+ "dependencies": {
36
+ "@runcontext/core": "workspace:^",
37
+ "@modelcontextprotocol/sdk": "^1.12.0",
38
+ "express": "^5.1.0",
39
+ "zod": "^3.24.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/express": "^5.0.0",
43
+ "@types/node": "^25.3.3",
44
+ "tsup": "^8.4.0",
45
+ "typescript": "^5.7.0",
46
+ "vitest": "^3.2.0"
47
+ }
48
+ }