ctxjev-mcp 0.1.7 → 0.1.9

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/schemas.d.ts CHANGED
@@ -42,3 +42,7 @@ export declare const pruneHistoryInput: {
42
42
  }, z.core.$strip>>;
43
43
  recencyWeight: z.ZodOptional<z.ZodNumber>;
44
44
  };
45
+ /** dropBelow/summarizeBelow are each in range on their own, but nothing above stops a reversed
46
+ * pair from making 'summarize' unreachable — check the actual values a call resolves to
47
+ * (including the defaults) before running it. */
48
+ export declare function validatePolicyOrdering(dropBelow: number, summarizeBelow: number): void;
package/dist/schemas.js CHANGED
@@ -1,29 +1,43 @@
1
1
  import { z } from 'zod';
2
+ import { DEFAULT_POLICY } from 'ctxjev-core';
3
+ // Entries are billed per input token and, per ctxjev-core's own Entry doc, meant to be a short
4
+ // excerpt rather than a full payload — cap both dimensions at the MCP boundary instead of
5
+ // trusting every caller to already know that.
6
+ const MAX_ENTRIES = 500;
7
+ const MAX_CONTENT_LENGTH = 4000;
2
8
  export const entrySchema = z.object({
3
- id: z.string(),
9
+ id: z.string().min(1),
4
10
  role: z.enum(['user', 'assistant', 'tool']),
5
11
  toolName: z.string().optional(),
6
- content: z.string(),
12
+ content: z.string().max(MAX_CONTENT_LENGTH),
7
13
  timestamp: z.number(),
8
14
  });
9
15
  export const scoreRelevanceInput = {
10
- goal: z.string().describe('The current task/goal to judge each entry\'s relevance against.'),
11
- entries: z.array(entrySchema).describe('The agent history entries to score.'),
16
+ goal: z.string().min(1).describe('The current task/goal to judge each entry\'s relevance against.'),
17
+ entries: z.array(entrySchema).max(MAX_ENTRIES).describe('The agent history entries to score.'),
12
18
  recencyWeight: z
13
19
  .number()
14
20
  .min(0)
15
21
  .max(1)
16
22
  .optional()
17
- .describe('How much an entry\'s position in the batch (recency) should factor into its score, 0-1. Defaults to 0.1.'),
23
+ .describe(`How much an entry's position in the batch (recency) should factor into its score, 0-1. Defaults to ${DEFAULT_POLICY.recencyWeight}.`),
18
24
  };
19
25
  export const pruneHistoryInput = {
20
26
  ...scoreRelevanceInput,
21
- dropBelow: z.number().min(0).max(1).optional().describe('Combined-score floor below which an entry is dropped. Defaults to 0.25.'),
27
+ dropBelow: z.number().min(0).max(1).optional().describe(`Combined-score floor below which an entry is dropped. Defaults to ${DEFAULT_POLICY.dropBelow}.`),
22
28
  summarizeBelow: z
23
29
  .number()
24
30
  .min(0)
25
31
  .max(1)
26
32
  .optional()
27
- .describe('Combined-score floor below which an entry is summarized rather than kept verbatim. Defaults to 0.6.'),
33
+ .describe(`Combined-score floor below which an entry is summarized rather than kept verbatim. Defaults to ${DEFAULT_POLICY.summarizeBelow}.`),
28
34
  };
35
+ /** dropBelow/summarizeBelow are each in range on their own, but nothing above stops a reversed
36
+ * pair from making 'summarize' unreachable — check the actual values a call resolves to
37
+ * (including the defaults) before running it. */
38
+ export function validatePolicyOrdering(dropBelow, summarizeBelow) {
39
+ if (dropBelow > summarizeBelow) {
40
+ throw new Error(`dropBelow (${dropBelow}) must not be greater than summarizeBelow (${summarizeBelow})`);
41
+ }
42
+ }
29
43
  //# sourceMappingURL=schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC;IAC5F,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC7E,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,0GAA0G,CAAC;CACxH,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,mBAAmB;IACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yEAAyE,CAAC;IAClI,cAAc,EAAE,CAAC;SACd,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,qGAAqG,CAAC;CACnH,CAAA"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,+FAA+F;AAC/F,0FAA0F;AAC1F,8CAA8C;AAC9C,MAAM,WAAW,GAAG,GAAG,CAAA;AACvB,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAE/B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iEAAiE,CAAC;IACnG,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC9F,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,sGAAsG,cAAc,CAAC,aAAa,GAAG,CAAC;CACnJ,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,mBAAmB;IACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qEAAqE,cAAc,CAAC,SAAS,GAAG,CAAC;IACzJ,cAAc,EAAE,CAAC;SACd,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,kGAAkG,cAAc,CAAC,cAAc,GAAG,CAAC;CAChJ,CAAA;AAED;;iDAEiD;AACjD,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,cAAsB;IAC9E,IAAI,SAAS,GAAG,cAAc,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,cAAc,SAAS,8CAA8C,cAAc,GAAG,CAAC,CAAA;IACzG,CAAC;AACH,CAAC"}
package/dist/tools.d.ts CHANGED
@@ -1,8 +1,4 @@
1
1
  import { type Entry } from 'ctxjev-core';
2
- /**
3
- * Plain functions wrapping ctxjev-core, kept independent of the MCP framework so they're
4
- * testable without spinning up a server. src/server.ts adapts these into MCP tool handlers.
5
- */
6
2
  export type ScoreRelevanceArgs = {
7
3
  goal: string;
8
4
  entries: Entry[];
package/dist/tools.js CHANGED
@@ -1,7 +1,20 @@
1
1
  import { DEFAULT_POLICY, createUsageAccumulator, pruneContext, scoreEntries, summarizeSavings } from 'ctxjev-core';
2
+ import { validatePolicyOrdering } from './schemas.js';
3
+ /**
4
+ * Plain functions wrapping ctxjev-core, kept independent of the MCP framework so they're
5
+ * testable without spinning up a server. src/server.ts adapts these into MCP tool handlers.
6
+ */
7
+ // A long-lived server process gets called repeatedly with overlapping history as an agent's
8
+ // transcript grows — this in-memory cache (module-level, shared across calls, but never
9
+ // persisted) means the second call over the same content doesn't re-pay Jev for it. Unbounded,
10
+ // like the CLI's own file-backed cache — fine for one server process's lifetime.
11
+ const scoreCache = (() => {
12
+ const store = new Map();
13
+ return { get: (key) => store.get(key), set: (key, value) => store.set(key, value) };
14
+ })();
2
15
  export async function scoreRelevanceTool({ goal, entries, recencyWeight }) {
3
16
  const { usage, onUsage } = createUsageAccumulator();
4
- const scored = await scoreEntries(entries, goal, recencyWeight ?? DEFAULT_POLICY.recencyWeight, { onUsage });
17
+ const scored = await scoreEntries(entries, goal, recencyWeight ?? DEFAULT_POLICY.recencyWeight, { onUsage, cache: scoreCache });
5
18
  return { scored, usage };
6
19
  }
7
20
  export async function pruneHistoryTool({ goal, entries, recencyWeight, dropBelow, summarizeBelow }) {
@@ -10,8 +23,9 @@ export async function pruneHistoryTool({ goal, entries, recencyWeight, dropBelow
10
23
  summarizeBelow: summarizeBelow ?? DEFAULT_POLICY.summarizeBelow,
11
24
  recencyWeight: recencyWeight ?? DEFAULT_POLICY.recencyWeight,
12
25
  };
26
+ validatePolicyOrdering(policy.dropBelow, policy.summarizeBelow);
13
27
  const { usage, onUsage } = createUsageAccumulator();
14
- const decisions = await pruneContext(entries, goal, policy, { onUsage });
28
+ const decisions = await pruneContext(entries, goal, policy, { onUsage, cache: scoreCache });
15
29
  const savings = summarizeSavings(entries, decisions);
16
30
  return { decisions, savings, usage };
17
31
  }
package/dist/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAkC,MAAM,aAAa,CAAA;AAalJ,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAsB;IAC3F,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,sBAAsB,EAAE,CAAA;IACnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,IAAI,cAAc,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IAC5G,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAC1B,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAoB;IAClH,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,SAAS,IAAI,cAAc,CAAC,SAAS;QAChD,cAAc,EAAE,cAAc,IAAI,cAAc,CAAC,cAAc;QAC/D,aAAa,EAAE,aAAa,IAAI,cAAc,CAAC,aAAa;KAC7D,CAAA;IAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,sBAAsB,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACpD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AACtC,CAAC"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAmD,MAAM,aAAa,CAAA;AACnK,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAErD;;;GAGG;AAEH,4FAA4F;AAC5F,wFAAwF;AACxF,+FAA+F;AAC/F,iFAAiF;AACjF,MAAM,UAAU,GAAe,CAAC,GAAG,EAAE;IACnC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAA;AACrF,CAAC,CAAC,EAAE,CAAA;AAQJ,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAsB;IAC3F,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,sBAAsB,EAAE,CAAA;IACnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,IAAI,cAAc,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/H,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAC1B,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAoB;IAClH,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,SAAS,IAAI,cAAc,CAAC,SAAS;QAChD,cAAc,EAAE,cAAc,IAAI,cAAc,CAAC,cAAc;QAC/D,aAAa,EAAE,aAAa,IAAI,cAAc,CAAC,aAAa;KAC7D,CAAA;IACD,sBAAsB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;IAE/D,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,sBAAsB,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;IAC3F,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACpD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AACtC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ctxjev-mcp",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "MCP server exposing ctxjev's Jev-based context scoring/pruning as tools for any MCP-capable agent host.",
5
5
  "keywords": [
6
6
  "mcp",
@@ -40,7 +40,7 @@
40
40
  "dependencies": {
41
41
  "@modelcontextprotocol/sdk": "^1.30.0",
42
42
  "zod": "^4.6.5",
43
- "ctxjev-core": "0.1.7"
43
+ "ctxjev-core": "0.1.9"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^22",