Coverage for mcp/tools/examples.py: 96%

58 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-15 15:07 +0000

1"""Example manifest discovery MCP tool. 

2 

3Wraps the ``EXAMPLE_METADATA`` catalog defined in ``mcp/resources/docs.py`` 

4and exposes a single ``find_examples`` tool that the LLM can call with a 

5free-text query plus optional category/gpu/opt_in filters. Scoring is a 

6deterministic weighted sum over keyword/summary/name/use_case substring 

7matches; results are sorted by score descending then name ascending so a 

8caller iterating with ``limit`` always sees a stable ordering. 

9""" 

10 

11from audit import audit_logged 

12from resources.docs import EXAMPLE_METADATA 

13from server import mcp 

14 

15 

16def _coerce_bool_flag(value: str | bool | None) -> bool | None: 

17 """Normalise a string/bool tri-state filter to True/False/None. 

18 

19 Returns ``None`` when the caller did not supply a filter (so the 

20 search loop knows to skip the gpu/opt_in checks entirely). 

21 """ 

22 if value is None: 

23 return None 

24 if isinstance(value, bool): 

25 return value 

26 return value.strip().lower() in ("yes", "true", "1") 

27 

28 

29def _has_gpu(meta: dict[str, str | list[str]]) -> bool: 

30 """Treat anything other than ``"no"``/``""`` as GPU-bearing. 

31 

32 The ``gpu`` field carries values like ``"NVIDIA"``, ``"NVIDIA + EFA"``, 

33 ``"Trainium"``, ``"Inferentia"``, ``"NVIDIA (time-sliced)"``, and 

34 ``"optional"`` — all of which should match ``gpu="yes"``. 

35 """ 

36 return str(meta.get("gpu", "no")) not in ("", "no") 

37 

38 

39def _search( 

40 query: str | None, 

41 category: str | None, 

42 gpu: str | bool | None, 

43 opt_in: str | bool | None, 

44) -> list[tuple[str, int]]: 

45 """Filter and score examples; return ``[(name, score), ...]`` sorted desc.""" 

46 want_gpu = _coerce_bool_flag(gpu) 

47 want_opt_in = _coerce_bool_flag(opt_in) 

48 q = query.lower() if query else None 

49 

50 results: list[tuple[str, int]] = [] 

51 for name, meta in EXAMPLE_METADATA.items(): 

52 # Hard filters — drop the entry when any non-matching filter is set. 

53 if category and str(meta.get("category", "")).lower() != category.lower(): 53 ↛ 54line 53 didn't jump to line 54 because the condition on line 53 was never true

54 continue 

55 if want_gpu is not None and _has_gpu(meta) != want_gpu: 

56 continue 

57 if want_opt_in is not None and bool(meta.get("opt_in", "")) != want_opt_in: 

58 continue 

59 

60 # Scoring runs only when there's a query — without one, every entry 

61 # that survived the filters is included with score 0. 

62 score = 0 

63 if q: 

64 keywords = meta.get("keywords", []) 

65 if isinstance(keywords, list): 65 ↛ 69line 65 didn't jump to line 69 because the condition on line 65 was always true

66 for kw in keywords: 

67 if q in str(kw).lower(): 

68 score += 5 

69 if q in str(meta.get("summary", "")).lower(): 

70 score += 2 

71 if q in name.lower(): 

72 score += 3 

73 use_cases = meta.get("use_cases", []) 

74 if isinstance(use_cases, list): 74 ↛ 78line 74 didn't jump to line 78 because the condition on line 74 was always true

75 for uc in use_cases: 

76 if q in str(uc).lower(): 

77 score += 3 

78 if score == 0: 

79 continue 

80 results.append((name, score)) 

81 

82 # Sort by score desc, then name asc for stable ordering across calls. 

83 results.sort(key=lambda x: (-x[1], x[0])) 

84 return results 

85 

86 

87def _format(name: str) -> dict[str, object]: 

88 """Format a metadata entry for the tool response.""" 

89 meta = EXAMPLE_METADATA.get(name, {}) 

90 return { 

91 "name": name, 

92 "category": meta.get("category", ""), 

93 "summary": meta.get("summary", ""), 

94 "gpu": meta.get("gpu", "no"), 

95 "opt_in": meta.get("opt_in", ""), 

96 "submission": meta.get("submission", ""), 

97 "keywords": meta.get("keywords", []), 

98 "use_cases": meta.get("use_cases", []), 

99 "related": meta.get("related", []), 

100 } 

101 

102 

103@mcp.tool(tags={"safe", "examples"}) 

104@audit_logged 

105async def find_examples( 

106 query: str | None = None, 

107 category: str | None = None, 

108 gpu: str | None = None, 

109 opt_in: str | None = None, 

110 limit: int = 10, 

111) -> list[dict[str, object]]: 

112 """`find_examples` — search the example-manifest catalog by keyword and filters. 

113 

114 Args: 

115 query: Natural-language query matched against keywords, summary, 

116 name, and use_cases (case-insensitive substring match). 

117 category: Filter by category (case-insensitive exact match). 

118 gpu: Pass ``"yes"``/``"true"`` to require GPU examples; 

119 ``"no"``/``"false"`` to exclude. Omit to leave unconstrained. 

120 opt_in: Pass ``"yes"`` to require an opt-in feature flag; 

121 ``"no"`` to exclude. 

122 limit: Maximum results (default 10). ``limit <= 0`` returns ``[]``. 

123 

124 Returns a list of dicts with ``name``, ``category``, ``summary``, 

125 ``gpu``, ``opt_in``, ``submission``, ``keywords``, ``use_cases``, and 

126 ``related`` for each match. 

127 """ 

128 if limit <= 0: 

129 return [] 

130 

131 no_filters = not query and not category and gpu is None and opt_in is None 

132 if no_filters: 

133 # Stable alpha-sorted listing for the no-arg case. 

134 names = sorted(EXAMPLE_METADATA.keys())[:limit] 

135 return [_format(name) for name in names] 

136 

137 matches = _search(query, category, gpu, opt_in) 

138 return [_format(name) for name, _score in matches[:limit]]