@adrkit/mcp 0.2.0 → 0.3.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/README.md +292 -31
- package/dist/bin.js +50 -70
- package/dist/corpus/ordering.d.ts +6 -15
- package/dist/index.d.ts +24 -2
- package/dist/index.js +42 -69
- package/dist/main-module.d.ts +9 -0
- package/dist/server.d.ts +17 -3
- package/dist/tools/get-decision-context.d.ts +1 -1
- package/dist/tools/get-decision.d.ts +1 -1
- package/dist/tools/list-superseded.d.ts +1 -1
- package/dist/tools/search-decisions.d.ts +1 -1
- package/dist/tools/shared.d.ts +2 -2
- package/package.json +6 -4
- package/src/corpus/ordering.ts +13 -38
- package/src/corpus/projection.ts +8 -27
- package/src/index.ts +35 -20
- package/src/main-module.ts +20 -1
- package/src/server.ts +38 -5
- package/src/tools/get-decision-context.ts +7 -5
- package/src/tools/get-decision.ts +1 -1
- package/src/tools/list-superseded.ts +1 -1
- package/src/tools/search-decisions.ts +1 -1
- package/src/tools/shared.ts +10 -10
package/src/server.ts
CHANGED
|
@@ -7,21 +7,54 @@
|
|
|
7
7
|
* `package.json#exports` and every public subpath.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
10
|
+
import { McpServer, type ServerOptions } from '@modelcontextprotocol/server';
|
|
11
11
|
import { registerSearchDecisions } from './tools/search-decisions.ts';
|
|
12
12
|
import { registerGetDecision } from './tools/get-decision.ts';
|
|
13
13
|
import { registerGetDecisionContext } from './tools/get-decision-context.ts';
|
|
14
14
|
import { registerListSuperseded } from './tools/list-superseded.ts';
|
|
15
15
|
import type { ToolConfig } from './tools/shared.ts';
|
|
16
16
|
|
|
17
|
-
export const SERVER_INFO = { name: '@adrkit/mcp', version: '0.
|
|
17
|
+
export const SERVER_INFO = { name: '@adrkit/mcp', version: '0.3.0' } as const;
|
|
18
18
|
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* The MCP protocol revision this server serves through `serveStdio`'s modern era.
|
|
21
|
+
*
|
|
22
|
+
* The SDK keeps the revision string internal (`LATEST_PROTOCOL_VERSION` names the
|
|
23
|
+
* latest *legacy*-era version, `2025-11-25`), so the modern revision is stated here
|
|
24
|
+
* once and asserted against the wire in `test/bin.test.ts`.
|
|
25
|
+
*/
|
|
26
|
+
export const MODERN_PROTOCOL_VERSION = '2026-07-28' as const;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* SEP-2549 cache hints for the two cacheable results this server can answer.
|
|
30
|
+
*
|
|
31
|
+
* Both are immutable for the lifetime of the process and carry no corpus content,
|
|
32
|
+
* caller identity, or per-request state: `tools/list` is the four ratified tools with
|
|
33
|
+
* their fixed schemas and annotations, and `server/discover` is the supported
|
|
34
|
+
* revisions plus the tools capability. They are therefore honestly `public` and safe
|
|
35
|
+
* to cache, which spares an agent a round trip per re-list. Corpus reads are NOT
|
|
36
|
+
* cacheable and are unaffected — every `tools/call` still loads a fresh projection.
|
|
37
|
+
*
|
|
38
|
+
* Without this the SDK falls back to the conservative `{ ttlMs: 0, cacheScope:
|
|
39
|
+
* 'private' }`. 2025-era responses never carry these fields either way.
|
|
40
|
+
*/
|
|
41
|
+
const CACHE_HINTS = {
|
|
42
|
+
'tools/list': { ttlMs: 300_000, cacheScope: 'public' },
|
|
43
|
+
'server/discover': { ttlMs: 300_000, cacheScope: 'public' },
|
|
44
|
+
} as const satisfies ServerOptions['cacheHints'];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Package-internal: build the concrete server with exactly the four ratified tools.
|
|
48
|
+
*
|
|
49
|
+
* Registration order is lexicographic by tool name so `tools/list` answers in a
|
|
50
|
+
* deterministic, self-evidently stable order (2026-07-28 minor change 3 — servers
|
|
51
|
+
* SHOULD do this so clients can cache catalogs and keep upstream prompt caches warm).
|
|
52
|
+
*/
|
|
20
53
|
export function buildRegisteredServer(config: ToolConfig): McpServer {
|
|
21
|
-
const server = new McpServer(SERVER_INFO);
|
|
22
|
-
registerSearchDecisions(server, config);
|
|
54
|
+
const server = new McpServer(SERVER_INFO, { cacheHints: CACHE_HINTS });
|
|
23
55
|
registerGetDecision(server, config);
|
|
24
56
|
registerGetDecisionContext(server, config);
|
|
25
57
|
registerListSuperseded(server, config);
|
|
58
|
+
registerSearchDecisions(server, config);
|
|
26
59
|
return server;
|
|
27
60
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* page is partitioned by status.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
11
|
-
import { resolveAffects, type Adr, type Finding, type FiredMatcher } from '@adrkit/core';
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
11
|
+
import { decisionBucketFor, resolveAffects, type Adr, type Finding, type FiredMatcher } from '@adrkit/core';
|
|
12
12
|
import { compareCodeUnits, sortFindingsCanonical } from '../corpus/ordering.ts';
|
|
13
13
|
import { paginate, queryShapeHash } from '../pagination/cursor.ts';
|
|
14
14
|
import {
|
|
@@ -37,10 +37,12 @@ interface GetDecisionContextArgs {
|
|
|
37
37
|
|
|
38
38
|
type Bucket = 'governing' | 'activeProposals' | 'history';
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Delegates to `@adrkit/core`'s `decisionBucketFor` so this tool and the CLI/Action
|
|
42
|
+
* cannot drift apart on what counts as governing (#39).
|
|
43
|
+
*/
|
|
40
44
|
function bucketFor(status: string): Bucket {
|
|
41
|
-
|
|
42
|
-
if (status === 'draft' || status === 'proposed') return 'activeProposals';
|
|
43
|
-
return 'history';
|
|
45
|
+
return decisionBucketFor(status);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
function contextEntry(record: Adr, firedMatchers: readonly FiredMatcher[]): ContextEntry {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* ambiguous-local-id. Relation refs are surfaced verbatim, never expanded.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
11
11
|
import { parseAdrRef, type Adr } from '@adrkit/core';
|
|
12
12
|
import { paginate, queryShapeHash, checkInapplicablePrimaryCursor } from '../pagination/cursor.ts';
|
|
13
13
|
import {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* finding templates.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
11
11
|
import { parseAdrRef, type Adr, type Finding } from '@adrkit/core';
|
|
12
12
|
import { sortFindingsCanonical } from '../corpus/ordering.ts';
|
|
13
13
|
import { paginate, queryShapeHash } from '../pagination/cursor.ts';
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* only — never a body, ranking score, or hidden index.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
11
11
|
import type { Adr } from '@adrkit/core';
|
|
12
12
|
import { compareCodeUnits } from '../corpus/ordering.ts';
|
|
13
13
|
import { normalize } from '../search/normalize.ts';
|
package/src/tools/shared.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { AdrFrontmatter, AdrRef, Status, Scope, type Finding, type FiredMatcher } from '@adrkit/core';
|
|
10
|
-
import type { CallToolResult } from '@modelcontextprotocol/
|
|
10
|
+
import type { CallToolResult } from '@modelcontextprotocol/server';
|
|
11
11
|
import {
|
|
12
12
|
loadCorpusProjection,
|
|
13
13
|
CorpusUnavailableError,
|
|
@@ -265,7 +265,7 @@ export function renderResponseText(spec: TextSpec): string {
|
|
|
265
265
|
* ------------------------------------------------------------------ */
|
|
266
266
|
|
|
267
267
|
export type ToolInputSchema = z.ZodType;
|
|
268
|
-
export type ToolOutputSchema = z.
|
|
268
|
+
export type ToolOutputSchema = z.ZodType;
|
|
269
269
|
|
|
270
270
|
const uniqueArray = <T>(schema: z.ZodType<T>, min: number, max: number) =>
|
|
271
271
|
z
|
|
@@ -392,7 +392,7 @@ export function searchDecisionsOutputSchema(): ToolOutputSchema {
|
|
|
392
392
|
sourcePath: z.string(),
|
|
393
393
|
matchedFields: z.array(z.enum(['id', 'title', 'tag', 'body'])),
|
|
394
394
|
});
|
|
395
|
-
return {
|
|
395
|
+
return z.object({
|
|
396
396
|
corpusHealth: corpusHealthSchema().optional(),
|
|
397
397
|
result: z.discriminatedUnion('outcome', [
|
|
398
398
|
z.object({
|
|
@@ -404,7 +404,7 @@ export function searchDecisionsOutputSchema(): ToolOutputSchema {
|
|
|
404
404
|
invalidCursorSchema(),
|
|
405
405
|
corpusUnavailableSchema(),
|
|
406
406
|
]),
|
|
407
|
-
};
|
|
407
|
+
});
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
export function getDecisionOutputSchema(): ToolOutputSchema {
|
|
@@ -417,7 +417,7 @@ export function getDecisionOutputSchema(): ToolOutputSchema {
|
|
|
417
417
|
frontmatter: AdrFrontmatter,
|
|
418
418
|
body: z.string(),
|
|
419
419
|
});
|
|
420
|
-
return {
|
|
420
|
+
return z.object({
|
|
421
421
|
corpusHealth: corpusHealthSchema().optional(),
|
|
422
422
|
result: z.discriminatedUnion('outcome', [
|
|
423
423
|
z.object({ outcome: z.literal('found'), decision: fullDecision, findings: findingsPageSchema() }),
|
|
@@ -439,7 +439,7 @@ export function getDecisionOutputSchema(): ToolOutputSchema {
|
|
|
439
439
|
invalidCursorSchema(),
|
|
440
440
|
corpusUnavailableSchema(),
|
|
441
441
|
]),
|
|
442
|
-
};
|
|
442
|
+
});
|
|
443
443
|
}
|
|
444
444
|
|
|
445
445
|
export function getDecisionContextOutputSchema(): ToolOutputSchema {
|
|
@@ -451,7 +451,7 @@ export function getDecisionContextOutputSchema(): ToolOutputSchema {
|
|
|
451
451
|
firedMatchers: z.array(z.object({ type: z.string(), pattern: z.string() })),
|
|
452
452
|
relations: relationRefsSchema(),
|
|
453
453
|
});
|
|
454
|
-
return {
|
|
454
|
+
return z.object({
|
|
455
455
|
corpusHealth: corpusHealthSchema().optional(),
|
|
456
456
|
result: z.discriminatedUnion('outcome', [
|
|
457
457
|
z.object({
|
|
@@ -465,7 +465,7 @@ export function getDecisionContextOutputSchema(): ToolOutputSchema {
|
|
|
465
465
|
invalidCursorSchema(),
|
|
466
466
|
corpusUnavailableSchema(),
|
|
467
467
|
]),
|
|
468
|
-
};
|
|
468
|
+
});
|
|
469
469
|
}
|
|
470
470
|
|
|
471
471
|
export function listSupersededOutputSchema(): ToolOutputSchema {
|
|
@@ -493,7 +493,7 @@ export function listSupersededOutputSchema(): ToolOutputSchema {
|
|
|
493
493
|
sourcePath: z.string(),
|
|
494
494
|
supersededBy,
|
|
495
495
|
});
|
|
496
|
-
return {
|
|
496
|
+
return z.object({
|
|
497
497
|
corpusHealth: corpusHealthSchema().optional(),
|
|
498
498
|
result: z.discriminatedUnion('outcome', [
|
|
499
499
|
z.object({
|
|
@@ -505,7 +505,7 @@ export function listSupersededOutputSchema(): ToolOutputSchema {
|
|
|
505
505
|
invalidCursorSchema(),
|
|
506
506
|
corpusUnavailableSchema(),
|
|
507
507
|
]),
|
|
508
|
-
};
|
|
508
|
+
});
|
|
509
509
|
}
|
|
510
510
|
|
|
511
511
|
/* ------------------------------------------------------------------ *
|