@evantahler/mcpx 0.15.4 → 0.15.8

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.
@@ -1,6 +1,7 @@
1
1
  import type { SearchIndex } from "../config/schemas.ts";
2
2
  import { keywordSearch } from "./keyword.ts";
3
3
  import { semanticSearch } from "./semantic.ts";
4
+ import { DEFAULTS } from "../constants.ts";
4
5
 
5
6
  export interface SearchResult {
6
7
  server: string;
@@ -22,7 +23,7 @@ export async function search(
22
23
  index: SearchIndex,
23
24
  options: SearchOptions = {},
24
25
  ): Promise<SearchResult[]> {
25
- const topK = options.topK ?? 10;
26
+ const topK = options.topK ?? DEFAULTS.SEARCH_TOP_K;
26
27
  const results = new Map<string, SearchResult>();
27
28
 
28
29
  const runKeyword = !options.semanticOnly;
@@ -1,11 +1,8 @@
1
1
  import picomatch from "picomatch";
2
2
  import type { IndexedTool } from "../config/schemas.ts";
3
+ import type { BaseMatch } from "./types.ts";
3
4
 
4
- export interface KeywordMatch {
5
- server: string;
6
- tool: string;
7
- description: string;
8
- score: number;
5
+ export interface KeywordMatch extends BaseMatch {
9
6
  matchedField: string;
10
7
  }
11
8
 
@@ -1,11 +1,8 @@
1
1
  import type { IndexedTool } from "../config/schemas.ts";
2
+ import { DEFAULTS } from "../constants.ts";
3
+ import type { BaseMatch } from "./types.ts";
2
4
 
3
- export interface SemanticMatch {
4
- server: string;
5
- tool: string;
6
- description: string;
7
- score: number;
8
- }
5
+ export type SemanticMatch = BaseMatch;
9
6
 
10
7
  // Lazy-loaded pipeline singleton
11
8
  let pipelineInstance: ((text: string) => Promise<Float32Array>) | null = null;
@@ -56,7 +53,7 @@ export function cosineSimilarity(a: number[], b: number[]): number {
56
53
  export async function semanticSearch(
57
54
  query: string,
58
55
  tools: IndexedTool[],
59
- topK = 10,
56
+ topK = DEFAULTS.SEARCH_TOP_K,
60
57
  ): Promise<SemanticMatch[]> {
61
58
  // Only search tools that have embeddings
62
59
  const withEmbeddings = tools.filter((t) => t.embedding.length > 0);
@@ -0,0 +1,7 @@
1
+ /** Base interface for tool search matches */
2
+ export interface BaseMatch {
3
+ server: string;
4
+ tool: string;
5
+ description: string;
6
+ score: number;
7
+ }
@@ -16,18 +16,12 @@ export interface ValidationResult {
16
16
  errors: ValidationError[];
17
17
  }
18
18
 
19
- /** Validate tool arguments against the tool's inputSchema */
20
- export function validateToolInput(
21
- serverName: string,
22
- tool: Tool,
19
+ /** Compile (or retrieve from cache), validate, and return result */
20
+ function validateWithSchema(
21
+ cacheKey: string,
22
+ schema: Record<string, unknown>,
23
23
  input: Record<string, unknown>,
24
24
  ): ValidationResult {
25
- const schema = tool.inputSchema;
26
- if (!schema || Object.keys(schema).length === 0) {
27
- return { valid: true, errors: [] };
28
- }
29
-
30
- const cacheKey = `${serverName}/${tool.name}`;
31
25
  let validate = validatorCache.get(cacheKey);
32
26
 
33
27
  if (!validate) {
@@ -35,7 +29,6 @@ export function validateToolInput(
35
29
  validate = ajv.compile(schema);
36
30
  validatorCache.set(cacheKey, validate);
37
31
  } catch {
38
- // If schema can't be compiled, skip validation
39
32
  return { valid: true, errors: [] };
40
33
  }
41
34
  }
@@ -49,30 +42,25 @@ export function validateToolInput(
49
42
  return { valid: false, errors };
50
43
  }
51
44
 
52
- /** Validate user-collected form data against an elicitation requestedSchema */
53
- export function validateElicitationResponse(
54
- schema: Record<string, unknown>,
45
+ /** Validate tool arguments against the tool's inputSchema */
46
+ export function validateToolInput(
47
+ serverName: string,
48
+ tool: Tool,
55
49
  input: Record<string, unknown>,
56
50
  ): ValidationResult {
57
- const cacheKey = `__elicitation__${JSON.stringify(schema)}`;
58
- let validate = validatorCache.get(cacheKey);
59
-
60
- if (!validate) {
61
- try {
62
- validate = ajv.compile(schema);
63
- validatorCache.set(cacheKey, validate);
64
- } catch {
65
- return { valid: true, errors: [] };
66
- }
67
- }
68
-
69
- const valid = validate(input);
70
- if (valid) {
51
+ const schema = tool.inputSchema;
52
+ if (!schema || Object.keys(schema).length === 0) {
71
53
  return { valid: true, errors: [] };
72
54
  }
55
+ return validateWithSchema(`${serverName}/${tool.name}`, schema, input);
56
+ }
73
57
 
74
- const errors = (validate.errors ?? []).map(formatAjvError);
75
- return { valid: false, errors };
58
+ /** Validate user-collected form data against an elicitation requestedSchema */
59
+ export function validateElicitationResponse(
60
+ schema: Record<string, unknown>,
61
+ input: Record<string, unknown>,
62
+ ): ValidationResult {
63
+ return validateWithSchema(`__elicitation__${JSON.stringify(schema)}`, schema, input);
76
64
  }
77
65
 
78
66
  function formatAjvError(err: ErrorObject): ValidationError {