Evalsmith Mcp

io.github.diegoperezg7由 GitHub 账号 diegoperezg7 发布v0.1.0更新于 Oct 29, 2026

Evaluate RAG retrieval, agent tool calls and prompt regressions with deterministic metrics.

概览

AI 生成的概览

本地 MCP 服务器,用确定性指标评估 RAG 检索、智能体工具调用和提示词回归,并生成报告。

可以做什么
  • 按 qrels 评估检索结果:各截断点的 recall、precision、nDCG、命中率与 MRR
  • 用带种子的配对自助法置信区间对两到三个配置排序,并给出差异是否显著的结论
  • 将智能体轨迹与期望的工具调用比对,支持严格或宽松顺序及参数匹配器
  • 在黄金集上检测基线输出与候选输出之间的提示词回归
  • 将结果渲染为 Markdown、JSON 或 JUnit 报告,并运行工作区内的 evalsmith.yaml 套件
  • 提供内置的合成示例数据集和引导提示词,用于比较配置、审查轨迹和评审提示词改动
适用场景
适合在调整检索器、提示词或智能体时使用:让助手在对话中或合并前量化某次改动是否有效、领先是否在统计上真实,以及工具调用与黄金集输出是否仍然成立。
运行要求
通过 npx 或全局 npm 安装以 stdio 在本地运行(需要 Node.js)。可选的 LLM 评审需要 OpenAI 兼容端点,由 EVALSMITH_JUDGE_BASE_URL 和 EVALSMITH_JUDGE_MODEL 指定;托管端点还需 EVALSMITH_JUDGE_API_KEY。EVALSMITH_ROOT 限定 run_suite 可读取的目录,LOG_LEVEL 控制日志级别。
安装前请注意
评审默认关闭;启用后会把两份输出发送到外部 chat-completions 端点,每个用例产生两次请求,相关工具也不再幂等。EVALSMITH_JUDGE_API_KEY 是托管端点用的密钥。run_suite 会读取 EVALSMITH_ROOT 下的文件,应指向范围较窄的目录。其余工具为只读,不会修改你的数据。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Evalsmith Mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

[evalsmith logo]

evalsmith-mcp

Evaluate RAG retrieval and AI agents with deterministic metrics, from any MCP client or from CI.

[Node] [TypeScript] [MCP SDK] [CI] [Paid API keys] [npm] [License: MIT] [M8ven Score] [Glama score] [Evalsmith MCP server]

evalsmith answers four questions that come up every time a retriever, prompt or agent changes:

  1. Is retrieval good enough? recall@k, precision@k, nDCG@k, hit rate and MRR from qrels and a ranked run.
  2. Which configuration is better, and is the gap real? 2-3 configurations ranked with seeded paired-bootstrap confidence intervals.
  3. Did the agent call the right tools? Trace vs. expected calls, strict or lax order, argument matchers.
  4. Did the prompt change break anything? Golden-set checks on baseline vs. candidate outputs.

Everything is deterministic and runs offline. An LLM judge exists for a second opinion, but it is off by default and never decides the verdict. Results come out as a terminal table, Markdown, JSON, JUnit XML or a self-contained HTML report, and the GitHub Action turns them into a merge gate.

[evalsmith run: retrieval metrics, config comparison, tool-call check, prompt regression and a failing CI gate]


Interfaces over the same core

mermaid
flowchart LR    subgraph Clients        A[MCP client<br/>desktop app, IDE, agent]        B[Remote MCP client<br/>or service]        C[Terminal / CI job]        D[GitHub workflow]    end    subgraph evalsmith        S1[MCP server<br/>stdio]        S2[MCP server<br/>Streamable HTTP, stateless]        S3[CLI<br/>evalsmith run]        S4[GitHub Action<br/>uses: evalsmith-mcp@v0]        CORE[(src/core<br/>metrics, bootstrap, matchers,<br/>checks, gates, reports)]    end    A --> S1 --> CORE    B --> S2 --> CORE    C --> S3 --> CORE    D --> S4 --> CORE    S3 -. exit code + JUnit + HTML .-> C    S4 -. outputs + job summary .-> D
InterfaceEntry pointWho uses itWhy it exists
MCP over stdiodist/mcp/server.jsDesktop MCP clients, IDE assistants, local agentsAn assistant can score a run, compare configs or audit a trace mid-conversation, with typed structuredContent back.
MCP over Streamable HTTPEVALSMITH_TRANSPORT=httpRemote clients, internal platforms, the MCP InspectorSame tools over the network. Stateless: no sessions to store, scales horizontally.
CLI / CIevalsmith run evalsmith.yamlPipelines and terminals--fail-under recall@5=0.8 turns a metric into a merge gate. Exit codes, Markdown summary, JUnit XML, HTML report.
GitHub Actionuses: diegoperezg7/evalsmith-mcp@v0GitHub workflowsThe same gates as a step, with outputs, a job summary and no install.

All four call the same functions in src/core. The MCP tools are thin adapters: parse input with Zod, call the core, return structuredContent validated against an output schema.


MCP surface

mermaid
flowchart TB    subgraph Tools        T1[evaluate_retrieval]        T2[compare_configs]        T3[check_tool_calls]        T4[detect_prompt_regression]        T5[generate_report]        T6[run_suite]    end    subgraph Resources        R1["evalsmith://examples/{name}<br/>12 synthetic datasets + suite"]    end    subgraph Prompts        P1[compare_rag_configs]        P2[audit_agent_trace]        P3[review_prompt_change]    end    T1 -- structuredContent --> T5    T2 -- structuredContent --> T5    T3 -- structuredContent --> T5    T4 -- structuredContent --> T5    classDef tool fill:#ffedd5,stroke:#c2410c,color:#431407    classDef res fill:#e0f2fe,stroke:#0369a1,color:#082f49    classDef prom fill:#ede9fe,stroke:#6d28d9,color:#2e1065    class T1,T2,T3,T4,T5,T6 tool    class R1 res    class P1,P2,P3 prom

Tools

Every tool declares an input and an output Zod schema, returns structuredContent plus a JSON text block, and is annotated readOnly and non-destructive. Four tools are also idempotent and closed-world. detect_prompt_regression and run_suite are declared open-world and non-idempotent: annotations are per tool, and with the judge enabled they call an external model whose answers can vary. With the judge off (the default) they behave like the others.

ToolInputOutput
evaluate_retrievalqrels, run, optional k listMean recall/precision/nDCG/hit rate at every k, MRR, per-query values, skipped and missing queries
compare_configsqrels, 2-3 {name, run}, primary metric, bootstrap {samples, seed, confidence}Ranking with intervals, winner, runner-up, paired interval of the gap, significant
check_tool_callstrace as logged (evalsmith, Anthropic Messages, OpenAI Chat or Responses), expected, order: strict | laxpassed, score, matched position and reasons per expected call, unexpected calls
detect_prompt_regressiongolden, baseline, candidate, optional judge {enabled}Verdict, pass rates, regressions, improvements, per-case failures, judge votes when enabled
generate_reportAny of the results above, gates, format: markdown | json | junitpassed, rendered report
run_suiteOptional config path to an evalsmith.yaml, gates, judge, formatpassed, rendered report and every section's results, read from the suite's files

run_suite runs the same suites as evalsmith run, so a client can evaluate data that lives in files instead of pasting it into the conversation. It only reads inside the workspace root (EVALSMITH_ROOT, the directory the server started in by default), following symlinks before it checks, and runs the bundled example suite when no config is given.

Bad input (unknown metric, duplicate config names, qrels with no relevant documents) comes back as an InvalidParams tool error with a message the model can act on. A judge endpoint that is down or returns an HTTP error is an InternalError.

Resources

evalsmith://examples/{name} lists and serves the synthetic datasets in examples/datasets, so a client can try every tool before wiring in its own data:

NameContent
rag-corpus, rag-queries, rag-qrels20 help-center articles of a fictional invoicing app, 12 questions, graded judgements
rag-run-bm25, rag-run-hybrid, rag-run-hybrid-rerankTop-10 rankings from three retrieval configurations
agent-trace, agent-expectedA support agent refunding a duplicate charge, and the calls it should make
prompts-golden, prompts-baseline, prompts-candidate, prompts-candidate-regressedSix golden cases and three sets of outputs
suiteThe example evalsmith.yaml

Prompts

PromptArgumentWhat it asks the model to do
compare_rag_configsmetricCompare the configurations, report the gap with its interval and the weakest queries
audit_agent_traceorderCheck the trace and propose the smallest fix for each failed step
review_prompt_changecandidateDetect regressions, build a Markdown report, decide ship / do not ship

A conversation with an MCP client

mermaid
sequenceDiagram    autonumber    actor User    participant Host as MCP client (LLM host)    participant ES as evalsmith (stdio)    participant Core as src/core
    User->>Host: "Is the reranker worth it on our help-center set?"    Host->>ES: initialize, tools/list, resources/list    ES-->>Host: 6 tools + JSON Schemas, 13 resources    Host->>ES: resources/read evalsmith://examples/rag-qrels (+ 3 runs)    ES-->>Host: qrels and runs as JSON    Host->>ES: tools/call compare_configs {metric: "ndcg@5", configs: [...]}    ES->>Core: compareConfigs(qrels, configs, "ndcg@5", {seed: 42})    Core-->>ES: ranking, intervals, paired delta    ES-->>Host: structuredContent {winner: "hybrid+rerank", significant: true, ...}    Host->>ES: tools/call generate_report {format: "markdown", comparison}    ES-->>Host: Markdown report    Host-->>User: "Yes: +0.153 nDCG@5 over hybrid, 95% CI [0.069, 0.251]."

Metrics

For a query $q$ with relevant set $R_q$ (documents with grade $> 0$) and ranking $D_q$, with $D_q^{k}$ its first $k$ documents:

math
\mathrm{Recall@}k = \frac{|R_q \cap D_q^{k}|}{|R_q|}\qquad\mathrm{Precision@}k = \frac{|R_q \cap D_q^{k}|}{k}\qquad\mathrm{HitRate@}k = \mathbb{1}\left[\,R_q \cap D_q^{k} \neq \varnothing\,\right]
math
\mathrm{RR}_q = \frac{1}{\text{rank of the first relevant document}}\qquad\mathrm{MRR} = \frac{1}{|Q|}\sum_{q \in Q} \mathrm{RR}_q
math
\mathrm{DCG@}k = \sum_{i=1}^{k} \frac{\mathrm{rel}_i}{\log_2(i+1)}\qquad\mathrm{nDCG@}k = \frac{\mathrm{DCG@}k}{\mathrm{IDCG@}k}

$\mathrm{rel}_i$ is the graded judgement of the document at rank $i$ (linear gain, as in trec_eval), and IDCG is the DCG of the judgements sorted in descending order. Reported values are means over judged queries.

Conventions, all covered by tests:

  • Queries whose judgements are all 0 are skipped and listed in skippedQueries.
  • Judged queries missing from the run score 0 and are listed in missingFromRun.
  • Precision divides by $k$, not by the ranking length.
  • Repeated document ids in a ranking keep only their first position, as in trec_eval, so a run cannot score above 1 by repeating a relevant document.
  • Cut-offs start at 1: recall@0 is rejected.

Worked example (tests/core/retrieval.test.ts): judgements a=2, b=1, c=0, ranking d, a, e, b, c. DCG@5 $= 2/\log_2 3 + 1/\log_2 5 = 1.69254$, IDCG@5 $= 2/\log_2 2 + 1/\log_2 3 = 2.63093$, so nDCG@5 $= 0.64332$; recall@3 $= 0.5$, precision@5 $= 0.4$, RR $= 0.5$.

Bootstrap. compare_configs resamples queries with replacement, using the same indices for every configuration (paired), samples times, from a seeded PRNG (mulberry32). Intervals are percentiles of the resampled means. The lead is significant when the interval of winner minus runner-up excludes zero. The same seed gives the same intervals on every machine.

Tool-call matchers

json
{  "tool": "create_refund",  "args": {    "invoice_id": { "type": "exact", "value": "INV-2041" },    "reason": { "type": "any" },    "metadata": { "type": "subset", "value": { "ticket": "T-5532" } },    "to": { "type": "regex", "pattern": "@acme-robotics\\.example$" }  }}

strict requires the trace to be exactly the expected calls in order; calls past the expected sequence fail the check and appear as failed test cases in JUnit. lax ignores order and pairs expected calls with trace calls by maximum bipartite matching (augmenting paths), so a loose matcher never steals the only call a stricter one accepts. Extra calls are reported without failing. Every matcher, exact included, fails when the argument is missing.

Prompt checks

exact (trimmed by default), regex, contains (case-insensitive by default), json_schema (the output is parsed and validated with Ajv) and length (min / max characters). A regression is a case that passes on the baseline and fails on the candidate. Missing outputs count as failures.

The optional judge sends both outputs to any OpenAI-compatible /chat/completions endpoint, Ollama included, at temperature 0. To cancel position bias each case is judged twice, with baseline as answer A and then as answer B. A side wins only when both orderings agree; a disagreement counts as a tie. That costs two requests per case. Its votes are reported next to the verdict.


Quickstart

bash
npx -y evalsmith-mcp                       # MCP server on stdionpm install -g evalsmith-mcp               # or install the `evalsmith` CLI and `evalsmith-mcp` serverdocker build -t evalsmith-mcp . && docker run --rm -i evalsmith-mcp   # or run the server in a container

To run the bundled examples and the tests from source:

bash
git clone https://github.com/diegoperezg7/evalsmith-mcp.gitcd evalsmith-mcpnpm ci            # also builds dist/ through the prepare scriptnpx playwright install chromium   # the HTML report tests open it in a real browsernpm test          # metrics, traces, MCP in-memory + HTTP, CLI exit codes, HTML report, action
node dist/cli/index.js run examples/evalsmith.yaml

Connect an MCP client (stdio)

[Install in Cursor] [Install in VS Code]

From a terminal:

bash
claude mcp add evalsmith -- npx -y evalsmith-mcp     # Claude Codecodex mcp add evalsmith -- npx -y evalsmith-mcp      # Codex CLIcode --add-mcp '{"name":"evalsmith","command":"npx","args":["-y","evalsmith-mcp"]}'   # VS Code

Other desktop MCP clients read an mcpServers block like this (examples/mcp-client-config.json):

json
{  "mcpServers": {    "evalsmith": {      "command": "npx",      "args": ["-y", "evalsmith-mcp"],      "env": { "LOG_LEVEL": "warn" }    }  }}

Restart the client, then try the compare_rag_configs prompt or ask it to read evalsmith://examples/agent-trace and check it.

Streamable HTTP

bash
EVALSMITH_TRANSPORT=http EVALSMITH_HTTP_PORT=3333 node dist/mcp/server.jscurl -s localhost:3333/healthz                  # {"status":"ok","version":"0.1.0"}npx @modelcontextprotocol/inspector             # connect to http://127.0.0.1:3333/mcp
VariableDefaultPurpose
EVALSMITH_TRANSPORTstdiostdio or http
EVALSMITH_HTTP_HOST / EVALSMITH_HTTP_PORT127.0.0.1 / 3333HTTP bind address
EVALSMITH_JUDGE_BASE_URLhttp://localhost:11434/v1OpenAI-compatible endpoint for the optional judge
EVALSMITH_JUDGE_MODELllama3.1:8bJudge model
EVALSMITH_JUDGE_API_KEYunsetOnly for hosted endpoints
EVALSMITH_ROOTcurrent directoryDirectory run_suite may read suites and data from
LOG_LEVELinfopino level; logs always go to stderr

CLI and CI

bash
evalsmith run <config> [--fail-under metric=value ...] [--format table|json|markdown|html]                       [--report file.{md,json,xml,html}] [--report-format markdown|json|junit|html]evalsmith doctor [config] [--judge]

Gates accept recall@k, precision@k, ndcg@k, hit_rate@k, mrr, tool_calls (score of check_tool_calls) and prompt_pass_rate. Gates in the YAML file apply too; a command-line gate with the same name overrides it. A prompt regression or a failed tool-call check fails the run even without gates.

Exit codeMeaning
0Every gate passed, no regression
1A gate is below its threshold, the candidate regressed, or the tool calls do not match
2Usage error, invalid config, unknown metric, unreadable dataset, judge endpoint down

Real output

node dist/cli/index.js run examples/evalsmith.yaml on the bundled datasets (examples/evalsmith.yaml):

text
evalsmith · ledgerly-support-assistant
Retrieval (12 queries, MRR 0.8403)┌────┬────────┬───────────┬────────┬──────────┐│  k │ recall │ precision │   nDCG │ hit rate │├────┼────────┼───────────┼────────┼──────────┤│  1 │ 0.4583 │    0.7500 │ 0.6667 │   0.7500 ││  3 │ 0.7500 │    0.4167 │ 0.7442 │   0.9167 ││  5 │ 0.9167 │    0.3000 │ 0.8059 │   1.0000 ││ 10 │ 1.0000 │    0.1667 │ 0.8285 │   1.0000 │└────┴────────┴───────────┴────────┴──────────┘
Comparison on ndcg@5 (paired bootstrap, 2000 samples, seed 42)┌───┬───────────────┬────────┬──────────────────┐│ # │ config        │ ndcg@5 │ 95% CI           │├───┼───────────────┼────────┼──────────────────┤│ 1 │ hybrid+rerank │ 0.9588 │ [0.8950, 1.0000] ││ 2 │ hybrid        │ 0.8059 │ [0.6875, 0.9141] ││ 3 │ bm25          │ 0.5596 │ [0.3782, 0.7354] │└───┴───────────────┴────────┴──────────────────┘hybrid+rerank wins on ndcg@5 (0.9588), +0.1528 over hybrid; 95% interval of the gap [0.0692, 0.2506] excludes zero.
Agent tool calls (strict)┌──────────────────┬─────────┬────────┬───────┐│ expected         │ matched │ status │ notes │├──────────────────┼─────────┼────────┼───────┤│ search_customers │ #1      │ pass   │       ││ get_invoice      │ #2      │ pass   │       ││ create_refund    │ #3      │ pass   │       ││ send_email       │ #4      │ pass   │       │└──────────────────┴─────────┴────────┴───────┘All 4 expected call(s) matched (strict order).
Prompt regression┌───────────────────────┬──────────┬───────────┬────────────────────┐│ case                  │ baseline │ candidate │ candidate failures │├───────────────────────┼──────────┼───────────┼────────────────────┤│ classify-intent       │ pass     │ pass      │                    ││ extract-invoice-id    │ pass     │ pass      │                    ││ refund-policy-summary │ fail     │ pass      │                    ││ due-date-format       │ pass     │ pass      │                    ││ refuse-card-number    │ pass     │ pass      │                    ││ refund-payload        │ pass     │ pass      │                    │└───────────────────────┴──────────┴───────────┴────────────────────┘No regressions across 6 case(s). Pass rate 83.3% -> 100.0%.
Gates┌────────────┬────────┬────────┬────────┐│ metric     │    min │ actual │ status │├────────────┼────────┼────────┼────────┤│ recall@5   │ 0.8000 │ 0.9167 │ pass   ││ ndcg@5     │ 0.7500 │ 0.8059 │ pass   ││ tool_calls │ 1.0000 │ 1.0000 │ pass   │└────────────┴────────┴────────┴────────┘
PASS

Raising the bar makes the same run fail the build:

text
$ node dist/cli/index.js run examples/evalsmith.yaml --fail-under recall@5=0.95 --fail-under mrr=0.9 --report report.xml...Gates┌────────────┬────────┬────────┬────────┐│ metric     │    min │ actual │ status │├────────────┼────────┼────────┼────────┤│ recall@5   │ 0.9500 │ 0.9167 │ FAIL   ││ ndcg@5     │ 0.7500 │ 0.8059 │ pass   ││ tool_calls │ 1.0000 │ 1.0000 │ pass   ││ mrr        │ 0.9000 │ 0.8403 │ FAIL   │└────────────┴────────┴────────┴────────┘
FAIL · 2 gate(s) below thresholdReport written to report.xml$ echo $?1

HTML report

--report report.html (or --format html on stdout) writes the whole run to one HTML file that opens offline and follows the system light or dark mode:

  • the verdict, and a card per gate with its value, threshold and status;
  • retrieval metrics per k as bars with a bootstrap interval over the queries, and gate thresholds marked on them;
  • the configuration comparison with each interval, the winner and the gap to the runner-up;
  • expected vs. actual tool calls, with the matched pairs linked and mismatches flagged;
  • baseline vs. candidate per golden case, with the failing checks one click away.

[evalsmith HTML report in light mode: FAIL verdict, gate cards and retrieval metrics per k with intervals]

Dark mode and an opened prompt regression

[The same report in dark mode]

[Prompt regression table with a regressed case opened, showing the check that fails on the candidate]

Dataset text (case ids, tool names, failure messages) is embedded as JSON in a non-executable <script type="application/json"> block and rendered with textContent only. A Content-Security-Policy allows no network access and only the page's own script, by hash. Tests open a report full of markup in Chromium and check that nothing from it runs. npm run docs:screenshots regenerates the pictures above.


GitHub Action

yaml
- uses: actions/checkout@v5- uses: diegoperezg7/evalsmith-mcp@v0  id: evals  with:    config: evals/evalsmith.yaml    fail-under: |      recall@5=0.8      ndcg@10=0.7      tool_calls=1    html-report: evalsmith-report.html

The step fails when a gate is below its threshold, the prompt candidate regresses or the tool calls do not match, and writes the Markdown report with the verdict to the job summary. It runs the same core as the CLI from a bundled node24 script, with no install step and no shell. examples/github-workflow.yml is a complete workflow that also keeps the HTML report as an artifact and publishes the JUnit XML as a check run.

InputDefaultDescription
configevalsmith.yamlSuite file. Dataset paths inside it are relative to the file
fail-underOne metric=value per line. Adds to the gates in the suite file and overrides those with the same name
report-fileReport file: .md, .json, .xml (JUnit) or .html
report-formatfrom extensionmarkdown, json, junit or html
html-reportPath for the self-contained HTML report
upload-summarytrueAppend the Markdown report to the job summary
OutputDescription
verdictpass or fail
failed-gatesGates below their threshold
metricsRetrieval metrics as JSON, e.g. fromJSON(steps.evals.outputs.metrics)['recall@5']
mrrMRR of the retrieval run
tool-callsTool-call score, matched / expected
prompt-pass-rateCandidate pass rate on the golden set
prompt-regressionsCases that pass on baseline and fail on candidate
winnerWinning configuration of the comparison
report-filePath of report-file, empty when not requested
html-reportPath of the HTML report, empty when not requested

Outputs of a section the suite does not have are empty. Dataset text printed to the log is wrapped in ::stop-commands::, so a case id or tool name cannot issue workflow commands. The judge reads EVALSMITH_JUDGE_* from the step environment, as the CLI does.

Without the action, the CLI does the same from any CI:

bash
npx evalsmith run evals/evalsmith.yaml --fail-under recall@5=0.8 --format markdown --report evalsmith-report.xml >> "$GITHUB_STEP_SUMMARY"

Suite file

yaml
name: ledgerly-support-assistantretrieval:  qrels: datasets/rag/qrels.json # { queryId: { docId: grade } }  run: datasets/rag/runs/hybrid.json # { queryId: [docId, ...] }  k: [1, 3, 5, 10]compare:  metric: ndcg@5  configs:    - { name: bm25, run: datasets/rag/runs/bm25.json }    - { name: hybrid, run: datasets/rag/runs/hybrid.json }    - { name: hybrid+rerank, run: datasets/rag/runs/hybrid-rerank.json }  bootstrap: { samples: 2000, seed: 42, confidence: 0.95 }agent:  trace: datasets/agent/trace.json  expected: datasets/agent/expected.json  order: strictprompts:  golden: datasets/prompts/golden.json  baseline: datasets/prompts/baseline.json  candidate: datasets/prompts/candidate.json  judge: { enabled: false }gates:  recall@5: 0.8  ndcg@5: 0.75  tool_calls: 1.0

Every section is optional. Paths are relative to the YAML file.


Pairs with ragcompass

ragcompass profiles a corpus and recommends how to configure the RAG pipeline: parser, chunking, top-k, hybrid search, reranking. evalsmith checks whether that configuration holds up:

mermaid
flowchart LR    A[Documents] --> B[ragcompass analyze<br/>recommended configs]    B --> C[Index 2-3 candidate configs]    C --> D[Run the eval queries<br/>save rankings]    D --> E[evalsmith compare_configs<br/>winner + intervals]    E --> F[evalsmith run in CI<br/>--fail-under gates]

Design decisions

  • Deterministic first. Metrics, matchers and checks are pure functions with hand-computed tests. A model is never needed to get a verdict, so results do not drift between runs and no paid API key is required.
  • Judge off by default. When enabled it goes through any OpenAI-compatible endpoint (local Ollama works), and its votes sit next to the verdict instead of changing it.
  • Intervals, not just means. Twelve queries can make a 0.03 lead look decisive. A paired bootstrap with a fixed seed makes the uncertainty visible and reproducible.
  • Stateless HTTP done properly. A stateless StreamableHTTPServerTransport cannot be reused across requests, so every POST gets its own server and transport. Registration is cheap, and a test makes two consecutive calls over real HTTP to prove it.
  • stdout belongs to the protocol. pino writes to stderr and ESLint forbids console in src/, so no stray byte breaks the stdio transport. The CLI keeps stdout for results only.
  • One schema, three uses. The Zod schemas in src/core/schemas.ts validate MCP input, generate the JSON Schemas clients see, and type the core.

Project layout

text
src/  core/         metrics, bootstrap, tool-call matchers, prompt checks, judge, gates, reports (incl. HTML), suite runner  mcp/          server (stdio + HTTP), tools/, resources/, prompts/  cli/          evalsmith run | doctor, table/json/markdown/html output  action/       GitHub Action entry point, bundled into dist/action  shared/       config (Zod), pino logger on stderr, MCP errorstests/  core/         hand-computed metrics, bootstrap, matchers, checks, reports, HTML in Chromium  mcp/          InMemoryTransport client and real Streamable HTTP client  cli/          exit codes 0 / 1 / 2, JUnit file, doctorexamples/  datasets/     synthetic RAG corpus + qrels + 3 runs, agent trace, golden prompts  evalsmith.yaml, github-workflow.yml, mcp-client-config.json
bash
npm run check     # typecheck + eslint + prettier + vitestnpm run inspect   # MCP Inspector against the built stdio server

Releases come from version tags: release.yml publishes to npm with provenance, to the MCP Registry and to GitHub Releases, and the action is published to the Marketplace from the release. docs/RELEASING.md has the steps, including the action bundle and the v0 tag. Changes are listed in CHANGELOG.md.

License

MIT

来源:README.md,提交 d130d5b

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.1.0最新Oct 29, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分