---
summary: "Framework bump to 0.8.13 — gated tools stay visible in the operator manifest via disabledTool(), SQL gate function deny-list adopted from the framework, RequestContext slice swapped onto the framework's exported type."
breaking: false
---

# 0.4.11 — 2026-05-03

Maintenance pass on top of v0.4.10. The framework picked up three things this server was carrying locally — operator-visible disabled tools, the SQL function deny-list, and the request-context slice type — so they're swapped onto the upstream surface here. No tool surface, schema, or env-var changes for callers.

## Changed

- **Framework bump** — `@cyanheads/mcp-ts-core` `^0.8.10` → `^0.8.13`. Picks up `disabledTool()`, `SQL_GATE_REASONS` / `SqlGateReason` exports, the `DENIED_TABLE_FUNCTIONS` plus pre-EXPLAIN `assertNoDeniedFunctions` SQL-gate layer, and the `RequestContext` interface with the 0.8.12 strict-optional widening.
- **Gated tools stay in the operator manifest** — `src/index.ts` swaps the conditional spreads (`enableWrites ? writeToolDefinitions : []` and `canvasEnabled ? dataframeToolDefinitions : []`) for `disabledTool(d, { reason, hint })` wrappers from `@cyanheads/mcp-ts-core/tools`. Disabled tools are still skipped at registration so clients can't invoke them, but operators reading `/.well-known/mcp.json` and the HTML landing page see them with a one-line reason and an enable hint. Dataframe tools surface `Set BRAPI_CANVAS_ENABLED=true and CANVAS_PROVIDER_TYPE=duckdb to enable.`; the write surface surfaces `Set BRAPI_ENABLE_WRITES=true to enable observation submission.`. Registration-gate tests updated to assert the `__mcpDisabled` marker shape on the wrapped definition.
- **`brapi_dataframe_query` consumes the framework's gate-reason union** — `src/mcp-server/tools/definitions/brapi-dataframe-query.tool.ts` now imports `SQL_GATE_REASONS` and the `SqlGateReason` union from `@cyanheads/mcp-ts-core/canvas` instead of duplicating the strings locally. The `extractSqlGateReason` helper returns `SqlGateReason | undefined` so the `data.gateReason` payload stays in lockstep with the framework's gate. New gate codes (`denied_function`, `denied_function_in_plan`) flow through automatically.
- **`CanvasBridge.asRequestContext` uses the framework's `RequestContext` type** — `src/services/canvas-bridge/canvas-bridge.ts` drops the local `CanvasRequestContext` slice in favor of `RequestContext` imported from `@cyanheads/mcp-ts-core/utils`. The slice still has to be constructed explicitly because `RequestContext` carries an `[key: string]: unknown` index signature the strict `Context` interface lacks, so direct assignment fails despite the strict-optional widening — the construction shape is unchanged.

## Removed

- **Server-side `FORBIDDEN_SQL_FUNCTIONS` deny-list** — the regex-based pre-canvas guard for `read_json*` / `read_parquet*` / `parquet_scan` / `iceberg_scan` / `delta_scan` is removed from `src/services/canvas-bridge/canvas-bridge.ts` along with the eight unit tests that exercised it. The framework now ships a richer pre-EXPLAIN deny-list (`assertNoDeniedFunctions` + `DENIED_TABLE_FUNCTIONS`) plus a plan-walk rescan, so the local belt-and-suspenders is redundant. Disallowed function calls now surface as `denied_function` / `denied_function_in_plan` gate reasons instead of the previous `plan_operator_not_allowed` synthetic reason.
