Skip to main content
Glama
borovkov-d

BuildWindow

by borovkov-d

BuildWindow

MCP 实验项目:一个智能体使用两个 MCP 服务器,根据真实天气预报规划施工作业。

这是 KSE AI Agentic School 的课程作业(一个 MCP 集成作业):为真实领域问题构建一个自定义 MCP 服务器,然后将其与现有的第三方 MCP 服务器一起连接到同一个智能体,让智能体同时使用两者来完成单个工具无法完成的事情。

概述

BuildWindow 是一个围绕具体调度问题构建的 MCP(模型上下文协议)实验项目:给定一份带有依赖关系的施工作业清单,以及某个城市的天气预报,生成一个同时满足两者的调度计划。负责规划的智能体同时持有两个独立的 MCP 连接。第一个是外部的、基于 Go 的 OpenWeather MCP 服务器(github.com/mschneider82/mcp-openweather),智能体每次运行调用一次,以获取所请求城市的实时当前天气状况和 5 天预报——这是整个项目中唯一发生网络调用的地方。第二个是本仓库自己的 BuildWindow MCP 服务器:一个本地、完全确定性的服务器,运行时无网络调用,由本地 JSON 数据集(包含施工作业类型及其天气限制)支撑,暴露四个编码了施工领域规则的工具(天气适宜性判定、养护时间估算和多作业调度)。

这两个服务器刻意不重叠职责。OpenWeather MCP 是唯一提供逐日变化信息的来源——即天气本身。BuildWindow MCP 则拥有所有固定规则:给定作业类型能承受的温度、风力、湿度和降水范围,混凝土在给定温度下需要多长时间养护,以及如何将多个有依赖关系的作业安排到跨多天预报中最早的非禁止时段。BuildWindow 服务器使用官方 Python MCP SDK(包 mcp,v2.0.0+)构建,使用其 MCPServer 类——注意,在旧版 SDK 中此类名为 FastMCP,自 SDK v2.0.0 起更名为 MCPServer。驱动两个连接的智能体使用 Claude Agent SDK(PyPI 上的 claude-agent-sdk)构建。

对调度关键的 OpenWeather 调用刻意不由 LLM 执行。上游工具的实际输出(通过阅读其源码确认——见 docs/tool-contracts.md)是纯文本报告,而非 JSON,并且它对任何失败(密钥错误、城市无法识别、提供商不可达)给出的唯一信号是语法上成功但内容为空的响应——没有可供反应的错误文本。因此 agent/main.py 通过低级 MCP 客户端直接调用它,用一个小的、经过单元测试的函数(agent/normalize.py)解析,然后才启动 LLM 会话——将已经干净的每日数据交给模型,而不是要求它解释原始提供商文本。LLM 会话同时连接到两个 MCP 服务器(get_mcp_status() 发现显示两个连接),并且模型确实被允许自己调用天气工具(allowed_tools 明确列出它)——但仅限于最终报告中的一句当前天气状况描述,按系统提示要求;驱动 plan_work_schedule 的每日预报始终来自会话前确定性的预取,绝不来自模型自己的调用。两个服务器在智能体自身的流程中都被真正使用,而不仅仅是可见。

engineer input (city + work list)
  -> agent/main.py calls OpenWeather MCP directly (not via the LLM) for
     the schedule-critical daily forecast
  -> agent/normalize.py parses the plain-text response into daily figures
  -> (if no usable forecast: report plainly, stop -- no LLM session started)
  -> LLM session starts, connected to BOTH MCP servers; may itself call
     the weather tool once for current-conditions color commentary only
  -> given the daily forecast + works as plain JSON (the only input that
     ever drives scheduling)
  -> BuildWindow MCP  (plan_work_schedule, validate_work_window,
     estimate_curing_time, ...)
  -> schedule + explanation

Related MCP server: condensation-mcp

先决条件

  • Python 3.12+ — 本仓库针对 3.12.3 构建并测试。

  • uv — 用作本项目的依赖管理器。

  • Go 1.24+ — 仅当你想自己构建 OpenWeather MCP 服务器时才需要(此处通过 winget install --id GoLang.Go 安装,当前为 Go 1.26.7)。使用 BuildWindow 服务器或运行其测试不需要。

  • OpenWeather API 密钥 — 仅当针对真实天气进行实时智能体运行时需要。免费层级可在 openweathermap.org/api 获取。

安装

从仓库根目录:

uv sync

这会创建 .venv 并安装运行时依赖(mcp、pydantic、claude-agent-sdk、python-dotenv)和开发依赖(pytest、ruff、black)。

配置

复制示例环境文件并填入你的密钥:

Copy-Item .env.example .env

bash:cp .env.example .env

然后编辑 .env,将 OWM_API_KEY 设置为来自 openweathermap.org/api(免费层级)的真实密钥。.env 已被 gitignore——永远不会被提交。

agent/mcp_config.json 是两个 MCP 服务器配置的唯一事实来源。其 openweather 条目引用 ${OWM_API_KEY} 作为占位符,agent/main.py 在启动时从进程环境替换它。注意 agent/main.py 本身不读取 .env——其 main() 首先调用 python-dotenv 的 load_dotenv(),正是这个调用使 .env 中的值在替换发生前进入进程环境。

其 openweather.command 字段本身也是一个占位符 ${MCP_OPENWEATHER_PATH}——agent/main.py 在设置了 MCP_OPENWEATHER_PATH 环境变量时从中解析,否则回退到裸命令 mcp-openweather(依赖 PATH)。如果你不想把二进制文件所在目录加入 PATH,请在 .env 中设置 MCP_OPENWEATHER_PATH(见 .env.example)为二进制的绝对路径——两种方式都已验证可实时工作。

构建 OpenWeather MCP 服务器(仅当你想针对真实天气进行实时运行时需要)。以下是在本仓库自身开发环境中用于构建和验证的确切命令:

winget install --id GoLang.Go -e --accept-source-agreements --accept-package-agreements
# open a new shell so PATH picks up the Go toolchain, then:
go install github.com/mschneider82/mcp-openweather@main

这会安装到 $(go env GOPATH)\bin\mcp-openweather.exe——在 Windows 上通常是 %USERPROFILE%\go\bin\mcp-openweather.exe。重要: Go MSI 安装程序会将 Go 工具链(C:\Program Files\Go\bin)添加到 PATH,但不会添加 %USERPROFILE%\go\bin——即 go install 实际放置构建二进制文件的位置。要么自己将该目录添加到 PATH,要么将 MCP_OPENWEATHER_PATH 设置为二进制的完整路径(见上文)——本仓库自身的设置使用后者。

为什么用 @main 而不是 @latest: go install ...@latest 解析到标签 v1.0.0,它比仓库的 main 分支落后一个真实提交("Fix #5")。本项目对两者都进行了构建并实时比较:v1.0.0 在完全省略可选的 units/lang 参数时没有回退,因此省略 lang 会以 language unavailable 失败,尽管工具自身的 schema 声明了默认值;main 的 "Fix #5" 提交添加了防御性处理,同样的调用成功。除此之外,两个版本的预报模板完全相同(通过阅读两个版本的源码确认)——从 main 构建不会增加逐日风力/湿度/降水,只修复了参数 bug。agent/main.py 无论如何总是显式传递 city、units="c" 和 lang="en",所以这个 bug 无论如何都不会通过本项目暴露——但如果你以其他方式调用该工具,main 是更稳健的依赖选择。

不要使用上游 README 某些示例中显示的 -o mcp-weather 标志——那会产生与其自身配置示例不一致的二进制名称。使用默认名称 mcp-openweather 构建。

运行 MCP 服务器

uv run python -m server.main

这通过 stdio 运行 BuildWindow MCP 服务器,独立于智能体进程——它可以完全独立地启动和运行。成功时它向 stderr 打印恰好这一行:

BuildWindow MCP server ready: 4 tools, 12 work types loaded

运行智能体

uv run python -m agent.main

不带参数时,使用内置演示城市("Kyiv")和内置演示作业列表:excavation,然后是 concrete_pour(依赖前者),然后是 concrete_finishing(依赖 concrete_pour)。

两者都可以覆盖:

uv run python -m agent.main "CityName"
uv run python -m agent.main "CityName" '[{"work_code": "excavation", "duration_days": 1, "depends_on": []}]'

可选的第二个参数是与演示列表形状相同的 JSON 作业数组。

回放模式 — --forecast-from-file <path> 完全离线:它用从记录文件读取的数据替换每日预报和当前天气状况说明,通过与实时调用相同的确定性解析器(normalize_forecast、parse_current_conditions)。此模式下 openweather 完全不连接(通过 get_mcp_status() 确认——只出现 buildwindow),因此运行不需要网络访问,也不需要任何 API 密钥——已通过同时使用故意损坏的 OWM_API_KEY 和不可达的 MCP_OPENWEATHER_PATH 实时验证;运行仍然正常完成:

uv run python -m agent.main "Longyearbyen" '[{"work_code": "excavation", "duration_days": 1, "depends_on": []}, {"work_code": "exterior_painting", "duration_days": 2, "depends_on": []}]' --forecast-from-file fixtures/weather_longyearbyen.txt

fixtures/weather_kyiv.txt 和 fixtures/weather_longyearbyen.txt 是本项目实时捕获的真实响应(每个裁剪为 3 个完整的真实日历日,两者内部均无密钥)——不是合成的,不是虚构的示例。如果演示城市的真实天气在你运行时已经改变,或者演示时完全没有网络,这些文件很有用。

针对真实天气的完整实时运行需要真正有效的 OWM_API_KEY(见上文配置)——已在本仓库自身开发环境中确认可用:uv run python -m agent.main "Kyiv" 从真实预报生成真实调度,uv run python -m agent.main "Longyearbyen" '[...]' 演示了真实天气确实迫使重新调度(见 docs/demo-checklist.md 步骤 4))。没有有效密钥时,agent/main.py 直接获取预报(不通过 LLM),得到空结果,打印 Forecast unavailable for '<city>' (...),并在启动任何 LLM 会话之前退出——不浪费模型调用,不生成虚构调度。这已通过三种真实失败模式验证:mcp-openweather 二进制完全不可达、无效的 OWM_API_KEY、以及无效的城市名称——后两者通过这个上游工具实际上无法区分(原因见 docs/tool-contracts.md),并且都确认以同样干净的方式失败,即使同一环境中其他地方有真正有效的密钥。

OpenWeather 速率限制: 一次成功的实时运行恰好对 weather 工具进行两次真实调用(通过计数实时确认)——确定性的会话前预取,加上模型自己的一次当前天气状况调用(见上文概述)。一次失败的实时运行(无可用预报)恰好进行一次,因为 LLM 会话从未启动。回放模式(--forecast-from-file)进行零次——每日预报和当前天气状况说明都来自记录文件,此模式下 openweather 完全不连接(实时确认:get_mcp_status() 只显示 buildwindow)。OpenWeather 免费层级文档为 60 次/分钟和 1,000,000 次/月——对于任意数量的手动演示运行都绰绰有余;本项目本身不压力测试该公布数字。

项目结构

.
├── README.md, DECISIONS.md, pyproject.toml, uv.lock, .env.example, .gitignore
├── docs/
│   ├── tool-contracts.md
│   ├── design-rationale.md
│   └── demo-checklist.md
├── scripts/
│   └── list_tools.py      # proves both MCP connections discover fine offline
├── server/
│   ├── main.py            # MCP server entry point, registers the 4 tools
│   ├── schemas.py         # Pydantic input/output models
│   ├── rules.py           # deterministic verdict/curing/planner logic
│   ├── dataset.py         # loads and validates work_types.json
│   ├── errors.py          # domain exceptions and error codes
│   └── data/work_types.json
├── agent/
│   ├── main.py             # agent entry point (Claude Agent SDK)
│   ├── normalize.py        # deterministic OpenWeather text -> daily figures
│   └── mcp_config.json     # config for both MCP servers
├── fixtures/
│   ├── weather_kyiv.txt      # real captured response, for --forecast-from-file
│   └── weather_longyearbyen.txt  # real captured response, for --forecast-from-file
└── tests/
    ├── conftest.py
    ├── test_dataset.py, test_lookup.py, test_validate.py
    ├── test_curing.py, test_planner.py, test_errors.py
    └── test_normalization.py

工具概述

工具

摘要

lookup_work_requirements

查找某个作业类型或整个类别的天气限制。

validate_work_window

将一个作业类型与一天的天气进行核对,并返回逐项判定。

estimate_curing_time

给定每日温度序列,估算养护作业类型实际何时就绪。

plan_work_schedule

一次调用将多个有依赖关系的作业安排到跨多天预报中。

完整契约——每个工具的确切 JSON Schema 和真实捕获示例,包括本项目使用的外部 weather 工具——位于 docs/tool-contracts.md。

测试

uv run pytest -v
uv run ruff check .
uv run black --check .

目前这三项在本仓库中均顺利通过:51 个测试通过(涵盖 38 个规范要求用例、若干补充断言,以及 8 个针对 agent/normalize.py 天气解析模块的测试,其中包括两个真实夹具用例和两个当前天气状况用例),且 ruff 和 black 均未报告任何问题。

局限性

每项限制背后的完整理由见 docs/design-rationale.md——此列表有意保持简洁:

  • 数据集阈值仅为示意性数值,并非源自真实的 ДБН/ДСТУ 标准。

  • 规划器没有资源/人员约束——工序之间可以日期重叠。

  • 实际规划周期因 OpenWeather 提供商而限制为 5 天。

  • 养护时间采用简化的 Nurse-Saul 成熟度模型。

  • 每道工序占据一个连续时间段——不支持拆分排程。

  • OpenWeather MCP 服务器的 weather 工具(通过阅读其源码确认,而非臆测)仅暴露每个 3 小时预报条目的温度——风速和湿度仅在单个当前天气状况快照中可用,此处将其作为常量应用于每个预报日,而降水量则完全未暴露,因此通过此集成 precipitation_mm 始终为 0.0。这意味着 BuildWindow 的降水规则(当 precipitation_allowed=false 的工序在 precipitation_mm > 0 时会被判定为硬性违规)实际上永远无法通过此集成的实时运行触发——它是真实、正确的代码,由针对构造数据的单元测试覆盖(tests/test_validate.py,规范用例 #16-17),但实时演示无法展示,因为不存在非零降水的实时路径。本项目不会模拟或注入虚假降雨数据来制造该演示。同一上游工具也无法区分无效 API 密钥、无法识别的城市和无法访问的提供商——这三种情况都返回相同的语法成功但内容为空的响应,这就是为什么 agent/main.py 对于这三种情况只能报告"无可用预报",而无法报告具体原因。完整且经源码验证的细节见 docs/tool-contracts.md。

  • 一个真正有效的 OWM_API_KEY 现已确认可用:针对真实基辅天气的完整实时运行可端到端生成真实排程,并且找到了一个真实的寒冷城市(朗伊尔城),其实时预报确实迫使某道工序被判定为 unschedulable,且 validate_work_window 以真实数据触发——见 docs/demo-checklist.md 第 4 步。本 README 中描述的所有内容现已针对真实有效的密钥验证过,而不仅仅是缺失的密钥;关于那次针对真实数据的实时运行对代码做了哪些改变、未做哪些改变,见 DECISIONS.md。

文档

  • docs/tool-contracts.md — 全部四个 BuildWindow 工具以及本项目使用的外部 OpenWeather weather 工具的精确 JSON Schema 契约,每个均附有真实捕获的示例。

  • docs/design-rationale.md — 每个工具存在的原因、工具集如何映射到工作流、组件之间的边界、所做的权衡以及项目的完整局限性。

  • docs/demo-checklist.md — 运行项目实时演示的分步检查清单。

  • DECISIONS.md — 带日期的实现决策日志,每项决策均附有理由和被否决的替代方案。

Available Tools

4 tools
estimate_curing_timeA

Estimate how long a concrete or coating work type needs to cure under a given sequence of daily temperatures, using the Nurse-Saul maturity method. Use this when a work type has a curing stage and cold weather may extend it beyond the nominal duration. Returns the ready date, or capped=true when the supplied temperature sequence is too short to reach the required maturity. Fails with no_curing_stage for work types that have no curing stage at all.

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
cappedYesTrue if the supplied temperature sequence was too short to reach required_maturity.
work_codeYesThe work type curing was estimated for.
ready_dateYesDate the work becomes ready, or null if not reached within the supplied days.
daily_breakdownYesPer-day maturity accounting. Truncated at the ready day if one was found; includes every supplied day if capped is true.
effective_hoursYesElapsed hours (in whole days) needed to reach the ready date, or covered by the supplied days if capped.
required_maturityYesTarget Nurse-Saul maturity in degree-Celsius-hours.
accumulated_maturityYesMaturity actually accumulated over the supplied days.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and clearly discloses return behavior (ready date vs capped=true when the sequence is too short) and error behavior (no_curing_stage). It also names the calculation method, which informs the agent of the model type.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and information-dense, with the main action, method, use trigger, return modes, and error case all front-loaded. There is no filler; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description explains the output conditions and failure mode, and an output schema exists, so the remaining gaps are acceptable. A brief note about which sibling tool to use instead would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Top-level schema coverage is 0%, so the description must compensate; it does mention daily temperatures and work types in prose but does not clarify start_date semantics or the work_code enum/units. The nested schema does contain field descriptions, so this is adequate but not a strong contribution beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (estimate curing time), the resource class (concrete/coating work types), the input (daily temperature sequence), and the method (Nurse-Saul), which clearly distinguishes it from planning/lookup siblings. The use-case sentence also reinforces that this tool estimates curing duration rather than performing scheduling, validation, or requirements lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use this when a work type has a curing stage and cold weather may extend duration beyond nominal, and notes that it fails with no_curing_stage for work types without one. It does not name sibling alternatives or provide a full when-not-to-use list, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_work_requirementsA

Return the normative weather constraints for construction work types. Call this first when you need to know the temperature, wind, humidity or precipitation limits that apply to a work type, or to enumerate all work types in a category. Provide either a single work_code or a category, never both. Returns an empty list with matched_count=0 when the category contains no work types; this is a successful result, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
requirementsYesMatching work type requirements. Empty if none matched.
matched_countYesNumber of items in requirements.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It does: it notes that an empty category returns an empty list with matched_count=0 and is a successful result, not an error. It also states the exclusive parameter requirement. It does not go into depth about authorization, reversible side effects, or detailed response structure, but for a read-only lookup this is adequate. The empty-result behavior is a valuable disclosure beyond what a schema would imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences, front-loaded with the core purpose, then usage guidance, then a constraint, then a behavioral nuance. Every sentence contributes information; there is no fluff. The structure guides the agent from 'what' to 'how' to 'edge case' efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a straightforward lookup tool with two optional parameters and an output schema (not shown). The description covers the trigger conditions, the parameter rule, and the successful empty-result case. Since an output schema exists, defining the return format is not necessary. All information needed to invoke the tool correctly and interpret a common edge case is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides rich descriptions for both parameters (enums with names and descriptions), so the baseline is 3 given high schema coverage. The description adds the critical mutual-exclusivity rule ('never both') which is also in the schema description, but the tool description reinforces it in a clearer, action-oriented way. It also mentions the two parameter names, which helps an agent map the rule to the fields. Slight added value over the schema, hence 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Return the normative weather constraints for construction work types.' It also explains the two call patterns (by work_code or category) and clearly distinguishes this tool from siblings like validate_work_window and estimate_curing_time, which address different concerns. The phrase 'Call this first' reinforces its role as a primary lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it: 'Call this first when you need to know the temperature, wind, humidity or precipitation limits...' and also covers the alternate use case 'to enumerate all work types in a category.' It adds a strict usage constraint ('Provide either a single work_code or a category, never both') and clarifies the handling of empty results. No ambiguity remains about when to call this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

plan_work_scheduleA

Produce a feasible day-by-day schedule for several construction works across a weather forecast, honouring declared dependencies between works. Each work is placed in the earliest window where no day is prohibited. Returns both the scheduled works and the works that could not be placed, each with an explicit reason. Use this instead of repeated validate_work_window calls when planning more than one work.

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
scheduledYesWorks successfully placed.
horizon_endYesLast date covered by the supplied forecast.
horizon_startYesFirst date covered by the supplied forecast.
unschedulableYesWorks that could not be placed, each with a reason.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the scheduling algorithm ('earliest window where no day is prohibited'), the dependency handling, and what the return value contains (scheduled works and unplaced works, each with an explicit reason). It does not explicitly state side-effect behavior, but the tool's planning nature and return-focused wording make non-mutation reasonably clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences and every sentence carries useful information: purpose, algorithm, return value, and usage guidance. It is not bloated, though the algorithm and return-value sentences could potentially be tightened without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a relatively complex input (multiple works, dependencies, weather windows) and an output schema, the description covers the essential behaviors: feasibility, dependency ordering, earliest placement, and the split between scheduled and unscheduled works with reasons. It does not mention input limits or detailed weather constraint logic, but those are already present in the schema and would not affect tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0% at the top level, and the description does not directly explain the `request` parameter structure. However, it does reference the core semantic pieces: 'several construction works', 'weather forecast', and 'dependencies', which map to `works`, `forecast`, and `depends_on`. The nested schema definitions are rich, so the description adds modest context without fully compensating for the top-level coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Produce a feasible day-by-day schedule for several construction works across a weather forecast' while also naming the key constraint ('honouring declared dependencies'). It clearly distinguishes this tool from the sibling validate_work_window by framing it as the multi-work planning alternative, so an agent can identify its purpose immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool instead of an alternative: 'Use this instead of repeated validate_work_window calls when planning more than one work.' This provides a clear condition and names the sibling tool it replaces, giving the agent actionable selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_work_windowA

Evaluate whether one construction work type may proceed during one specific day of weather. Returns a verdict of allowed, conditional or prohibited together with the exact constraints that were breached and by how much. Use this to check a single work-day; use plan_work_schedule when you need to place several works across a forecast. The verdict is computed by deterministic rules, not estimated — treat it as authoritative.

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
verdictYesOverall verdict for this work-day.
warningsYesNear-boundary breaches within the conditional tolerance band. Any entry here (with violations empty) forces verdict=conditional.
work_codeYesThe work type that was evaluated.
violationsYesHard constraint breaches. Any entry here forces verdict=prohibited.
window_dateYesThe date that was evaluated.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses the output format (allowed, conditional, or prohibited verdict) and that it includes constraints breached and by how much. It also states the tool is deterministic and authoritative, setting clear expectations for behavior. It does not detail the exact conditions for each verdict, but for a validation tool this is adequate and is not a major gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, consisting of two clear sentences with no redundant phrases. It efficiently conveys purpose, usage, and behavior without fluff, making it easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers the necessary context: what the tool does, when to use it, what it returns, and how it differs from a sibling. The existence of an output schema (even if not shown) is not a barrier because the description already specifies the expected output shape. It is self-contained and sufficient for an agent to decide when and how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides rich descriptions for the nested fields (work_code, window, and weather properties), so the parameter semantics are already well-defined. The description text does not add explicit parameter details beyond implicitly referencing 'work type' and 'day of weather.' Since the schema coverage is strong, the description's minimal contribution is acceptable, but it does not elevate the score beyond the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: evaluating whether a work type may proceed under given weather. It explicitly distinguishes it from the sibling tool plan_work_schedule, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool versus the alternative: 'Use this to check a single work-day; use plan_work_schedule when you need to place several works across a forecast.' This leaves no ambiguity about appropriate invocation scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedestimate_curing_time
    • First observedlookup_work_requirements
    • First observedplan_work_schedule
    • First observedvalidate_work_window

TDQS

A4.6/5.0

Scored across 4 tools

Disambiguation5/5

Each tool serves a distinct purpose: querying requirements, validating a single day, estimating curing, and planning schedules. No overlap in functionality; an agent can easily select the right tool for the task.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: lookup_work_requirements, validate_work_window, estimate_curing_time, plan_work_schedule. The naming style is uniform and predictable.

Tool Count5/5

With only 4 tools, the server is well-scoped for its construction weather planning domain. Each tool is essential and there is no bloat or missing core functionality.

Completeness5/5

The server covers the full workflow from looking up constraints to validating individual days, estimating curing, and planning multi-work schedules. It also handles edge cases like capping and failures gracefully, indicating thorough domain coverage.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Enables users to get weather alerts and forecasts through natural language interactions. Provides real-time weather information and alert notifications via MCP tools.
    2
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables users to assess condensation and mold risk for building surfaces using physics-based calculations (dew point, surface temperature, critical thresholds), with support for real-time weather data and prescription generation.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables users to check whether an Australian field-service job can be worked at a location on a given day for a specific trade, using live weather forecasts, daylight hours, and public holiday data.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables construction teams to create local projects, record sourced field evidence, run deterministic quantity calculations, and draft daily logs, estimates, and change orders with visible assumptions and human approval gates. Keeps all data local and portable with no external side effects.
    10
    Apache 2.0