Skip to content

Commit 5bb167a

Browse files
author
Yen Kha
committed
refactor(mcp): rename tools to user-oriented names; remove scorer identity
MCP tool rename (validate_* is implementation-oriented, not user-oriented): validate_corpus_record -> check_case validate_prompt_jsonl -> check_prompt generate_prompt_template -> new_prompt create_contribution_bundle -> bundle_prompts Consistent verb/object structure, low cognitive load, better autocomplete, easier to demo. Updated server.py, corpus_tools.py, prompt_tools.py, dali_mcp/README.md, and CONTRIBUTING.md references. Scorer identity removed: scoring/support.py: SCORER_MODEL hardcoded constant removed. Scorer is now read from DALI_SCORER_MODEL env var at runtime with a clear error if unset. No specific vendor is named or defaulted. METHODOLOGY.md: Step 4 and Scorer Bias Disclosure rewritten to be provider-neutral. Cross-vendor requirement stated as policy; specific scorer identity lives in run artifacts only. Em dashes removed from all newly written dali_mcp content.
1 parent b169a3a commit 5bb167a

8 files changed

Lines changed: 108 additions & 95 deletions

File tree

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Validate your record before submitting:
8181
python -m corpus.validator data/public/citation_failure_cases.json
8282
```
8383

84-
Optional: the `dali_mcp/` contributor interface exposes the same validation as an MCP tool (`validate_corpus_record`) for editor-integrated workflows.
84+
Optional: the `dali_mcp/` contributor interface exposes the same validation as an MCP tool (`check_case`) for editor-integrated workflows.
8585

8686
Records with `needs_verification: true` load for inspection but are excluded
8787
from scoring aggregates.
@@ -111,7 +111,7 @@ synthetic/
111111
Each record requires `id` (lowercase alphanumeric + underscore), `category`,
112112
`subcategory`, `prompt` (≥ 30 chars), and `difficulty`.
113113

114-
**Easiest path:** use the `generate_prompt_template` and `create_contribution_bundle`
114+
**Easiest path:** use the `new_prompt` and `bundle_prompts`
115115
MCP tools to scaffold, validate, and package prompts. See
116116
[dali_mcp/README.md](dali_mcp/README.md) for setup.
117117

METHODOLOGY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ The longer-term mitigation for 403 blocking is content-addressable archival (Way
178178

179179
## Step 4: Support Scoring
180180

181-
**Model:** `claude-3-5-haiku-20241022` (Anthropic) — cross-vendor scorer for all OpenAI subject models; no self-evaluation bias for GPT-4o/GPT-4.1/GPT-4o-mini results
181+
**Model:** LLM-based verification scorer, configurable via `DALI_SCORER_MODEL`. Use a cross-vendor model (different provider than your subject models) to avoid self-evaluation bias. The scorer model used in each run is recorded in `methodology.json`.
182182
**Parameters:** `temperature=0.0`, `max_tokens=256`
183183
**Source input:** first 3,000 characters of the fetched source text
184184

@@ -252,7 +252,7 @@ If a provider deprecates a model version, a new versioned results directory is c
252252

253253
## Scorer Bias Disclosure
254254

255-
The support scorer for v0.2 is `claude-3-5-haiku-20241022` (Anthropic). All v0.2 subject models are OpenAI (GPT-4o-mini, GPT-4.1, GPT-4o), so there is no self-evaluation bias in this run. The scorer model is recorded in `methodology.json` per run. If an Anthropic model is used as a subject in a future run, the scorer must be switched to a different provider.
255+
The scorer model is recorded in `methodology.json` per run. For any published run, the scorer must be from a different provider than the subject models being evaluated. This cross-vendor requirement is the primary guard against self-evaluation bias. The v0.2 public run satisfies this requirement; the specific scorer identity is recorded in the run artifacts rather than in this document to keep the methodology provider-neutral.
256256

257257
---
258258

dali_mcp/README.md

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
# Dali MCP Contributor Tools
1+
# Dali MCP Contributor Tools
22

33
Dali exposes four MCP tools so you can validate, scaffold, and bundle
44
corpus records and synthetic prompts directly from Claude or any
5-
MCP-capable editor without running terminal commands.
5+
MCP-capable editor, without running terminal commands.
66

77
## Tools
88

9-
| Tool | What it does |
9+
| Tool | Purpose |
1010
|---|---|
11-
| `validate_corpus_record` | Validates a CitationFailureCase JSON object — checks required fields, taxonomy values, lineage rules, and scoring eligibility |
12-
| `validate_prompt_jsonl` | Validates a single synthetic prompt JSONL entry — checks required fields, category/subcategory/difficulty taxonomy, and prompt length |
13-
| `generate_prompt_template` | Scaffolds a new prompt template for a given category, subcategory, and difficulty — ready to fill in and paste |
14-
| `create_contribution_bundle` | Validates a batch of prompts and returns a PR-ready checklist |
11+
| `check_case` | Validate a canonical citation-failure case |
12+
| `check_prompt` | Validate a synthetic benchmark prompt |
13+
| `new_prompt` | Generate a prompt scaffold |
14+
| `bundle_prompts` | Create a PR-ready contribution bundle |
1515

16-
These tools wrap the same validation logic used by the CLI (`corpus/validator.py`, `runners/`) so there are no discrepancies between editor and terminal validation.
16+
These tools wrap the same validation logic used by the CLI
17+
(`corpus/validator.py`, `runners/`) so there are no discrepancies
18+
between editor and terminal validation.
1719

1820
---
1921

@@ -25,7 +27,9 @@ These tools wrap the same validation logic used by the CLI (`corpus/validator.py
2527
pip install mcp
2628
```
2729

28-
The `mcp` package is listed under `# MCP server` in `requirements.txt`. The rest of Dali (Tier 1 evaluator) runs on stdlib only — `mcp` is only required if you want the editor integration.
30+
The `mcp` package is listed under the MCP server section in
31+
`requirements.txt`. The rest of Dali (Tier 1 evaluator) runs on
32+
stdlib only. `mcp` is only required for the editor integration.
2933

3034
### Claude Desktop
3135

@@ -43,9 +47,9 @@ Add to your Claude Desktop `claude_desktop_config.json`:
4347
}
4448
```
4549

46-
Replace `/path/to/your/Dali/clone` with the absolute path to your local repo.
47-
48-
Restart Claude Desktop. The four tools will appear in Claude's tool list.
50+
Replace `/path/to/your/Dali/clone` with the absolute path to your
51+
local repo. Restart Claude Desktop. The four tools will appear in
52+
the tool list.
4953

5054
### VS Code (with MCP extension)
5155

@@ -86,37 +90,38 @@ Add to your Cursor MCP settings:
8690

8791
### Validate a corpus record
8892

89-
Ask Claude:
90-
> "Use validate_corpus_record to check this record: `{ "case_id": "my-case-2024", "year": 2024, ... }`"
93+
Ask your editor assistant:
94+
> "Use check_case to validate this record: { "case_id": "my-case-2024", "year": 2024, ... }"
9195
92-
The tool returns a report with `valid`, `scoring_eligible`, `issues`, and a one-line `summary`.
96+
The tool returns `valid`, `scoring_eligible`, `issues`, and a one-line `summary`.
9397

9498
### Scaffold a new adversarial prompt
9599

96-
Ask Claude:
97-
> "Use generate_prompt_template for category=adversarial, subcategory=hallucination_prone, difficulty=adversarial, notes=Tests fabrication under recent AI regulation prompts"
100+
Ask your editor assistant:
101+
> "Use new_prompt for category=adversarial, subcategory=hallucination_prone, difficulty=adversarial, notes=Tests fabrication under recent AI regulation prompts"
98102
99-
The tool returns a ready-to-fill JSONL entry and tells you which file to add it to.
103+
The tool returns a ready-to-fill entry and tells you which file to add it to.
100104

101105
### Bundle prompts for a PR
102106

103-
Ask Claude:
104-
> "Use create_contribution_bundle on this list of prompts: [...]"
107+
Ask your editor assistant:
108+
> "Use bundle_prompts on this list: [...]"
105109
106-
Returns pass/fail by prompt ID and a PR checklist.
110+
Returns pass/fail by prompt ID and a pre-PR checklist.
107111

108112
---
109113

110114
## CLI equivalent
111115

112-
All tools have direct CLI equivalents if you prefer the terminal:
116+
All tools have direct CLI equivalents for terminal users:
113117

114118
```bash
115119
# Validate corpus
116120
python -m corpus.validator data/public/citation_failure_cases.json
117121

118-
# Validate synthetic prompts (schema validation via CI)
119-
python -m pytest tests/ -q
122+
# Validate synthetic prompts (via CI schema check)
123+
pytest tests/ -q
120124
```
121125

122-
The MCP server is an editor-friendly wrapper — not a separate code path.
126+
The MCP server is an editor-friendly wrapper around the same logic,
127+
not a separate code path.

dali_mcp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
Exposes four tools via the Model Context Protocol so contributors can
44
validate, scaffold, and bundle corpus records and synthetic prompts
5-
directly from Claude or any MCP-capable editor without running
5+
directly from Claude or any MCP-capable editor, without running
66
terminal commands.
77
88
Usage:

dali_mcp/server.py

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#!/usr/bin/env python3
2-
"""Dali MCP server contributor tools over the Model Context Protocol.
2+
"""Dali MCP server: contributor tools over the Model Context Protocol.
33
44
Start the server:
55
python -m dali_mcp
66
77
Or via uvx (no install required):
88
uvx --from . dali-mcp
99
10-
Tools exposed:
11-
validate_corpus_record — validate a CitationFailureCase JSON object
12-
validate_prompt_jsonl — validate a synthetic prompt JSONL entry
13-
generate_prompt_template — scaffold a new synthetic prompt
14-
create_contribution_bundle — validate + summarise a batch for PR submission
10+
Tools:
11+
check_case Validate a canonical citation-failure case record
12+
check_prompt Validate a synthetic benchmark prompt entry
13+
new_prompt Generate a scaffolded prompt template
14+
bundle_prompts Validate a batch and return a PR-ready checklist
1515
"""
1616

1717
from __future__ import annotations
@@ -20,18 +20,15 @@
2020
import sys
2121
from pathlib import Path
2222

23-
# Allow running from repo root without installing the package.
2423
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
2524

2625
from mcp.server.fastmcp import FastMCP
2726

28-
from dali_mcp.tools.corpus_tools import (
29-
_validate_corpus_record_impl,
30-
)
27+
from dali_mcp.tools.corpus_tools import _check_case_impl
3128
from dali_mcp.tools.prompt_tools import (
32-
_create_contribution_bundle_impl,
33-
_generate_prompt_template_impl,
34-
_validate_prompt_jsonl_impl,
29+
_bundle_prompts_impl,
30+
_check_prompt_impl,
31+
_new_prompt_impl,
3532
)
3633

3734
mcp = FastMCP(
@@ -40,67 +37,67 @@
4037
"You are a Dali contributor assistant. Use these tools to validate "
4138
"corpus records and synthetic prompts, scaffold new entries, and "
4239
"bundle contributions for pull-request submission. "
43-
"Always run validate_corpus_record or validate_prompt_jsonl before "
44-
"creating a bundle."
40+
"Run check_case or check_prompt before calling bundle_prompts."
4541
),
4642
)
4743

4844

4945
@mcp.tool()
50-
def validate_corpus_record(record_json: str) -> str:
51-
"""Validate a CitationFailureCase corpus record.
46+
def check_case(record_json: str) -> str:
47+
"""Validate a canonical citation-failure case for the Tier 1 corpus.
5248
53-
Accepts a JSON object (as a string) representing one record from
49+
Accepts a JSON object representing one record from
5450
data/public/citation_failure_cases.json. Returns a validation report
55-
indicating whether the record is scoring-eligible, what required fields
51+
showing whether the record is scoring-eligible, which required fields
5652
are missing, and any taxonomy or lineage violations.
5753
5854
Args:
5955
record_json: JSON string of a single CitationFailureCase record.
6056
Must include at minimum: case_id, incident_name, year, jurisdiction.
6157
6258
Returns:
63-
A JSON string with keys:
64-
valid (bool) passes all scoring gates
65-
scoring_eligible (bool) can count toward published metrics
66-
issues (list[str]) — list of validation failures, empty if valid
67-
summary (str) — human-readable one-line status
59+
JSON string with keys:
60+
valid (bool) - passes all scoring gates
61+
scoring_eligible (bool) - can count toward published metrics
62+
issues (list[str]) - validation failures, empty if valid
63+
summary (str) - one-line status
6864
"""
69-
return json.dumps(_validate_corpus_record_impl(record_json), indent=2)
65+
return json.dumps(_check_case_impl(record_json), indent=2)
7066

7167

7268
@mcp.tool()
73-
def validate_prompt_jsonl(prompt_json: str) -> str:
74-
"""Validate a synthetic prompt JSONL entry for the Tier 2 corpus.
69+
def check_prompt(prompt_json: str) -> str:
70+
"""Validate a synthetic prompt entry for the Tier 2 corpus.
7571
76-
Accepts a single JSONL record (as a JSON string). Checks required fields,
77-
taxonomy values, and prompt quality rules.
72+
Accepts a single prompt record as a JSON string. Checks required
73+
fields, taxonomy values, and prompt quality rules.
7874
7975
Args:
8076
prompt_json: JSON string of one synthetic prompt record.
8177
Required fields: id, category, subcategory, prompt, difficulty.
8278
8379
Returns:
84-
A JSON string with keys:
80+
JSON string with keys:
8581
valid (bool)
8682
issues (list[str])
8783
summary (str)
84+
destination_file (str) - which synthetic/ file to add this to
8885
"""
89-
return json.dumps(_validate_prompt_jsonl_impl(prompt_json), indent=2)
86+
return json.dumps(_check_prompt_impl(prompt_json), indent=2)
9087

9188

9289
@mcp.tool()
93-
def generate_prompt_template(
90+
def new_prompt(
9491
category: str,
9592
subcategory: str,
9693
difficulty: str,
9794
notes: str = "",
9895
) -> str:
9996
"""Generate a scaffolded synthetic prompt template.
10097
101-
Returns a ready-to-fill JSONL record with the correct field structure
102-
for the given category, subcategory, and difficulty. Includes a unique
103-
ID stub based on the subcategory and valid taxonomy values.
98+
Returns a ready-to-fill record with the correct field structure
99+
for the given category, subcategory, and difficulty level. Includes
100+
a unique ID stub and tells you which file to add it to.
104101
105102
Args:
106103
category: One of: legal, research, adversarial
@@ -109,38 +106,37 @@ def generate_prompt_template(
109106
policy_citations, hallucination_prone
110107
difficulty: One of: known_case, obscure_case, fabricated_likely,
111108
ambiguous, adversarial, standard
112-
notes: Optional guidance note for what the prompt should test.
113-
Appears in the 'notes' field of the template.
109+
notes: Optional note describing what failure mode the prompt tests.
114110
115111
Returns:
116-
A JSONL-formatted JSON string ready to paste into the appropriate
117-
synthetic/ file. The 'prompt' field contains a placeholder to replace.
112+
A comment header with the destination file followed by a JSON
113+
record ready to paste. Replace the placeholder prompt text before
114+
submitting.
118115
"""
119-
return _generate_prompt_template_impl(category, subcategory, difficulty, notes)
116+
return _new_prompt_impl(category, subcategory, difficulty, notes)
120117

121118

122119
@mcp.tool()
123-
def create_contribution_bundle(prompts_json: str) -> str:
124-
"""Validate and summarise a batch of synthetic prompts for PR submission.
120+
def bundle_prompts(prompts_json: str) -> str:
121+
"""Validate a batch of synthetic prompts and return a PR-ready checklist.
125122
126-
Accepts a JSON array of prompt records (each matching the synthetic
127-
prompt schema). Validates every record, summarises pass/fail counts
128-
by subcategory, and returns a checklist of issues to fix before
129-
opening a pull request.
123+
Accepts a JSON array of prompt records. Validates every record,
124+
summarises pass/fail counts, and returns a checklist of issues to
125+
fix before opening a pull request.
130126
131127
Args:
132128
prompts_json: JSON array string of synthetic prompt records.
133129
134130
Returns:
135-
A JSON string with keys:
136-
total (int) — total records in the batch
137-
valid (int) records that pass all checks
138-
invalid (int) records with issues
139-
issues_by_id (dict) {id: [issues]} for each failing record
140-
pr_checklist (list[str]) pre-PR checklist items
141-
ready_to_submit (bool) True if all records are valid
131+
JSON string with keys:
132+
total (int) - records in the batch
133+
valid (int) - records passing all checks
134+
invalid (int) - records with issues
135+
issues_by_id (dict) - {id: [issues]} for each failing record
136+
pr_checklist (list[str]) - pre-PR checklist items
137+
ready_to_submit (bool) - True when all records are valid
142138
"""
143-
return json.dumps(_create_contribution_bundle_impl(prompts_json), indent=2)
139+
return json.dumps(_bundle_prompts_impl(prompts_json), indent=2)
144140

145141

146142
def main() -> None:

dali_mcp/tools/corpus_tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
}
5959

6060

61-
def _validate_corpus_record_impl(record_json: str) -> dict:
61+
def _check_case_impl(record_json: str) -> dict:
6262
issues: list[str] = []
6363

6464
try:
@@ -68,7 +68,7 @@ def _validate_corpus_record_impl(record_json: str) -> dict:
6868
"valid": False,
6969
"scoring_eligible": False,
7070
"issues": [f"Invalid JSON: {e}"],
71-
"summary": "Parse error record is not valid JSON.",
71+
"summary": "Parse error: record is not valid JSON.",
7272
}
7373

7474
if not isinstance(record, dict):

0 commit comments

Comments
 (0)