model-finder-mcp 1.3.5__tar.gz

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.
Files changed (25) hide show
  1. model_finder_mcp-1.3.5/.gitignore +25 -0
  2. model_finder_mcp-1.3.5/LICENSE +21 -0
  3. model_finder_mcp-1.3.5/PKG-INFO +248 -0
  4. model_finder_mcp-1.3.5/README.md +232 -0
  5. model_finder_mcp-1.3.5/evaluations/README.md +23 -0
  6. model_finder_mcp-1.3.5/evaluations/fixture-repo/README.md +1 -0
  7. model_finder_mcp-1.3.5/mcp/server.py +876 -0
  8. model_finder_mcp-1.3.5/pypi/__init__.py +1 -0
  9. model_finder_mcp-1.3.5/pyproject.toml +39 -0
  10. model_finder_mcp-1.3.5/skills/eval-models/SKILL.md +51 -0
  11. model_finder_mcp-1.3.5/skills/eval-models/assets/example-config.json +65 -0
  12. model_finder_mcp-1.3.5/skills/eval-models/references/config-schema.md +67 -0
  13. model_finder_mcp-1.3.5/skills/eval-models/scripts/eval_models.py +379 -0
  14. model_finder_mcp-1.3.5/skills/eval-models/scripts/mf_core.py +624 -0
  15. model_finder_mcp-1.3.5/skills/eval-models/scripts/repo_scan.py +420 -0
  16. model_finder_mcp-1.3.5/skills/find-model/SKILL.md +65 -0
  17. model_finder_mcp-1.3.5/skills/find-model/references/analytics.md +9 -0
  18. model_finder_mcp-1.3.5/skills/find-model/references/coding-tasks.md +35 -0
  19. model_finder_mcp-1.3.5/skills/find-model/references/selection-rubric.md +38 -0
  20. model_finder_mcp-1.3.5/skills/route-models/SKILL.md +54 -0
  21. model_finder_mcp-1.3.5/skills/route-models/assets/router.py +110 -0
  22. model_finder_mcp-1.3.5/skills/route-models/scripts/make_routing.py +204 -0
  23. model_finder_mcp-1.3.5/skills/route-models/scripts/mf_core.py +624 -0
  24. model_finder_mcp-1.3.5/skills/size-local-model/SKILL.md +52 -0
  25. model_finder_mcp-1.3.5/skills/size-local-model/scripts/estimate_memory.py +134 -0
@@ -0,0 +1,25 @@
1
+ __pycache__/
2
+ *.pyc
3
+ model-eval-results/
4
+ results/
5
+ routing/
6
+ .env
7
+ .env.*
8
+ !.env.example
9
+ .venv/
10
+ venv/
11
+ .DS_Store
12
+ *.pem
13
+ *.key
14
+ *.p12
15
+ *.pfx
16
+ credentials.json
17
+ secrets.json
18
+
19
+ # Decoy for the eval fixture: proves secret-looking files are skipped (contains no secret)
20
+ !evaluations/fixture-repo/credentials.json
21
+
22
+ # Python packaging output
23
+ dist/
24
+ build/
25
+ *.egg-info/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Indigloo Softwares Private Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.5
2
+ Name: model-finder-mcp
3
+ Version: 1.3.5
4
+ Summary: Local MCP server: find the cheapest AI model that passes your own tests
5
+ Project-URL: Homepage, https://github.com/Abhiindigloo/EvalHarness
6
+ Project-URL: Issues, https://github.com/Abhiindigloo/EvalHarness/issues
7
+ Author: Indigloo
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: claude,evaluation,gemini,llm,mcp,model-selection,openai,routing
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+
17
+ <p align="center">
18
+ <picture>
19
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Abhiindigloo/EvalHarness/main/assets/readme-hero-dark.png">
20
+ <img alt="Model Finder: a field of test results across sixteen candidate models ordered by cost, with the cheapest model that passes the threshold marked in vermilion" src="https://raw.githubusercontent.com/Abhiindigloo/EvalHarness/main/assets/readme-hero-light.png" width="100%">
21
+ </picture>
22
+ </p>
23
+
24
+ <p align="center">
25
+ <a href="https://github.com/Abhiindigloo/EvalHarness/actions/workflows/test.yml"><img alt="tests" src="https://github.com/Abhiindigloo/EvalHarness/actions/workflows/test.yml/badge.svg"></a>
26
+ <img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9%2B-1c1b19?labelColor=f3f0e8">
27
+ <img alt="dependencies: none" src="https://img.shields.io/badge/dependencies-none-1c1b19?labelColor=f3f0e8">
28
+ <img alt="MCP: local stdio" src="https://img.shields.io/badge/MCP-local%20stdio-cd462a?labelColor=f3f0e8">
29
+ <a href="LICENSE"><img alt="license MIT" src="https://img.shields.io/badge/license-MIT-1c1b19?labelColor=f3f0e8"></a>
30
+ </p>
31
+
32
+ <p align="center">
33
+ <b>Find the cheapest AI model that passes your own tests, and keep it that way.</b><br>
34
+ <sub>Claude · Gemini · OpenAI · Bedrock · Vertex AI · local models — published by Indigloo</sub>
35
+ </p>
36
+
37
+ <p align="center">
38
+ <a href="#install">Install</a> &nbsp;·&nbsp;
39
+ <a href="#how-it-works">How it works</a> &nbsp;·&nbsp;
40
+ <a href="#mcp-tools">MCP tools</a> &nbsp;·&nbsp;
41
+ <a href="#quick-start">Quick start</a> &nbsp;·&nbsp;
42
+ <a href="PRIVACY.md">Privacy</a> &nbsp;·&nbsp;
43
+ <a href="SECURITY.md">Security</a>
44
+ </p>
45
+
46
+ <!-- mcp-name: co.indigloo/model-finder -->
47
+
48
+ > [!NOTE]
49
+ > **Runs locally.** Model Finder is a set of four Agent Skills plus a local MCP server (`mcp/server.py`, Python 3.9+ standard library, no dependencies). The server makes no network calls, needs no API keys, never writes files and never sends anything to Indigloo. Only the eval script and the router it generates call model providers, with your own keys, when you run them.
50
+
51
+ ## How it works
52
+
53
+ ```mermaid
54
+ flowchart LR
55
+ A["Audit<br/><sub>models and SDKs in your repo</sub>"] --> B["Draft evals<br/><sub>from your prompts, PII dropped</sub>"]
56
+ B --> C["Evaluate<br/><sub>your keys · pass rate · latency · cost</sub>"]
57
+ C --> D["Rank<br/><sub>cost per passing answer</sub>"]
58
+ D --> E["Route<br/><sub>cheapest first, escalate on failure</sub>"]
59
+ F["Size<br/><sub>weights + KV cache vs your GPU</sub>"] -.-> C
60
+ classDef step fill:#f3f0e8,stroke:#1c1b19,color:#1c1b19;
61
+ classDef pick fill:#f3f0e8,stroke:#cd462a,color:#cd462a;
62
+ class A,B,C,E,F step;
63
+ class D pick;
64
+ ```
65
+
66
+ | Skill | What it does |
67
+ |---|---|
68
+ | `find-model` | Recommends models across Claude, Gemini, OpenAI, cloud, and local options for your task, budget, and route, including coding subtasks in an IDE. |
69
+ | `eval-models` | Runs your examples against shortlisted models and measures pass rate, latency, and billed cost with your own keys. |
70
+ | `route-models` | Builds a cheapest-first routing setup: a standalone router with quality guards plus a LiteLLM config. |
71
+ | `size-local-model` | Estimates memory for weights and KV cache and compares it with your hardware. |
72
+
73
+ Advisory only: nothing is deployed, your active model is never changed, and data goes only to providers you configure and approve. Personal data and secrets are blocked before sending by default; see [DATA-PROTECTION.md](DATA-PROTECTION.md) for how this maps to India's DPDP Act.
74
+
75
+ ## Install
76
+
77
+ Requires Python 3.9+ on your PATH as `python3` (see [Windows](#windows)). Nothing to `pip install`.
78
+
79
+ | Client | Command | Skills | MCP tools |
80
+ |---|---|:-:|---|
81
+ | **Claude Code** | `/plugin marketplace add Abhiindigloo/EvalHarness` then `/plugin install model-finder@model-finder` | ✅ | ✅ via `.mcp.json` |
82
+ | **OpenAI Codex CLI** | `codex plugin marketplace add Abhiindigloo/EvalHarness` then `codex plugin add model-finder@model-finder` | ✅ | ✅ via `mcp.json` (Agent Plugins format, runs `./mcp/server.py`). Codex gives the server no workspace, so the agent passes the project path |
83
+ | **GitHub Copilot CLI** | `copilot plugin marketplace add Abhiindigloo/EvalHarness` then `copilot plugin install model-finder@model-finder` | ✅ | ✅ via `mcp.json` |
84
+ | **Gemini CLI** | `gemini extensions install https://github.com/Abhiindigloo/EvalHarness` | ✅ | ✅ via `gemini-extension.json` |
85
+ | **Cursor** | Install from the Cursor marketplace or cursor.directory once listed. Until then, clone into `~/.cursor/plugins/local/model-finder` and reload the window | ✅ | ✅ via `mcp.json` or `.cursor-plugin/plugin.json` → `.mcp.json` |
86
+ | **Any MCP client, from PyPI** | `uvx model-finder-mcp` (published by the release workflow; see [Releases](#releases)) | — | ✅ |
87
+ | **VS Code, JetBrains, Windsurf, others** | Add the server to the client's MCP settings ([manual setup](#manual-mcp-setup)) | — | ✅ |
88
+ | **Other Agent Skills clients** | Copy `skills/<name>/` into the client's skills directory | ✅ | — |
89
+
90
+ Gemini CLI only starts extension MCP servers in folders you have trusted; it asks the first time you open a project.
91
+
92
+ ### Manual MCP setup
93
+
94
+ <details>
95
+ <summary><b>VS Code</b> — <code>.vscode/mcp.json</code> (top-level key is <code>servers</code>)</summary>
96
+
97
+ ```json
98
+ {
99
+ "servers": {
100
+ "model-finder": {
101
+ "type": "stdio",
102
+ "command": "python3",
103
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
104
+ "env": { "MODEL_FINDER_ROOT": "${workspaceFolder}" }
105
+ }
106
+ }
107
+ }
108
+ ```
109
+ </details>
110
+
111
+ <details>
112
+ <summary><b>Cursor</b> — <code>.cursor/mcp.json</code> in your project, or <code>~/.cursor/mcp.json</code></summary>
113
+
114
+ ```json
115
+ {
116
+ "mcpServers": {
117
+ "model-finder": {
118
+ "command": "python3",
119
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
120
+ "env": { "MODEL_FINDER_ROOT": "${workspaceFolder}" }
121
+ }
122
+ }
123
+ }
124
+ ```
125
+ </details>
126
+
127
+ <details>
128
+ <summary><b>JetBrains, Windsurf, Claude Desktop and others</b> — <code>mcpServers</code></summary>
129
+
130
+ If the client has no workspace variable, write the project path:
131
+
132
+ ```json
133
+ {
134
+ "mcpServers": {
135
+ "model-finder": {
136
+ "command": "python3",
137
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
138
+ "env": { "MODEL_FINDER_ROOT": "/absolute/path/to/your/project" }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+ </details>
144
+
145
+ Clone the repo once and replace `/absolute/path/to/EvalHarness`. Repository tools read only inside the workspace: the roots your client shares over MCP, else `MODEL_FINDER_ROOT`, else the server's working directory. A filesystem root or home directory is refused.
146
+
147
+ ### Windows
148
+
149
+ Codex, Copilot CLI and Cursor start the server as `./mcp/server.py`, which relies on its `#!/usr/bin/env python3` line; on Windows use the manual setup or `uvx model-finder-mcp`. If `python3` is not on your PATH, the MCP server will not start. Install Python from python.org (tick "Add python.exe to PATH") and either create a `python3` alias or use the manual setup with `"command": "py"` and `"args": ["-3", "C:/path/to/EvalHarness/mcp/server.py"]`.
150
+
151
+ ## MCP tools
152
+
153
+ Ten read-only tools, so the same features work as tools in every supported IDE:
154
+
155
+ | Tool | What it does |
156
+ |---|---|
157
+ | `modelfinder_audit_models` | Lists AI model IDs and SDKs in your repo with file:line locations, routes and hard-coded IDs |
158
+ | `modelfinder_draft_eval_examples` | Drafts eval examples from prompt files and fixtures, dropping anything with personal data or secrets |
159
+ | `modelfinder_create_eval_config` · `modelfinder_validate_eval_config` | Builds and checks an eval config: call count, env var names, unpriced models, guard verdict |
160
+ | `modelfinder_check_output` | Tests a reply against eval checks or routing guards |
161
+ | `modelfinder_rank_eval_results` | Ranks results by cost per passing answer, with the cost/reliability cascade |
162
+ | `modelfinder_generate_routing` | Returns routing.json and a LiteLLM config from eval results |
163
+ | `modelfinder_estimate_cost` | Monthly token cost and cost per accepted result |
164
+ | `modelfinder_estimate_memory` | Local memory for weights and KV cache |
165
+ | `modelfinder_scan_sensitive_data` | Personal-data and secrets scan (categories and counts only) |
166
+
167
+ Every tool returns a readable markdown summary by default and the full result as structured JSON (`response_format: "json"` puts the JSON in the text too). Large results are paginated (`limit`, `offset`, `has_more`, `next_offset`), `modelfinder_audit_models` can filter by provider family or hard-coded IDs, and unknown arguments are rejected with the list of valid ones. The server never opens a network connection, never reads API keys and never writes files. Only `eval_models.py` and the generated `router.py` call model providers, with your keys, when you run them.
168
+
169
+ ## Quick start
170
+
171
+ In your IDE, ask: *"Audit which AI models this repo uses, then draft evals from our prompts and test whether a cheaper model passes."* The assistant uses the MCP tools to audit and draft, agrees checks with you, and asks before the paid run.
172
+
173
+ From a terminal:
174
+
175
+ ```bash
176
+ cp skills/eval-models/assets/example-config.json my-eval.json # fill in verified model IDs and prices
177
+ export ANTHROPIC_API_KEY=... GEMINI_API_KEY=... OPENAI_API_KEY=...
178
+ python3 skills/eval-models/scripts/repo_scan.py audit . # what the repo uses
179
+ python3 skills/eval-models/scripts/repo_scan.py examples . # draft examples from prompt files
180
+ python3 skills/eval-models/scripts/eval_models.py my-eval.json --dry-run
181
+ python3 skills/eval-models/scripts/eval_models.py my-eval.json --out results
182
+ python3 skills/route-models/scripts/make_routing.py --results results/results.json --guards guards.json --out routing
183
+ python3 routing/router.py routing/routing.json "your prompt"
184
+ ```
185
+
186
+ **Size a local model:**
187
+
188
+ ```bash
189
+ python3 skills/size-local-model/scripts/estimate_memory.py --params-b 8.03 --bits 16 \
190
+ --layers 32 --kv-heads 8 --head-dim 128 --context 8192 --available-gib 24
191
+ ```
192
+
193
+ ## Tests
194
+
195
+ ```bash
196
+ python3 -m unittest discover -s tests -v
197
+ ```
198
+
199
+ End-to-end tests run against a local mock of the OpenAI-compatible, Anthropic, and Gemini APIs, and drive the MCP server over stdio; no key or network access is needed. [`evaluations/`](evaluations/) holds a 10-question agent evaluation of the MCP tools.
200
+
201
+ ## Releases
202
+
203
+ 1. Bump the version everywhere (`python3 tests/check_release_version.py` lists any field that differs) and add a CHANGELOG entry.
204
+ 2. Push a tag `vX.Y.Z`. `release.yml` runs the tests, checks the versions, builds the package, publishes it to PyPI with trusted publishing, then publishes `server.json` to the official MCP Registry.
205
+ 3. One-time setup:
206
+ - **PyPI**: add a pending trusted publisher for project `model-finder-mcp` (owner `Abhiindigloo`, repository `EvalHarness`, workflow `release.yml`, environment `pypi`), ideally from the Indigloo PyPI organization, and create the `pypi` environment in the repository settings.
207
+ - **MCP Registry** (`co.indigloo/model-finder`, verified through the indigloo.co domain). On your own machine, with OpenSSL 3:
208
+ ```bash
209
+ openssl genpkey -algorithm Ed25519 -out mcp-registry-key.pem
210
+ echo "TXT record for indigloo.co: v=MCPv1; k=ed25519; p=$(openssl pkey -in mcp-registry-key.pem -pubout -outform DER | tail -c 32 | base64)"
211
+ echo "GitHub secret MCP_REGISTRY_PRIVATE_KEY: $(openssl pkey -in mcp-registry-key.pem -noout -text | grep -A3 'priv:' | tail -n +2 | tr -d ' :\n')"
212
+ ```
213
+ Add the TXT record at the apex of indigloo.co, create a repository environment `mcp-registry`, store the hex key as its secret `MCP_REGISTRY_PRIVATE_KEY`, then delete `mcp-registry-key.pem` or keep it in a password manager.
214
+
215
+ <details>
216
+ <summary><b>Repository layout</b></summary>
217
+
218
+ ```
219
+ skills/ shared Agent Skills (single source of truth)
220
+ mcp/server.py local MCP server (stdio, standard library only)
221
+ .mcp.json MCP launch config for Claude Code and Cursor (${CLAUDE_PLUGIN_ROOT}); disabled as a
222
+ project config inside this repo by .claude/settings.json
223
+ mcp.json Agent Plugins MCP launch config (Codex, Copilot CLI, Cursor): runs ./mcp/server.py
224
+ server.json, pyproject.toml MCP Registry entry and PyPI package (model-finder-mcp); pypi/ holds the package marker
225
+ glama.json Glama directory ownership
226
+ .github/workflows/ tests on every push; release.yml publishes tags to PyPI and the MCP Registry
227
+ .claude-plugin/ Claude Code (and Copilot CLI) plugin + marketplace manifests
228
+ .codex-plugin/ Codex plugin manifest
229
+ .agents/plugins/ Codex repository marketplace
230
+ .cursor-plugin/ Cursor plugin + marketplace manifests
231
+ gemini-extension.json Gemini CLI extension (context: GEMINI.md)
232
+ plugin.json Agent Plugins manifest with OpenAI listing metadata
233
+ AGENTS.md, GEMINI.md skill index for agents that read root instructions
234
+ PRIVACY.md, TERMS.md, SUPPORT.md pages the marketplace listings link to
235
+ assets/ logo, README plates, and DESIGN.md (the visual language)
236
+ ```
237
+
238
+ `skills/eval-models/scripts/mf_core.py` is duplicated in `skills/route-models/scripts/` so each skill works on its own. The test suite fails if the copies differ.
239
+ </details>
240
+
241
+ ---
242
+
243
+ <p align="center">
244
+ <sub>
245
+ <a href="SUPPORT.md">Support</a> · <a href="PRIVACY.md">Privacy</a> · <a href="TERMS.md">Terms</a> · <a href="SECURITY.md">Security</a> · <a href="DATA-PROTECTION.md">Data protection</a><br>
246
+ MIT License · © 2026 Indigloo Softwares Private Limited
247
+ </sub>
248
+ </p>
@@ -0,0 +1,232 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Abhiindigloo/EvalHarness/main/assets/readme-hero-dark.png">
4
+ <img alt="Model Finder: a field of test results across sixteen candidate models ordered by cost, with the cheapest model that passes the threshold marked in vermilion" src="https://raw.githubusercontent.com/Abhiindigloo/EvalHarness/main/assets/readme-hero-light.png" width="100%">
5
+ </picture>
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://github.com/Abhiindigloo/EvalHarness/actions/workflows/test.yml"><img alt="tests" src="https://github.com/Abhiindigloo/EvalHarness/actions/workflows/test.yml/badge.svg"></a>
10
+ <img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9%2B-1c1b19?labelColor=f3f0e8">
11
+ <img alt="dependencies: none" src="https://img.shields.io/badge/dependencies-none-1c1b19?labelColor=f3f0e8">
12
+ <img alt="MCP: local stdio" src="https://img.shields.io/badge/MCP-local%20stdio-cd462a?labelColor=f3f0e8">
13
+ <a href="LICENSE"><img alt="license MIT" src="https://img.shields.io/badge/license-MIT-1c1b19?labelColor=f3f0e8"></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <b>Find the cheapest AI model that passes your own tests, and keep it that way.</b><br>
18
+ <sub>Claude · Gemini · OpenAI · Bedrock · Vertex AI · local models — published by Indigloo</sub>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <a href="#install">Install</a> &nbsp;·&nbsp;
23
+ <a href="#how-it-works">How it works</a> &nbsp;·&nbsp;
24
+ <a href="#mcp-tools">MCP tools</a> &nbsp;·&nbsp;
25
+ <a href="#quick-start">Quick start</a> &nbsp;·&nbsp;
26
+ <a href="PRIVACY.md">Privacy</a> &nbsp;·&nbsp;
27
+ <a href="SECURITY.md">Security</a>
28
+ </p>
29
+
30
+ <!-- mcp-name: co.indigloo/model-finder -->
31
+
32
+ > [!NOTE]
33
+ > **Runs locally.** Model Finder is a set of four Agent Skills plus a local MCP server (`mcp/server.py`, Python 3.9+ standard library, no dependencies). The server makes no network calls, needs no API keys, never writes files and never sends anything to Indigloo. Only the eval script and the router it generates call model providers, with your own keys, when you run them.
34
+
35
+ ## How it works
36
+
37
+ ```mermaid
38
+ flowchart LR
39
+ A["Audit<br/><sub>models and SDKs in your repo</sub>"] --> B["Draft evals<br/><sub>from your prompts, PII dropped</sub>"]
40
+ B --> C["Evaluate<br/><sub>your keys · pass rate · latency · cost</sub>"]
41
+ C --> D["Rank<br/><sub>cost per passing answer</sub>"]
42
+ D --> E["Route<br/><sub>cheapest first, escalate on failure</sub>"]
43
+ F["Size<br/><sub>weights + KV cache vs your GPU</sub>"] -.-> C
44
+ classDef step fill:#f3f0e8,stroke:#1c1b19,color:#1c1b19;
45
+ classDef pick fill:#f3f0e8,stroke:#cd462a,color:#cd462a;
46
+ class A,B,C,E,F step;
47
+ class D pick;
48
+ ```
49
+
50
+ | Skill | What it does |
51
+ |---|---|
52
+ | `find-model` | Recommends models across Claude, Gemini, OpenAI, cloud, and local options for your task, budget, and route, including coding subtasks in an IDE. |
53
+ | `eval-models` | Runs your examples against shortlisted models and measures pass rate, latency, and billed cost with your own keys. |
54
+ | `route-models` | Builds a cheapest-first routing setup: a standalone router with quality guards plus a LiteLLM config. |
55
+ | `size-local-model` | Estimates memory for weights and KV cache and compares it with your hardware. |
56
+
57
+ Advisory only: nothing is deployed, your active model is never changed, and data goes only to providers you configure and approve. Personal data and secrets are blocked before sending by default; see [DATA-PROTECTION.md](DATA-PROTECTION.md) for how this maps to India's DPDP Act.
58
+
59
+ ## Install
60
+
61
+ Requires Python 3.9+ on your PATH as `python3` (see [Windows](#windows)). Nothing to `pip install`.
62
+
63
+ | Client | Command | Skills | MCP tools |
64
+ |---|---|:-:|---|
65
+ | **Claude Code** | `/plugin marketplace add Abhiindigloo/EvalHarness` then `/plugin install model-finder@model-finder` | ✅ | ✅ via `.mcp.json` |
66
+ | **OpenAI Codex CLI** | `codex plugin marketplace add Abhiindigloo/EvalHarness` then `codex plugin add model-finder@model-finder` | ✅ | ✅ via `mcp.json` (Agent Plugins format, runs `./mcp/server.py`). Codex gives the server no workspace, so the agent passes the project path |
67
+ | **GitHub Copilot CLI** | `copilot plugin marketplace add Abhiindigloo/EvalHarness` then `copilot plugin install model-finder@model-finder` | ✅ | ✅ via `mcp.json` |
68
+ | **Gemini CLI** | `gemini extensions install https://github.com/Abhiindigloo/EvalHarness` | ✅ | ✅ via `gemini-extension.json` |
69
+ | **Cursor** | Install from the Cursor marketplace or cursor.directory once listed. Until then, clone into `~/.cursor/plugins/local/model-finder` and reload the window | ✅ | ✅ via `mcp.json` or `.cursor-plugin/plugin.json` → `.mcp.json` |
70
+ | **Any MCP client, from PyPI** | `uvx model-finder-mcp` (published by the release workflow; see [Releases](#releases)) | — | ✅ |
71
+ | **VS Code, JetBrains, Windsurf, others** | Add the server to the client's MCP settings ([manual setup](#manual-mcp-setup)) | — | ✅ |
72
+ | **Other Agent Skills clients** | Copy `skills/<name>/` into the client's skills directory | ✅ | — |
73
+
74
+ Gemini CLI only starts extension MCP servers in folders you have trusted; it asks the first time you open a project.
75
+
76
+ ### Manual MCP setup
77
+
78
+ <details>
79
+ <summary><b>VS Code</b> — <code>.vscode/mcp.json</code> (top-level key is <code>servers</code>)</summary>
80
+
81
+ ```json
82
+ {
83
+ "servers": {
84
+ "model-finder": {
85
+ "type": "stdio",
86
+ "command": "python3",
87
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
88
+ "env": { "MODEL_FINDER_ROOT": "${workspaceFolder}" }
89
+ }
90
+ }
91
+ }
92
+ ```
93
+ </details>
94
+
95
+ <details>
96
+ <summary><b>Cursor</b> — <code>.cursor/mcp.json</code> in your project, or <code>~/.cursor/mcp.json</code></summary>
97
+
98
+ ```json
99
+ {
100
+ "mcpServers": {
101
+ "model-finder": {
102
+ "command": "python3",
103
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
104
+ "env": { "MODEL_FINDER_ROOT": "${workspaceFolder}" }
105
+ }
106
+ }
107
+ }
108
+ ```
109
+ </details>
110
+
111
+ <details>
112
+ <summary><b>JetBrains, Windsurf, Claude Desktop and others</b> — <code>mcpServers</code></summary>
113
+
114
+ If the client has no workspace variable, write the project path:
115
+
116
+ ```json
117
+ {
118
+ "mcpServers": {
119
+ "model-finder": {
120
+ "command": "python3",
121
+ "args": ["/absolute/path/to/EvalHarness/mcp/server.py"],
122
+ "env": { "MODEL_FINDER_ROOT": "/absolute/path/to/your/project" }
123
+ }
124
+ }
125
+ }
126
+ ```
127
+ </details>
128
+
129
+ Clone the repo once and replace `/absolute/path/to/EvalHarness`. Repository tools read only inside the workspace: the roots your client shares over MCP, else `MODEL_FINDER_ROOT`, else the server's working directory. A filesystem root or home directory is refused.
130
+
131
+ ### Windows
132
+
133
+ Codex, Copilot CLI and Cursor start the server as `./mcp/server.py`, which relies on its `#!/usr/bin/env python3` line; on Windows use the manual setup or `uvx model-finder-mcp`. If `python3` is not on your PATH, the MCP server will not start. Install Python from python.org (tick "Add python.exe to PATH") and either create a `python3` alias or use the manual setup with `"command": "py"` and `"args": ["-3", "C:/path/to/EvalHarness/mcp/server.py"]`.
134
+
135
+ ## MCP tools
136
+
137
+ Ten read-only tools, so the same features work as tools in every supported IDE:
138
+
139
+ | Tool | What it does |
140
+ |---|---|
141
+ | `modelfinder_audit_models` | Lists AI model IDs and SDKs in your repo with file:line locations, routes and hard-coded IDs |
142
+ | `modelfinder_draft_eval_examples` | Drafts eval examples from prompt files and fixtures, dropping anything with personal data or secrets |
143
+ | `modelfinder_create_eval_config` · `modelfinder_validate_eval_config` | Builds and checks an eval config: call count, env var names, unpriced models, guard verdict |
144
+ | `modelfinder_check_output` | Tests a reply against eval checks or routing guards |
145
+ | `modelfinder_rank_eval_results` | Ranks results by cost per passing answer, with the cost/reliability cascade |
146
+ | `modelfinder_generate_routing` | Returns routing.json and a LiteLLM config from eval results |
147
+ | `modelfinder_estimate_cost` | Monthly token cost and cost per accepted result |
148
+ | `modelfinder_estimate_memory` | Local memory for weights and KV cache |
149
+ | `modelfinder_scan_sensitive_data` | Personal-data and secrets scan (categories and counts only) |
150
+
151
+ Every tool returns a readable markdown summary by default and the full result as structured JSON (`response_format: "json"` puts the JSON in the text too). Large results are paginated (`limit`, `offset`, `has_more`, `next_offset`), `modelfinder_audit_models` can filter by provider family or hard-coded IDs, and unknown arguments are rejected with the list of valid ones. The server never opens a network connection, never reads API keys and never writes files. Only `eval_models.py` and the generated `router.py` call model providers, with your keys, when you run them.
152
+
153
+ ## Quick start
154
+
155
+ In your IDE, ask: *"Audit which AI models this repo uses, then draft evals from our prompts and test whether a cheaper model passes."* The assistant uses the MCP tools to audit and draft, agrees checks with you, and asks before the paid run.
156
+
157
+ From a terminal:
158
+
159
+ ```bash
160
+ cp skills/eval-models/assets/example-config.json my-eval.json # fill in verified model IDs and prices
161
+ export ANTHROPIC_API_KEY=... GEMINI_API_KEY=... OPENAI_API_KEY=...
162
+ python3 skills/eval-models/scripts/repo_scan.py audit . # what the repo uses
163
+ python3 skills/eval-models/scripts/repo_scan.py examples . # draft examples from prompt files
164
+ python3 skills/eval-models/scripts/eval_models.py my-eval.json --dry-run
165
+ python3 skills/eval-models/scripts/eval_models.py my-eval.json --out results
166
+ python3 skills/route-models/scripts/make_routing.py --results results/results.json --guards guards.json --out routing
167
+ python3 routing/router.py routing/routing.json "your prompt"
168
+ ```
169
+
170
+ **Size a local model:**
171
+
172
+ ```bash
173
+ python3 skills/size-local-model/scripts/estimate_memory.py --params-b 8.03 --bits 16 \
174
+ --layers 32 --kv-heads 8 --head-dim 128 --context 8192 --available-gib 24
175
+ ```
176
+
177
+ ## Tests
178
+
179
+ ```bash
180
+ python3 -m unittest discover -s tests -v
181
+ ```
182
+
183
+ End-to-end tests run against a local mock of the OpenAI-compatible, Anthropic, and Gemini APIs, and drive the MCP server over stdio; no key or network access is needed. [`evaluations/`](evaluations/) holds a 10-question agent evaluation of the MCP tools.
184
+
185
+ ## Releases
186
+
187
+ 1. Bump the version everywhere (`python3 tests/check_release_version.py` lists any field that differs) and add a CHANGELOG entry.
188
+ 2. Push a tag `vX.Y.Z`. `release.yml` runs the tests, checks the versions, builds the package, publishes it to PyPI with trusted publishing, then publishes `server.json` to the official MCP Registry.
189
+ 3. One-time setup:
190
+ - **PyPI**: add a pending trusted publisher for project `model-finder-mcp` (owner `Abhiindigloo`, repository `EvalHarness`, workflow `release.yml`, environment `pypi`), ideally from the Indigloo PyPI organization, and create the `pypi` environment in the repository settings.
191
+ - **MCP Registry** (`co.indigloo/model-finder`, verified through the indigloo.co domain). On your own machine, with OpenSSL 3:
192
+ ```bash
193
+ openssl genpkey -algorithm Ed25519 -out mcp-registry-key.pem
194
+ echo "TXT record for indigloo.co: v=MCPv1; k=ed25519; p=$(openssl pkey -in mcp-registry-key.pem -pubout -outform DER | tail -c 32 | base64)"
195
+ echo "GitHub secret MCP_REGISTRY_PRIVATE_KEY: $(openssl pkey -in mcp-registry-key.pem -noout -text | grep -A3 'priv:' | tail -n +2 | tr -d ' :\n')"
196
+ ```
197
+ Add the TXT record at the apex of indigloo.co, create a repository environment `mcp-registry`, store the hex key as its secret `MCP_REGISTRY_PRIVATE_KEY`, then delete `mcp-registry-key.pem` or keep it in a password manager.
198
+
199
+ <details>
200
+ <summary><b>Repository layout</b></summary>
201
+
202
+ ```
203
+ skills/ shared Agent Skills (single source of truth)
204
+ mcp/server.py local MCP server (stdio, standard library only)
205
+ .mcp.json MCP launch config for Claude Code and Cursor (${CLAUDE_PLUGIN_ROOT}); disabled as a
206
+ project config inside this repo by .claude/settings.json
207
+ mcp.json Agent Plugins MCP launch config (Codex, Copilot CLI, Cursor): runs ./mcp/server.py
208
+ server.json, pyproject.toml MCP Registry entry and PyPI package (model-finder-mcp); pypi/ holds the package marker
209
+ glama.json Glama directory ownership
210
+ .github/workflows/ tests on every push; release.yml publishes tags to PyPI and the MCP Registry
211
+ .claude-plugin/ Claude Code (and Copilot CLI) plugin + marketplace manifests
212
+ .codex-plugin/ Codex plugin manifest
213
+ .agents/plugins/ Codex repository marketplace
214
+ .cursor-plugin/ Cursor plugin + marketplace manifests
215
+ gemini-extension.json Gemini CLI extension (context: GEMINI.md)
216
+ plugin.json Agent Plugins manifest with OpenAI listing metadata
217
+ AGENTS.md, GEMINI.md skill index for agents that read root instructions
218
+ PRIVACY.md, TERMS.md, SUPPORT.md pages the marketplace listings link to
219
+ assets/ logo, README plates, and DESIGN.md (the visual language)
220
+ ```
221
+
222
+ `skills/eval-models/scripts/mf_core.py` is duplicated in `skills/route-models/scripts/` so each skill works on its own. The test suite fails if the copies differ.
223
+ </details>
224
+
225
+ ---
226
+
227
+ <p align="center">
228
+ <sub>
229
+ <a href="SUPPORT.md">Support</a> · <a href="PRIVACY.md">Privacy</a> · <a href="TERMS.md">Terms</a> · <a href="SECURITY.md">Security</a> · <a href="DATA-PROTECTION.md">Data protection</a><br>
230
+ MIT License · © 2026 Indigloo Softwares Private Limited
231
+ </sub>
232
+ </p>
@@ -0,0 +1,23 @@
1
+ # Evaluations
2
+
3
+ Ten questions that test whether an AI agent can answer realistic questions using **only** the Model Finder MCP
4
+ tools, following the MCP builder evaluation method: read-only, independent, single verifiable answers that do
5
+ not change.
6
+
7
+ - `fixture-repo/`: a small helpdesk codebase with models in several services, routes through Bedrock, Vertex AI
8
+ and Groq, an environment-variable default, legacy models, prompt files, and eval fixtures containing **fake**
9
+ personal data and a documentation example key. It is the workspace for every question.
10
+ - `model_finder_eval.xml`: the questions and verified answers.
11
+ - `run_with_claude_code.py`: runs every question through headless Claude Code with the plugin loaded and built-in
12
+ file, shell and web tools denied, then prints the score.
13
+
14
+ ```bash
15
+ python3 evaluations/run_with_claude_code.py
16
+ ```
17
+
18
+ ## Latest result
19
+
20
+ 10 of 10 correct (Claude Code 2.1.301, 17 October 2026; also 10 of 10 on 2.1.299). Each question took one or two MCP tool calls.
21
+
22
+ If you change the fixture, recompute the answers with the MCP tools before running, and update this file.
23
+ The `.gitignore` excludes `.env` files, so the fixture uses `credentials.json` (kept by a `.gitignore` exception) to exercise secret-file skipping.
@@ -0,0 +1 @@
1
+ # Fixture repository for Model Finder evaluations. All personal data and keys are fake.