Skip to content

wsdot mcp server changelog

io.github.cyanheads/wsdot-mcp-server

8 changes recorded. MCP Harbor re-reads this listing from the official registry every six hours and asks the live server what it exposes, and keeps what changed between one look and the next.

  • Tools +1
    • + wsdot_get_ferry_fares
  • server.json 3 fields changed
    description
    WA highway conditions, ferry schedules, vessel locations, toll rates, and border waits via MCP. WA highway conditions, ferry schedules and fares, vessel locations, tolls, and border waits via MCP.
    env_vars
    WSDOT_ACCESS_CODE, MCP_LOG_LEVEL WSDOT_ACCESS_CODE, WSDOT_CLAMP_LIMITS, MCP_LOG_LEVEL
    version
    0.5.0 0.6.0

  • AGENTS.md +12 −8

    https://raw.githubusercontent.com/cyanheads/wsdot-mcp-server/HEAD/AGENTS.md

    − **Version:** 0.4.1− **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.14`− **MCP SDK:** `@modelcontextprotocol/server` ^2.2.0 (protocol revisions 2026-07-28 and 2025-*)− **Zod:** ^4.6.5− throw new McpError(JsonRpcErrorCode.DatabaseError, 'Connection failed', { pool: 'primary' });− Skills are modular instructions in `framework-skills/` at the project root. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. The directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand these development skills to every agent that installs it. Keep `skills/` free for skills meant f− | `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |− `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was + **Version:** 0.5.0+ **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.18`+ **MCP SDK:** `@modelcontextprotocol/server` ^2.4.0 (protocol revisions 2026-07-28 and 2025-*)+ **Zod:** ^4.6.7+ throw new McpError(JsonRpcErrorCode.InitializationFailed, 'Connection failed', { pool: 'primary' });+ Development skills live in `framework-skills/`; read the matching skill before working, and use `bun run list-skills` for the registry. Root `skills/` is the published tree for agents calling this server. `skills/wsdot-guide/SKILL.md` guides ferry trip decisions across schedules, alerts, space, and vessel positions. It ships in plugin installs, npm, Docker, and MCPB, and `createApp({ skills: 'skills' })` serves it over MCP. `lint:packaging` validates the tree. Maintenance syncs development skill+ | `add-skill` | Author a published skill in root `skills/` for agents calling the server — gates, workflows, validation, delivery |+ | `bun run lint:packaging` | Packaging checks — env-var parity, bundle exclusions, plugin manifests, and published skills (run by devcheck) |+ `mcpb pack` reads `.mcpbignore`, not `.gitignore`. Keep exclusions root-anchored so `/docs/` excludes project docs without dropping dependency docs; root `skills/` must ship. The cleaner also strips node-gyp build output and framework build-only files from dependencies. Rebuild an older bundle after a framework update; `lint:packaging` checks its contents.+ `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`), platform-specific native bindings, node-gyp build output, and build-only package files from `node_modules/**`. Root-anchored `.mcpbignore` patterns cannot reach these dependency paths. MCPB is std+ - [ ] Root `plugin.json` and `mcp.json` use the Agent Plugins 1.0.0 schemas, the unscoped server name, and full npm install name. Root env contains fixed values only; user credentials stay in the client overlays. Keep `.codex-plugin/plugin.json`'s `mcpServers` pointer so Codex forwards `env_vars`.+ - [ ] Published `skills/wsdot-guide/SKILL.md` passes `lint:packaging`; live field testing verifies its gates and identifier claims, plus `resources/list` and the `skill://` read

  • Resources +1
    • + wsdot-guide

  • server.json 1 field changed
    version
    0.4.2 0.5.0

  • server.json 1 field changed
    version
    0.4.1 0.4.2

  • AGENTS.md +10 −9

    https://raw.githubusercontent.com/cyanheads/wsdot-mcp-server/HEAD/AGENTS.md

    − **Version:** 0.4.0− **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.6`− **MCP SDK:** `@modelcontextprotocol/server` ^2.0.0 (protocol revisions 2026-07-28 and 2025-*)− | `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.getMany(keys)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |− | `ctx.inputs` | Reader over a retried request's responses — `.accepted(key, schema)`, `.view(key)`, `.state()`, `.dropped`. Empty on the first round. |− | `ctx.requestId` | Unique request ID. |− **Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable?, severity?, thrownBy? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. Pass `ctx.recoveryFor('reaso−   if (!item) throw ctx.fail('no_match', `No item ${input.id}`, ctx.recoveryFor('no_match'));− **Every release goes through a release PR, straight-through** — `git-wrapup`'s "Release PR mode", mode `straight-through`. One run: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the changelog entry plus a gates section); `release-and-publish` then fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the branch, and publishes. A caller's bri+ **Version:** 0.4.1+ **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.14`+ **MCP SDK:** `@modelcontextprotocol/server` ^2.2.0 (protocol revisions 2026-07-28 and 2025-*)+ | `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.getMany(keys)`, `.list(prefix, { cursor, limit })`. Accepts any JSON-serializable value; reads return its JSON form (a `Date` comes back as an ISO string). |+ | `ctx.inputs` | The request's responses — `.accepted(key, schema)`, `.view(key)`, `.state()`, `.dropped` — limited to what the client declared (`elicitation` and its form/url modes, `sampling`, `roots`). Client-supplied: a consent gate trusts only a `ctx.state` record it stored when it asked, bound to the operation, caller, and target (see the `api-context` skill). |+ | `ctx.clientCapabilities` | What the client declared for this request, `undefined` when no view exists. Decides whether to ask for optional context (e.g. roots); never a reason to skip a consent prompt. |+ | `ctx.requestId` | Request ID — the one every log record of the call carries and its error envelope returns as `data.requestId`. |+ **Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable?, severity?, thrownBy? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. The framework puts it on the+   if (!item) throw ctx.fail('no_match', `No item ${input.id}`);+ **Every release goes through a release PR, straight-through** — `git-wrapup`'s "Release PR mode", mode `straight-through`. One run: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the release digest: theme line, `## Changes`, `## Gates`, changelog link last); `release-and-publish` then fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the 
  • server.json 1 field changed
    version
    0.4.0 0.4.1