@cyanheads/wsdot-mcp-server 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -8
- package/CLAUDE.md +8 -8
- package/Dockerfile +18 -9
- package/README.md +2 -1
- package/changelog/0.2.x/0.2.4.md +38 -0
- package/changelog/0.2.x/0.2.5.md +11 -0
- package/changelog/template.md +55 -16
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/wsdot-mcp-server
|
|
4
|
-
**Version:** 0.2.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.
|
|
4
|
+
**Version:** 0.2.5
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.12.3`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0 (protocol revisions 2026-07-28 and 2025-*)
|
|
8
8
|
**Zod:** ^4.4.3
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
17
17
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
18
18
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
19
|
-
- **
|
|
19
|
+
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
20
20
|
- **Secrets in env vars only** — never hardcoded.
|
|
21
21
|
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
22
22
|
|
|
@@ -91,13 +91,13 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
91
91
|
|
|
92
92
|
| Property | Description |
|
|
93
93
|
|:---------|:------------|
|
|
94
|
-
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
94
|
+
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. Dual-sink: Pino **and** `notifications/message` to the client, so treat it as client-visible. |
|
|
95
95
|
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.getMany(keys)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
96
|
-
| `ctx.
|
|
96
|
+
| `ctx.requestInput` | Suspend and ask the caller for more input — `return ctx.requestInput({ inputRequests: { key: inputRequired.elicit({ message, requestedSchema }) } })`. Never returns; the handler is re-entered with the answers. Always present. |
|
|
97
|
+
| `ctx.inputs` | Reader over a retried request's responses — `.accepted(key, schema)`, `.view(key)`, `.state()`, `.dropped`. Empty on the first round. |
|
|
97
98
|
| `ctx.enrich` | Success-path agent context (empty-result notices, query echo, pagination totals) — `ctx.enrich(...)` or `.notice()` / `.total()` / `.echo()` / `.truncated()`. Reaches `structuredContent` and `content[]`; lands only when the definition declares an `enrichment` block (no-op otherwise). |
|
|
98
99
|
| `ctx.content` | Non-text content blocks — `.image(data, mimeType)`, `.audio(data, mimeType)`, or `ctx.content(block)` for a raw block. Prepended to `content[]` after `format()`; never enters `structuredContent`. |
|
|
99
100
|
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
100
|
-
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
101
101
|
| `ctx.requestId` | Unique request ID. |
|
|
102
102
|
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. |
|
|
103
103
|
|
|
@@ -223,7 +223,7 @@ Available skills:
|
|
|
223
223
|
| `api-auth` | Auth modes, scopes, JWT/OAuth |
|
|
224
224
|
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
|
|
225
225
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
226
|
-
| `api-context` | Context interface, logger, state,
|
|
226
|
+
| `api-context` | Context interface, RequestContext, logger, state, multi-round-trip input |
|
|
227
227
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
228
228
|
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
229
229
|
| `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
|
package/CLAUDE.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** @cyanheads/wsdot-mcp-server
|
|
4
|
-
**Version:** 0.2.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.
|
|
4
|
+
**Version:** 0.2.5
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.12.3`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0 (protocol revisions 2026-07-28 and 2025-*)
|
|
8
8
|
**Zod:** ^4.4.3
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
17
17
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
18
18
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
19
|
-
- **
|
|
19
|
+
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
20
20
|
- **Secrets in env vars only** — never hardcoded.
|
|
21
21
|
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
22
22
|
|
|
@@ -91,13 +91,13 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
91
91
|
|
|
92
92
|
| Property | Description |
|
|
93
93
|
|:---------|:------------|
|
|
94
|
-
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
94
|
+
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. Dual-sink: Pino **and** `notifications/message` to the client, so treat it as client-visible. |
|
|
95
95
|
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.getMany(keys)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
96
|
-
| `ctx.
|
|
96
|
+
| `ctx.requestInput` | Suspend and ask the caller for more input — `return ctx.requestInput({ inputRequests: { key: inputRequired.elicit({ message, requestedSchema }) } })`. Never returns; the handler is re-entered with the answers. Always present. |
|
|
97
|
+
| `ctx.inputs` | Reader over a retried request's responses — `.accepted(key, schema)`, `.view(key)`, `.state()`, `.dropped`. Empty on the first round. |
|
|
97
98
|
| `ctx.enrich` | Success-path agent context (empty-result notices, query echo, pagination totals) — `ctx.enrich(...)` or `.notice()` / `.total()` / `.echo()` / `.truncated()`. Reaches `structuredContent` and `content[]`; lands only when the definition declares an `enrichment` block (no-op otherwise). |
|
|
98
99
|
| `ctx.content` | Non-text content blocks — `.image(data, mimeType)`, `.audio(data, mimeType)`, or `ctx.content(block)` for a raw block. Prepended to `content[]` after `format()`; never enters `structuredContent`. |
|
|
99
100
|
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
100
|
-
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
101
101
|
| `ctx.requestId` | Unique request ID. |
|
|
102
102
|
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. |
|
|
103
103
|
|
|
@@ -223,7 +223,7 @@ Available skills:
|
|
|
223
223
|
| `api-auth` | Auth modes, scopes, JWT/OAuth |
|
|
224
224
|
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
|
|
225
225
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
226
|
-
| `api-context` | Context interface, logger, state,
|
|
226
|
+
| `api-context` | Context interface, RequestContext, logger, state, multi-round-trip input |
|
|
227
227
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
228
228
|
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
229
229
|
| `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
|
package/Dockerfile
CHANGED
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
# This stage installs all dependencies (including dev), builds the TypeScript
|
|
5
5
|
# source code into JavaScript, and prepares the production assets.
|
|
6
6
|
# ==============================================================================
|
|
7
|
-
FROM oven/bun:1.
|
|
7
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.0 AS build
|
|
8
8
|
|
|
9
9
|
WORKDIR /usr/src/app
|
|
10
10
|
|
|
11
11
|
# Copy dependency manifests for optimized layer caching
|
|
12
12
|
COPY package.json bun.lock ./
|
|
13
13
|
|
|
14
|
-
# Install all dependencies (including dev dependencies for building),
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
|
|
14
|
+
# Install all dependencies (including dev dependencies for building), ignoring
|
|
15
|
+
# lifecycle scripts (native postinstalls unsupported under Bun; the build only
|
|
16
|
+
# runs tsc, which needs type declarations, not compiled bindings).
|
|
17
|
+
# The BuildKit cache mount persists Bun's global package cache across builds.
|
|
18
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
19
|
+
bun install --frozen-lockfile --ignore-scripts
|
|
18
20
|
|
|
19
21
|
# Copy the rest of the source code
|
|
20
22
|
COPY . .
|
|
@@ -30,7 +32,7 @@ RUN bun run build
|
|
|
30
32
|
# application. It uses a slim base image and only includes production
|
|
31
33
|
# dependencies and build artifacts.
|
|
32
34
|
# ==============================================================================
|
|
33
|
-
FROM oven/bun:1.
|
|
35
|
+
FROM oven/bun:1.4.0-slim AS production
|
|
34
36
|
|
|
35
37
|
WORKDIR /usr/src/app
|
|
36
38
|
|
|
@@ -51,14 +53,21 @@ COPY package.json bun.lock ./
|
|
|
51
53
|
|
|
52
54
|
# Install only production dependencies, ignoring any lifecycle scripts (like 'prepare')
|
|
53
55
|
# that are not needed in the final production image.
|
|
54
|
-
|
|
56
|
+
# `--omit=peer` drops the framework's optional peer tiers (test runner, service
|
|
57
|
+
# SDKs, parsers) that Bun would otherwise auto-install. Anything this server
|
|
58
|
+
# actually imports belongs in its own `dependencies`, so nothing needed at
|
|
59
|
+
# runtime is lost. The OTEL step below carries the same flag — without it, that
|
|
60
|
+
# install re-resolves the graph and pulls every optional peer back in.
|
|
61
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
62
|
+
bun install --production --omit=peer --frozen-lockfile --ignore-scripts
|
|
55
63
|
|
|
56
64
|
# Conditionally install OpenTelemetry optional peer dependencies (Tier 3).
|
|
57
65
|
# These are not bundled by default to keep the base image lean. Enable at build time
|
|
58
66
|
# with: docker build --build-arg OTEL_ENABLED=true
|
|
59
67
|
ARG OTEL_ENABLED=true
|
|
60
|
-
RUN
|
|
61
|
-
|
|
68
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
69
|
+
if [ "$OTEL_ENABLED" = "true" ]; then \
|
|
70
|
+
bun add --omit=dev --omit=peer --ignore-scripts @hono/otel \
|
|
62
71
|
@opentelemetry/instrumentation-http \
|
|
63
72
|
@opentelemetry/exporter-metrics-otlp-http \
|
|
64
73
|
@opentelemetry/exporter-trace-otlp-http \
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/wsdot-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/wsdot-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -312,6 +312,7 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
|
|
|
312
312
|
| `MCP_HTTP_HOST` | HTTP server hostname. | `127.0.0.1` |
|
|
313
313
|
| `MCP_HTTP_ENDPOINT_PATH` | HTTP endpoint path. | `/mcp` |
|
|
314
314
|
| `MCP_PUBLIC_URL` | Public origin for TLS-terminating reverse-proxy deployments. | — |
|
|
315
|
+
| `MCP_SESSION_MODE` | Session handling: `auto`, `stateful`, or `stateless`. The schema default `auto` resolves to stateful; this server sets `stateless` explicitly. | `stateless` |
|
|
315
316
|
| `MCP_AUTH_MODE` | Authentication: `none`, `jwt`, or `oauth`. | `none` |
|
|
316
317
|
| `MCP_LOG_LEVEL` | Log level (`debug`, `info`, `notice`, `warning`, `error`). | `info` |
|
|
317
318
|
| `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts mcp-ts-core ^0.12.3 and MCP SDK v2 — tool inputs are strict, so an argument no tool declares is rejected by name instead of dropped; the HTTP endpoint serves protocol revision 2026-07-28, advertised schemas moved to JSON Schema 2020-12, and handler logs now reach the client."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.2.4 — 2026-08-25
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`tests/tools/input-strictness.test.ts`** pins the strict-input guarantee across all twelve tools: an undeclared key is rejected by name, every declared argument still parses, and the emitted schema advertises `additionalProperties: false` in the 2020-12 dialect.
|
|
12
|
+
|
|
13
|
+
## Changed
|
|
14
|
+
|
|
15
|
+
- **Tool inputs are strict.** An argument key none of the twelve `wsdot_*` tools declares is now rejected by name, where it was previously dropped and the call ran without it — a misspelled `state_route` on `wsdot_search_alerts` returned every alert in the state and read as a success.
|
|
16
|
+
- **The HTTP endpoint serves MCP protocol revision `2026-07-28`** alongside the 2025 revisions; a 2025-era client negotiates exactly as before.
|
|
17
|
+
- **Advertised schemas moved to JSON Schema 2020-12**, and `outputSchema` now declares the error envelope. A client that rejects draft-07 outright, or that validates `structuredContent` without checking `isError`, no longer fails against these tools.
|
|
18
|
+
- **`ctx.log` output reaches the client** as `notifications/message` at its RFC 5424 level, gated by the client's `logging/setLevel`. Every tool logs a fetch summary, so those lines are now client-visible.
|
|
19
|
+
- **`tools/list` and `server/discover` carry a 24-hour `public` cache hint** for 2026-07-28 clients — the tool surface is fixed at build time and nothing in it is caller-scoped.
|
|
20
|
+
- **HTTP session mode is `stateless` explicitly.** `.env.example` sets `MCP_SESSION_MODE` and the README config table documents it, matching what the published container already sets; the schema default `auto` resolves to stateful, so a source run previously diverged from the container. `/.well-known/mcp.json` and the landing page also report the resolved mode rather than `auto`.
|
|
21
|
+
- **Docker: Bun pins move to `1.4.0`** on both stages, the production install and the OTEL step drop the framework's optional peer tiers (`--omit=peer`), and every install step shares Bun's package cache through a BuildKit cache mount.
|
|
22
|
+
- **`.github/CONTRIBUTING.md` and `CODE_OF_CONDUCT.md`** added, and `SECURITY.md` routes vulnerability reports to `security@caseyjhand.com`.
|
|
23
|
+
- Framework skills, `scripts/`, and `changelog/template.md` re-synced to what mcp-ts-core 0.12.3 ships: `lint-mcp` drops the removed tasks surface, `lint-packaging` tracks the SDK package rename to `@modelcontextprotocol/server`, and `tree` honors directory-only gitignore patterns, so `.claude/` leaves `docs/tree.md`. `tsconfig.json` pins `tsBuildInfoFile` to keep the typecheck cache out of `dist/`, and `typescript` is no longer allowlisted in the `outdated` gate.
|
|
24
|
+
|
|
25
|
+
## Fixed
|
|
26
|
+
|
|
27
|
+
- **Input-validation failures read as flat `path: message` sentences** instead of a serialized `ZodIssue[]` blob, and a call to an unknown tool rejects with `-32602` rather than resolving an error result.
|
|
28
|
+
- **A failure after the handler returns is recorded as a failed call** — output-schema validation, `format()`, and the enrichment merge run inside the measured region, so they produce an ERROR span and an error counter rather than a success.
|
|
29
|
+
- **Stdin EOF runs the full shutdown path before exiting**, so a stdio server whose client hangs up no longer stays resident.
|
|
30
|
+
|
|
31
|
+
## Dependencies
|
|
32
|
+
|
|
33
|
+
- `@cyanheads/mcp-ts-core` `^0.11.0` → `^0.12.3` (nine framework releases; `0.12.0` is the MCP SDK v2 adoption)
|
|
34
|
+
- `@biomejs/biome` `^2.5.5` → `^2.5.10`
|
|
35
|
+
- `@types/node` `^26.1.2` → `^26.2.0`
|
|
36
|
+
- `tsc-alias` `^1.9.1` → `^1.9.2`
|
|
37
|
+
- `vitest` `^4.1.10` → `^4.1.11`
|
|
38
|
+
- `packageManager` `bun@1.3.14` → `bun@1.4.0` (`engines.bun` stays `>=1.3.0`)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Docker build stage now runs on the native platform, so a multi-arch build no longer crashes tsc under qemu on the amd64 leg."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.2.5 — 2026-08-25
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`Dockerfile` build stage runs `--platform=$BUILDPLATFORM`.** Bun 1.4.0 aborts under qemu, so the amd64 leg of a multi-arch build crashed in `tsc`; the compiled output is arch-independent, so building it natively and copying into the target stage is equivalent. This release re-tags and re-publishes 0.2.4's npm tarball with the fix applied, since `Dockerfile` ships in `package.json` `files` and the published 0.2.4 tarball carried the un-pinned version.
|
package/changelog/template.md
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
# to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
|
|
5
5
|
# with a concrete date.
|
|
6
6
|
|
|
7
|
-
# Required. One-line GitHub Release-style headline. 350 character cap
|
|
8
|
-
# Default short and scannable. Don't pad, don't stitch
|
|
9
|
-
#
|
|
10
|
-
#
|
|
7
|
+
# Required. One-line GitHub Release-style headline. 350 character cap — a
|
|
8
|
+
# ceiling, not a target. Default short and scannable. Don't pad, don't stitch
|
|
9
|
+
# unrelated changes with commas/semicolons into an inventory — pick the
|
|
10
|
+
# headline, like a tag's theme line. Quotes required: unquoted YAML treats
|
|
11
|
+
# `: ` inside the value as a key separator and fails GitHub's strict parser.
|
|
11
12
|
summary: ""
|
|
12
13
|
|
|
13
14
|
# Set `true` when consumers must change code to upgrade: API removals,
|
|
@@ -24,9 +25,10 @@ security: false
|
|
|
24
25
|
|
|
25
26
|
# Optional free-form notes for maintenance agents processing this release.
|
|
26
27
|
# Not rendered in CHANGELOG — consumed by agents running `maintenance` on
|
|
27
|
-
# downstream servers.
|
|
28
|
-
#
|
|
29
|
-
#
|
|
28
|
+
# downstream servers. ADOPTION STEPS ONLY — new files to create, fields to
|
|
29
|
+
# populate, one-time migration steps. Never a second rendering of the body:
|
|
30
|
+
# if a body bullet already says it, name the bullet's symbol instead of
|
|
31
|
+
# re-explaining. Omit the field entirely when there's nothing to say.
|
|
30
32
|
# agent-notes: |
|
|
31
33
|
# <instructions for downstream maintenance agents>
|
|
32
34
|
---
|
|
@@ -41,17 +43,54 @@ security: false
|
|
|
41
43
|
each bullet with the symbol or concept name in **bold** so they can skip
|
|
42
44
|
what's irrelevant and zoom in on what's not.
|
|
43
45
|
|
|
44
|
-
Tone: terse, fact-dense, not verbose.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
Tone: terse, fact-dense, not verbose. Bullet shape: **symbol** + what
|
|
47
|
+
changed + at most one consumer-facing caveat. One sentence by default, two
|
|
48
|
+
when the second carries weight — a bullet past ~40 words or three sentences
|
|
49
|
+
is wrong. The depth lives one hop away: the linked issue carries the why,
|
|
50
|
+
the commit diff carries the how. The changelog names what changed and what
|
|
51
|
+
a consumer does about it; a reader who wants mechanism opens the link.
|
|
52
|
+
|
|
53
|
+
Model length on THIS guide, never on the previous entry — entries modeled
|
|
54
|
+
on entries compound.
|
|
55
|
+
|
|
56
|
+
Cut (each has shipped as a wall of text; these are the cruft):
|
|
57
|
+
- History/justification narration — how the bug worked, why the old
|
|
58
|
+
behavior was wrong. One short clause at most; the issue carries the story.
|
|
59
|
+
- Design-rationale defense — "chosen over Y because…", "guarding the
|
|
60
|
+
getter is not enough…". That is the author arguing with a reviewer;
|
|
61
|
+
reviewers read the PR, not the changelog.
|
|
62
|
+
- Defensive unchanged-clauses — "X is unchanged", "byte-identical to
|
|
63
|
+
<prev>". Keep one only where its absence would cause a real misread,
|
|
64
|
+
as a short parenthetical.
|
|
65
|
+
- Edge-case inventories — marker lists, not-flagged lists, escape tables.
|
|
66
|
+
Tests and the issue carry those.
|
|
67
|
+
- Mechanism walkthroughs (JSDoc, CLAUDE.md/AGENTS.md, or the relevant
|
|
68
|
+
skill own those), ceremonial framings ("This release introduces…"),
|
|
69
|
+
backwards-compat paragraphs, file-by-file test enumerations. Prefer
|
|
70
|
+
code/symbol names over English re-explanations.
|
|
71
|
+
|
|
72
|
+
Verified ≠ included: the every-claim-verified-from-the-diff rule bounds
|
|
73
|
+
the TRUTH of what you write, never the AMOUNT.
|
|
74
|
+
|
|
75
|
+
Example — same fact, right size:
|
|
76
|
+
|
|
77
|
+
TOO LONG: **`fetchWithTimeout`'s `timeoutMs` bounds the whole exchange**
|
|
78
|
+
(#341). `fetch` resolves once headers arrive and the deadline was
|
|
79
|
+
cleared as the helper returned, so a peer that answered promptly and
|
|
80
|
+
then stalled the stream held the request open indefinitely. A 2xx
|
|
81
|
+
carrying a body now comes back as a passthrough wrapper that disarms
|
|
82
|
+
the deadline when the body closes, errors, or is cancelled; …
|
|
83
|
+
[+90 more words of mechanism and edge cases]
|
|
84
|
+
|
|
85
|
+
RIGHT: **`fetchWithTimeout`'s `timeoutMs` now bounds the whole
|
|
86
|
+
exchange, not just the headers** (#341). A stalled body aborts with
|
|
87
|
+
the same `Timeout` error; the returned `Response` is a wrapper, so
|
|
88
|
+
identity assertions (`toBe(response)`) no longer hold.
|
|
52
89
|
|
|
53
90
|
Narrative intro: skip by default. Add one short sentence only when the
|
|
54
|
-
release theme genuinely needs framing the bullets can't carry.
|
|
91
|
+
release theme genuinely needs framing the bullets can't carry. When many
|
|
92
|
+
bullets share one upgrade consequence, state it ONCE — intro line or
|
|
93
|
+
agent-notes — never per bullet.
|
|
55
94
|
|
|
56
95
|
Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
|
|
57
96
|
Fixed, Security. Include only sections with entries; delete the rest
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,12 @@ import { initTrafficApiService } from './services/traffic/traffic-service.js';
|
|
|
10
10
|
await createApp({
|
|
11
11
|
name: 'wsdot-mcp-server',
|
|
12
12
|
title: 'wsdot-mcp-server',
|
|
13
|
+
// The tool surface is fixed at build time, so a 2026-07-28 client may hold discovery
|
|
14
|
+
// results for a day. Nothing here is tenant- or caller-specific — hence `public`.
|
|
15
|
+
cacheHints: {
|
|
16
|
+
'tools/list': { ttlMs: 86_400_000, cacheScope: 'public' },
|
|
17
|
+
'server/discover': { ttlMs: 86_400_000, cacheScope: 'public' },
|
|
18
|
+
},
|
|
13
19
|
tools: [
|
|
14
20
|
getMountainPasses,
|
|
15
21
|
searchAlerts,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,kBAAkB;IACzB,KAAK,EAAE;QACL,iBAAiB;QACjB,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,cAAc;KACf;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,2aAA2a;IAC7a,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B,KAAK,CAAC,IAAI;QACR,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,kBAAkB;IACzB,qFAAqF;IACrF,kFAAkF;IAClF,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;QACzD,iBAAiB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC/D;IACD,KAAK,EAAE;QACL,iBAAiB;QACjB,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,cAAc;KACf;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,2aAA2a;IAC7a,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B,KAAK,CAAC,IAAI;QACR,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/wsdot-mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Query WA highway conditions, ferry schedules, vessel locations, toll rates, border waits, and alerts via MCP. STDIO or Streamable HTTP.",
|
|
5
5
|
"mcpName": "io.github.cyanheads/wsdot-mcp-server",
|
|
6
6
|
"type": "module",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"url": "https://github.com/cyanheads/wsdot-mcp-server/issues"
|
|
74
74
|
},
|
|
75
75
|
"license": "Apache-2.0",
|
|
76
|
-
"packageManager": "bun@1.
|
|
76
|
+
"packageManager": "bun@1.4.0",
|
|
77
77
|
"engines": {
|
|
78
78
|
"bun": ">=1.3.0",
|
|
79
79
|
"node": ">=24.0.0"
|
|
@@ -82,18 +82,18 @@
|
|
|
82
82
|
"access": "public"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@cyanheads/mcp-ts-core": "^0.
|
|
85
|
+
"@cyanheads/mcp-ts-core": "^0.12.3",
|
|
86
86
|
"pino-pretty": "^13.1.3",
|
|
87
87
|
"zod": "^4.4.3"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@biomejs/biome": "^2.5.
|
|
90
|
+
"@biomejs/biome": "^2.5.10",
|
|
91
91
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
92
|
-
"@types/node": "^26.
|
|
92
|
+
"@types/node": "^26.2.0",
|
|
93
93
|
"depcheck": "^1.4.7",
|
|
94
94
|
"ignore": "^7.0.6",
|
|
95
|
-
"tsc-alias": "^1.9.
|
|
95
|
+
"tsc-alias": "^1.9.2",
|
|
96
96
|
"typescript": "^7.0.2",
|
|
97
|
-
"vitest": "^4.1.
|
|
97
|
+
"vitest": "^4.1.11"
|
|
98
98
|
}
|
|
99
99
|
}
|
package/server.json
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"url": "https://wsdot.caseyjhand.com/mcp"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
|
-
"version": "0.2.
|
|
15
|
+
"version": "0.2.5",
|
|
16
16
|
"packages": [
|
|
17
17
|
{
|
|
18
18
|
"registryType": "npm",
|
|
19
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
20
20
|
"identifier": "@cyanheads/wsdot-mcp-server",
|
|
21
21
|
"runtimeHint": "node",
|
|
22
|
-
"version": "0.2.
|
|
22
|
+
"version": "0.2.5",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
55
55
|
"identifier": "@cyanheads/wsdot-mcp-server",
|
|
56
56
|
"runtimeHint": "node",
|
|
57
|
-
"version": "0.2.
|
|
57
|
+
"version": "0.2.5",
|
|
58
58
|
"packageArguments": [
|
|
59
59
|
{
|
|
60
60
|
"type": "positional",
|