BuildWindow
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@BuildWindowSchedule the concrete pour and curing for the next 5 days"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
BuildWindow
MCP lab project: an agent plans construction work against a real weather forecast using two MCP servers.
This is a course assignment for the KSE AI Agentic School (an MCP integration assignment): build a custom MCP server for a real domain problem, then connect it — alongside an existing third-party MCP server — to an agent that uses both together to do something a single tool couldn't.
Overview
BuildWindow is an MCP (Model Context Protocol) lab project built around a concrete scheduling problem: given a list of construction works with dependencies between them, and a weather forecast for a city, produce a schedule that respects both. The agent that does this planning holds two separate MCP connections at once. The first is the external, Go-based OpenWeather MCP server (github.com/mschneider82/mcp-openweather), which the agent calls once per run to get live current conditions and a 5-day forecast for the requested city — this is the only place in the whole project where a network call happens. The second is this repository's own BuildWindow MCP server: a local, fully deterministic server with no network calls at runtime, backed by a local JSON dataset of construction work types and their weather limits, that exposes four tools encoding the construction-domain rules (weather-suitability verdicts, curing-time estimation, and multi-work scheduling).
The two servers deliberately do not overlap in responsibility. OpenWeather
MCP is the only source of anything that changes day to day — the weather
itself. BuildWindow MCP owns everything that is a fixed rule instead: what
temperature, wind, humidity and precipitation a given work type tolerates,
how long concrete takes to cure at a given temperature, and how to place
several dependent works into the earliest non-prohibited windows across a
multi-day forecast. The BuildWindow server is built with the official
Python MCP SDK (package mcp, v2.0.0+), using its MCPServer class — note
that this class was named FastMCP in older SDK versions and was renamed
to MCPServer as of SDK v2.0.0. The agent that drives both connections is
built with the Claude Agent SDK (claude-agent-sdk on PyPI).
The schedule-critical OpenWeather call is deliberately not made by
the LLM. The upstream tool's actual output (confirmed by reading its
source — see docs/tool-contracts.md) is a plain-text report, not JSON,
and the only signal it gives for any failure (bad key, unrecognized
city, unreachable provider) is a syntactically successful but empty
response — there is no error text to react to. So agent/main.py calls
it directly via a low-level MCP client, parses it with a small,
unit-tested function (agent/normalize.py), and only then starts an LLM
session — handing the model already-clean daily figures instead of
asking it to interpret raw provider text. The LLM session is connected to
both MCP servers (get_mcp_status() discovery shows both connections),
and the model genuinely is allowed to call the weather tool itself
(allowed_tools lists it explicitly) — but only for one current-
conditions sentence in its final report, per the system prompt; the daily
forecast that drives plan_work_schedule always comes from the
deterministic pre-session fetch, never from the model's own call. Both
servers are genuinely used in the agent's own flow, not just visible.
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 + explanationRelated MCP server: Weather MCP Server
Prerequisites
Python 3.12+ — this repo was built and tested against 3.12.3.
uv — used as the dependency manager for this project.
Go 1.24+ — only needed if you want to build the OpenWeather MCP server yourself (installed here via
winget install --id GoLang.Go, currently Go 1.26.7). Not required to use the BuildWindow server or to run its tests.An OpenWeather API key — only needed for a live agent run against real weather. Free tier available at openweathermap.org/api.
Installation
From the repo root:
uv syncThis creates a .venv and installs both the runtime dependencies (mcp,
pydantic, claude-agent-sdk, python-dotenv) and the dev dependencies
(pytest, ruff, black).
Configuration
Copy the example environment file and fill in your key:
Copy-Item .env.example .envbash: cp .env.example .env
Then edit .env and set OWM_API_KEY to a real key from
openweathermap.org/api (free tier).
.env is gitignored — it is never committed.
agent/mcp_config.json is the single source of truth for both MCP server
configurations. Its openweather entry references ${OWM_API_KEY} as a
placeholder, which agent/main.py substitutes from the process
environment at startup. Note that agent/main.py does not read .env
itself — its main() calls python-dotenv's load_dotenv() first, and
that call is what actually makes the values in .env reach the process
environment before the substitution happens.
Its openweather.command field is itself a placeholder,
${MCP_OPENWEATHER_PATH} — agent/main.py resolves it from the
MCP_OPENWEATHER_PATH environment variable if set, or falls back to the
bare command mcp-openweather (relying on PATH) if not. Set
MCP_OPENWEATHER_PATH in .env (see .env.example) to the binary's
absolute path if you don't want to add its directory to PATH — both
were verified to work live.
Building the OpenWeather MCP server (only needed if you want a live run against real weather). These are the exact commands used to build and verify it in this repo's own development environment:
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@mainThis installs to $(go env GOPATH)\bin\mcp-openweather.exe — on Windows
that's typically %USERPROFILE%\go\bin\mcp-openweather.exe. Important:
the Go MSI installer adds the Go toolchain (C:\Program Files\Go\bin)
to PATH, but does not add %USERPROFILE%\go\bin — where go install actually places built binaries. Either add that directory to
PATH yourself, or set MCP_OPENWEATHER_PATH to the binary's full path
(see above) — this repo's own setup uses the latter.
Why @main and not @latest: go install ...@latest resolves to
tag v1.0.0, which is one real commit ("Fix #5") behind the repository's
main branch. Both were built and compared live this project: v1.0.0
reads the optional units/lang arguments with no fallback when
they're omitted entirely, so an omitted lang fails with language unavailable even though the tool's own schema declares a default;
main's "Fix #5" commit adds defensive handling and the same call
succeeds. The forecast template itself is otherwise identical between
the two (confirmed by reading both versions' source) — building from
main doesn't add per-day wind/humidity/precipitation, it only fixes
the argument bug. agent/main.py always passes city, units="c", and
lang="en" explicitly regardless, so this bug can't actually surface
through this project either way — but main is the more robust binary
to depend on if you ever call the tool a different way.
Do not use the -o mcp-weather flag shown in some of the upstream
README's own examples — that produces a binary name inconsistent with its
own config example. Build with the default name, mcp-openweather.
Running the MCP server
uv run python -m server.mainThis runs the BuildWindow MCP server over stdio, independent of the agent process — it can be started and exercised entirely on its own. On success it prints exactly this line to stderr:
BuildWindow MCP server ready: 4 tools, 12 work types loadedRunning the agent
uv run python -m agent.mainWith no arguments, this uses a built-in demo city ("Kyiv") and a built-in
demo work list: excavation, then concrete_pour (depending on it), then
concrete_finishing (depending on that).
Both can be overridden:
uv run python -m agent.main "CityName"
uv run python -m agent.main "CityName" '[{"work_code": "excavation", "duration_days": 1, "depends_on": []}]'The optional second argument is a JSON array of works in the same shape as the demo list.
Replay mode — --forecast-from-file <path> is fully offline: it
replaces both the daily forecast and the current-conditions note with
data read from a recorded file, via the same deterministic parsers
(normalize_forecast, parse_current_conditions) used for a live call.
openweather is not connected at all in this mode (confirmed via
get_mcp_status() — only buildwindow appears), so a run needs no
network access and no API key whatsoever — verified live with a
deliberately broken OWM_API_KEY and an unreachable
MCP_OPENWEATHER_PATH at the same time; the run still completed
normally:
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.txtfixtures/weather_kyiv.txt and fixtures/weather_longyearbyen.txt are
real responses captured live this project (trimmed to 3 full real
calendar days each, no key inside either) — not synthetic, not
fabricated examples. Useful if the real weather in a demo city has
changed by the time you're running this, or if there's no network at
all at demo time.
A full live run against real weather requires a genuinely valid
OWM_API_KEY (see Configuration above) — confirmed working in this
repo's own development environment: uv run python -m agent.main "Kyiv"
produces a real schedule from a real forecast, and
uv run python -m agent.main "Longyearbyen" '[...]' demonstrates real
weather actually forcing a reschedule (see docs/demo-checklist.md step
4). Without a working key, agent/main.py fetches the forecast directly
(not via the LLM), gets an empty result, prints
Forecast unavailable for '<city>' (...), and exits before starting
any LLM session — no wasted model call, no fabricated schedule. This was
verified with three real failure modes: the mcp-openweather binary
unreachable at all, an invalid OWM_API_KEY, and an invalid city name —
the last two are actually indistinguishable through this upstream tool
(see docs/tool-contracts.md for why) and were both confirmed to fail
the same clean way, even with a genuinely valid key active elsewhere in
the same environment.
OpenWeather rate limits: one successful live run makes exactly
two real calls to the weather tool (confirmed live, by counting) —
the deterministic pre-session fetch, plus the model's own single
current-conditions call (see Overview above). A failed live run (no
usable forecast) makes exactly one, since the LLM session never starts.
Replay mode (--forecast-from-file) makes zero — both the daily
forecast and the current-conditions note come from the recorded file,
and openweather isn't connected at all in this mode (confirmed live:
get_mcp_status() shows only buildwindow). OpenWeather's free tier is
documented at 60 calls/minute and 1,000,000 calls/month — comfortably
enough for any number of manual demo runs; this project doesn't
stress-test that published figure itself.
Project structure
.
├── 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.pyTool overview
Tool | Summary |
| Look up a work type's, or an entire category's, weather limits. |
| Check one work type against one day of weather and get back an itemized verdict. |
| Estimate when a curing work type will actually be ready, given a sequence of daily temperatures. |
| Place several dependent works across a multi-day forecast in one call. |
The full contracts — exact JSON Schemas and real captured examples for
every tool, including the external weather tool as used by this project
— live in docs/tool-contracts.md.
Testing
uv run pytest -v
uv run ruff check .
uv run black --check .All three currently pass cleanly in this repo: 51 tests pass (covering
the 38 spec-required cases, a few supplementary assertions, and 8 tests
for the agent/normalize.py weather-parsing module, including the two
real-fixture and two current-conditions cases), and both ruff and
black report no issues.
Limitations
The full reasoning behind each of these lives in
docs/design-rationale.md — this list is
intentionally brief:
Dataset thresholds are illustrative, not derived from real ДБН/ДСТУ standards.
The planner has no resource/crew constraints — works can overlap dates.
The real planning horizon is capped at 5 days by the OpenWeather provider.
Curing time uses a simplified Nurse-Saul maturity model.
One work occupies one continuous block — there is no split scheduling.
The OpenWeather MCP server's
weathertool (confirmed by reading its source, not assumed) exposes only temperature per 3-hour forecast entry — wind speed and humidity are only available in a single current-conditions snapshot, applied here as a constant across every forecast day, and precipitation isn't exposed at all, soprecipitation_mmis always0.0through this integration. This means BuildWindow's precipitation rule (a work withprecipitation_allowed=falsegets a hard violation ifprecipitation_mm > 0) can never actually trigger from a live run through this integration — it's real, correct code, covered by unit tests against constructed data (tests/test_validate.py, spec cases #16-17), but not something a live demo can show, since there is no live path to non-zero precipitation. This project does not simulate or inject fake rain data to manufacture that demo. The same upstream tool also can't distinguish a bad API key from an unrecognized city from an unreachable provider — all three come back as the same syntactically-successful-but-empty response, which is whyagent/main.pycan only report "no forecast available," not a specific cause, for any of those three cases. Seedocs/tool-contracts.mdfor the full, source-verified detail.A genuinely valid
OWM_API_KEYis now confirmed working: a full live run against real Kyiv weather produces a real schedule end-to-end, and a real cold-weather city (Longyearbyen) was found where the live forecast actually forces a workunschedulableandvalidate_work_windowfires with real numbers — seedocs/demo-checklist.mdstep 4. Everything described in this README has now been verified against a real, working key, not just an absent one; seeDECISIONS.mdfor what that live run against real data did and didn't change in the code.
Documentation
docs/tool-contracts.md— the exact JSON Schema contracts for all four BuildWindow tools, and for the external OpenWeatherweathertool as used by this project, each with a real captured example.docs/design-rationale.md— why each tool exists, how the tool set maps onto the workflow, the boundaries between components, the trade-offs made, and the project's limitations in full.docs/demo-checklist.md— a step-by-step checklist for running a live demo of the project.DECISIONS.md— a dated log of implementation decisions, each with its rationale and the alternative that was rejected.
Available Tools
4 toolsestimate_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.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| capped | Yes | True if the supplied temperature sequence was too short to reach required_maturity. |
| work_code | Yes | The work type curing was estimated for. |
| ready_date | Yes | Date the work becomes ready, or null if not reached within the supplied days. |
| daily_breakdown | Yes | Per-day maturity accounting. Truncated at the ready day if one was found; includes every supplied day if capped is true. |
| effective_hours | Yes | Elapsed hours (in whole days) needed to reach the ready date, or covered by the supplied days if capped. |
| required_maturity | Yes | Target Nurse-Saul maturity in degree-Celsius-hours. |
| accumulated_maturity | Yes | Maturity actually accumulated over the supplied days. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| requirements | Yes | Matching work type requirements. Empty if none matched. |
| matched_count | Yes | Number of items in requirements. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| scheduled | Yes | Works successfully placed. |
| horizon_end | Yes | Last date covered by the supplied forecast. |
| horizon_start | Yes | First date covered by the supplied forecast. |
| unschedulable | Yes | Works that could not be placed, each with a reason. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| verdict | Yes | Overall verdict for this work-day. |
| warnings | Yes | Near-boundary breaches within the conditional tolerance band. Any entry here (with violations empty) forces verdict=conditional. |
| work_code | Yes | The work type that was evaluated. |
| violations | Yes | Hard constraint breaches. Any entry here forces verdict=prohibited. |
| window_date | Yes | The date that was evaluated. |
TDQS
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.
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.
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.
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.
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.
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. Dates show when Glama detected each change.
4 tool updates
v0.1.0- First observed
estimate_curing_time - First observed
lookup_work_requirements - First observed
plan_work_schedule - First observed
validate_work_window
TDQS
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.
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.
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.
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
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Built-environment forecasts, public benchmarks, and permit or zoning readiness through remote MCP.
- mcpOAuthcom.crisphive
Field operations on a deterministic solver — run jobs, crews & fleet from Claude or ChatGPT.
13 Forensic scheduling MCP for Primavera P6 (XER): AACE windows, DCMA-14, Monte Carlo, TIA.
- DemitonOAuthio.demiton
AI infrastructure for Australian civil construction. Public procurement data and connected systems.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables users to get weather alerts and forecasts through natural language interactions. Provides real-time weather information and alert notifications via MCP tools.2-
- AlicenseNot gradedqualityDmaintenanceGlobal weather intelligence for AI assistants providing 10 weather tools — forecasts, historical data, air quality, marine, geocoding, elevation, and climate projections at 1km resolution with 80+ years of archive.1MIT
- AlicenseNot gradedqualityDmaintenanceProvides personalized recommendations for optimal outdoor exercise times by integrating weather data, Garmin Connect training schedules, and user performance metrics.2Apache 2.0
- FlicenseNot gradedqualityCmaintenanceEnables 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.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/borovkov-d/buildwindow-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server