Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
882586b
Add layout traversal utilities for Dash component trees
KoolADE85 Apr 1, 2026
4d55ef8
Make Dash components compatible with Pydantic types
KoolADE85 Apr 1, 2026
998d8d7
Extract get_layout() from serve_layout()
KoolADE85 Apr 1, 2026
66eda33
Fix build issues for dash-table and dash-core-components
KoolADE85 Apr 1, 2026
0cdb67a
Add CallbackDispatchBody type hints to dispatch methods
KoolADE85 Apr 1, 2026
b64c3fe
Use python3.8 compatible pydantic
KoolADE85 Apr 1, 2026
a85aa6c
lint
KoolADE85 Apr 1, 2026
4ecaf7d
Fix lint error on CI
KoolADE85 Apr 1, 2026
069b049
Rename layout.py to _layout_utils.py
KoolADE85 Apr 6, 2026
d684507
Make NumberType import backwards-compatible in generated components
KoolADE85 Apr 6, 2026
17a7541
Fix type checker for NumberType implementation
KoolADE85 Apr 6, 2026
dc35bff
Clean up import for pyright
KoolADE85 Apr 7, 2026
00eb203
Add callback adapter core for MCP tool generation
KoolADE85 Apr 1, 2026
fcfa765
Fix type errors
KoolADE85 Apr 1, 2026
8c89d51
Fix import path
KoolADE85 Apr 6, 2026
eeadb7f
tighten up types used around callbacks
KoolADE85 Apr 13, 2026
5b09f99
Remove redundant error code
KoolADE85 Apr 13, 2026
fa99ab0
lint
KoolADE85 Apr 14, 2026
cd1f4d4
Add MCP resource providers for layout, components, pages, and clients…
KoolADE85 Apr 1, 2026
2f00c0e
Fix import path
KoolADE85 Apr 6, 2026
5e472b2
Implement base class for each resource type
KoolADE85 Apr 13, 2026
f8d9739
lint
KoolADE85 Apr 16, 2026
6d4e2a0
Fix pylint errors
KoolADE85 Apr 22, 2026
ef1ea3f
Implement callbacks as tools with rich input/output schema and descri…
KoolADE85 Apr 1, 2026
9060647
Refactor description sources to accept CallbackAdapter instances
KoolADE85 Apr 8, 2026
554ddc0
Fix pylint error
KoolADE85 Apr 8, 2026
2cfa193
Fix regression in CallbackAdapter
KoolADE85 Apr 16, 2026
dce8e9a
Refactor tool descriptions/schemas to use a base class (just as resou…
KoolADE85 Apr 16, 2026
e29cb9c
Disable docstrings by default in MCP tool descriptions
KoolADE85 Apr 21, 2026
991dfa5
lint
KoolADE85 Apr 22, 2026
4d7411c
Move all hard-coded text into a `prop_roles.py` file where it can be …
KoolADE85 Apr 24, 2026
b357495
Add pattern-matching callback support to input schemas and descriptions
KoolADE85 Apr 1, 2026
6906b3d
clean up duplicated code
KoolADE85 Apr 16, 2026
6a52dba
Refactor unit tests to conform to existing test patterns
KoolADE85 Apr 23, 2026
7ce9939
Add result formatters for Plotly figures and tabular data
KoolADE85 Apr 1, 2026
acf75a0
Update type names
KoolADE85 Apr 16, 2026
d01d43a
Refactor tool result formatters to use a base class (just as resource…
KoolADE85 Apr 16, 2026
92cf27b
lint
KoolADE85 Apr 16, 2026
13d0fbf
Make import top-level
KoolADE85 Apr 22, 2026
ef8fc34
Refactor unit tests to conform to existing test patterns
KoolADE85 Apr 23, 2026
88589cb
Use TABULAR/PLOTLY_FIGURE PropRole.matches() in formatters
KoolADE85 Apr 30, 2026
55f6514
Tighten formatter types: required-field access + plotly stub ignore
KoolADE85 Apr 30, 2026
0be83d3
code review feedback
KoolADE85 May 8, 2026
bcc86c8
Add get_dash_component tool and callback tool dispatch pipeline
KoolADE85 Apr 1, 2026
a95b3bf
Refactor tools to use a base class (just as resources do)
KoolADE85 Apr 16, 2026
9e4cc2c
lint
KoolADE85 Apr 16, 2026
c079065
Refactor unit tests to conform to existing test patterns
KoolADE85 Apr 23, 2026
9988753
Implement a mapping of "id+prop" to callbacks that are outputs/inputs…
KoolADE85 May 8, 2026
c2f06ae
Code review feedback
KoolADE85 May 8, 2026
34a4d98
Make run_callback compatible with 4.2.0 changes
KoolADE85 May 12, 2026
227eeed
Wire MCP server, SSE transport, and Dash app integration
KoolADE85 Apr 1, 2026
001a7b7
Enforce session management per MCP spec (404 for unknown sessions, 40…
KoolADE85 Apr 9, 2026
3fe035b
remove unused code
KoolADE85 Apr 15, 2026
3b44944
Fix types for mypy
KoolADE85 Apr 17, 2026
9dc1f10
Remove unused SSE code for initial MCP implementation
KoolADE85 Apr 20, 2026
f640328
add app-level config for exposing callback docstrings in MCP tools
KoolADE85 Apr 21, 2026
d108faf
Disable MCP server by default
KoolADE85 Apr 21, 2026
eb94e14
lint
KoolADE85 Apr 22, 2026
fdaf822
fix leaky state in tests
KoolADE85 Apr 23, 2026
bfc61f2
Refactor unit tests to conform to existing test patterns
KoolADE85 Apr 23, 2026
8c7d720
Add decorator to make any function mcp-enabled
KoolADE85 May 4, 2026
4f7329c
Notify connected agents of server restarts and hot-reloads so they ca…
KoolADE85 May 8, 2026
cf8e9d9
Migrate MCP server to use v4.2.0 backend abstractions
KoolADE85 May 13, 2026
6c3fec8
Fix async (Quart) route registration
KoolADE85 May 13, 2026
5e47755
Fix session management with multiple workers
KoolADE85 May 13, 2026
9566de0
Fix CI errors after rebase
KoolADE85 May 13, 2026
296b7ac
code review feedback
KoolADE85 May 14, 2026
15f2111
Implement background callback support
KoolADE85 Apr 8, 2026
ee4e48c
Ensure that background callback expiry is communicated in MCP tool
KoolADE85 Apr 8, 2026
bf442f7
lint
KoolADE85 Apr 30, 2026
576145c
Install diskcache extra in lint-unit and typing CI jobs
KoolADE85 May 8, 2026
0fef9b8
Fix mypy errors in CI
KoolADE85 May 8, 2026
fd8c8d9
Fix bug storing metadata on background callbacks
KoolADE85 May 12, 2026
3cc14d8
Enable programmatic querying of background callback status/result; re…
KoolADE85 May 13, 2026
9d5fa61
Fix get_task status race and CallbackExecutionResponse type annotation
robertclaus May 15, 2026
ef778a2
code review feedback
KoolADE85 May 19, 2026
b78fe2a
Revert match/case refactor due to compatibility problems
KoolADE85 May 20, 2026
16da30a
automatically load env vars with direnv
KoolADE85 May 20, 2026
1861302
bump version and changelog
KoolADE85 May 21, 2026
3558bd3
changelog
KoolADE85 May 21, 2026
3aed371
Merge pull request #3793 from plotly/release/4.3.0rc0
KoolADE85 May 21, 2026
f1ec286
Merge remote-tracking branch 'origin/dev' into mcp
KoolADE85 Jun 2, 2026
24a7b66
fix fastapi middleware swallowing user routes bodies
T4rk1n Jun 2, 2026
1297eb1
update changelog
T4rk1n Jun 2, 2026
678bb66
Fix DataTable conditional style typing
May 21, 2026
d04009c
Implement configuration function to customize MCP server
KoolADE85 May 26, 2026
17f67ec
Fix CI test
KoolADE85 Jun 1, 2026
52b2858
Fix @mcp_enabled decorator not working if defined after the app const…
KoolADE85 Jun 1, 2026
c5c4829
Address PR feedback
KoolADE85 Jun 3, 2026
28fd89d
Merge pull request #3796 from plotly/feature/mcp-configuration-function
KoolADE85 Jun 3, 2026
6b2de3f
improved path check
T4rk1n Jun 3, 2026
aa35e38
Merge pull request #3805 from plotly/fix/fastapi-middleware
T4rk1n Jun 3, 2026
63e61d1
Merge remote-tracking branch 'origin/dev' into mcp
KoolADE85 Jun 3, 2026
91c3710
Merge branch 'dev' into fix-datatable-conditional-style-types
T4rk1n Jun 3, 2026
578c313
Merge pull request #3792 from puneetdixit200/fix-datatable-conditiona…
T4rk1n Jun 4, 2026
4028449
Fix incorrect websocket pathname
KoolADE85 Jun 11, 2026
f525dd3
Fix background callback context serialisation for non-dict request args
imurraywano Jun 14, 2026
a17382d
Add regression tests for background callback args serialisation
imurraywano Jun 14, 2026
e39f3fc
Add CHANGELOG entry for background callback args serialisation fix (#…
imurraywano Jun 14, 2026
ffd8e96
Merge pull request #3813 from plotly/bugfix/websockets-behind-proxy
T4rk1n Jun 17, 2026
0966b07
Merge branch 'dev' into mcp
KoolADE85 Jun 17, 2026
48adf42
Merge branch 'dev' into fix/background-callback-queryparams-serialisa…
T4rk1n Jun 18, 2026
f4ff5cf
fix dependabot report
T4rk1n Jun 18, 2026
a8e3b55
fix percy
T4rk1n Jun 18, 2026
b14961f
Fix claude code connectivity timeouts
KoolADE85 Jun 18, 2026
664efdd
attempt fix on table test
KoolADE85 Jun 18, 2026
37432d3
try fix percy
T4rk1n Jun 18, 2026
c793778
changelog
KoolADE85 Jun 18, 2026
b39255a
Merge remote-tracking branch 'origin/mcp' into bugfix/claude-mcp-time…
KoolADE85 Jun 18, 2026
8c4b5e6
Merge pull request #3817 from i-murray/fix/background-callback-queryp…
T4rk1n Jun 18, 2026
ce08226
Merge branch 'dev' into fix-dependabot-report
T4rk1n Jun 18, 2026
f62582c
Merge pull request #3830 from plotly/bugfix/claude-mcp-timeouts
KoolADE85 Jun 18, 2026
bcf0960
Merge pull request #3829 from plotly/fix-dependabot-report
KoolADE85 Jun 18, 2026
ff4d66d
Merge remote-tracking branch 'origin/dev' into mcp
KoolADE85 Jun 18, 2026
7fe7a32
Fix failing mcp test
KoolADE85 Jun 18, 2026
27b8c45
Merge pull request #3807 from plotly/mcp
KoolADE85 Jun 18, 2026
adb6bb2
bump version
KoolADE85 Jun 18, 2026
16e09f2
Version bump of component suites
KoolADE85 Jun 18, 2026
86d02b4
Merge pull request #3831 from plotly/release/4.3.0
KoolADE85 Jun 18, 2026
0c89b98
Merge branch 'dev' into master-4.3.0
KoolADE85 Jun 18, 2026
b3babe4
build artifacts
KoolADE85 Jun 18, 2026
904e5ed
ci: skip Typing Tests on PRs targeting master
KoolADE85 Jun 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ for venv_dir in .venv .env venv env .venv* env* ENV; do
break
fi
done

# Include optional, local-only environment overrides
if [ -f .env ]; then
dotenv
fi
18 changes: 17 additions & 1 deletion .github/actions/percy-exec/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ inputs:
description: 'Working directory for the command'
required: false
default: '.'
browser-executable:
description: 'Path to a Chrome/Chromium binary for Percy to use. Defaults to the one found on PATH.'
required: false
default: ''

runs:
using: 'composite'
Expand All @@ -23,7 +27,19 @@ runs:
working-directory: ${{ inputs.working-directory }}
env:
PERCY_TOKEN: ${{ inputs.percy-token }}
run: npx percy exec -- ${{ inputs.command }}
PERCY_BROWSER_EXECUTABLE: ${{ inputs.browser-executable }}
run: |
# Percy otherwise downloads its own Chromium from storage.googleapis.com
# on the first snapshot. That download stalls in CI, which blocks the
# synchronous percy_snapshot() calls (so pytest never finishes and writes
# no JUnit) and leaves an empty Percy build with no snapshots. Point Percy
# at the Chrome already installed in the job so it skips the download.
if [ -z "${PERCY_BROWSER_EXECUTABLE:-}" ]; then
PERCY_BROWSER_EXECUTABLE="$(command -v google-chrome || command -v google-chrome-stable || command -v chrome || command -v chromium || command -v chromium-browser || true)"
export PERCY_BROWSER_EXECUTABLE
fi
echo "PERCY_BROWSER_EXECUTABLE=${PERCY_BROWSER_EXECUTABLE:-<unset: Percy will download Chromium>}"
npx percy exec -- ${{ inputs.command }}

- name: Run without Percy (fork PR)
if: inputs.percy-token == ''
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/post-test-status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ jobs:
test-report:
name: Consolidated Test Report (Fork PR)
runs-on: ubuntu-latest
# Only run for fork PRs (non-fork PRs are handled in the main workflow)
# Run for fork PRs and Dependabot PRs. Both run with a read-only
# GITHUB_TOKEN in the main workflow, so the check run is created here in the
# base-repo context instead. Other same-repo PRs are handled in the main workflow.
if: |
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name != github.repository
(github.event.workflow_run.head_repository.full_name != github.repository ||
github.event.workflow_run.actor.login == 'dependabot[bot]')
permissions:
checks: write
actions: read
Expand Down
53 changes: 48 additions & 5 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
run: |
python -m pip install --upgrade pip wheel
python -m pip install "setuptools<80.0.0"
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[dev,ci,testing]"' \;
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[dev,ci,testing,diskcache]"' \;

- name: Install dash-renderer dependencies
working-directory: dash/dash-renderer
Expand All @@ -122,6 +122,8 @@ jobs:
echo "DISPLAY=:99" >> $GITHUB_ENV

- name: Run lint
env:
PYLINT_EXTRA_ARGS: ${{ matrix.python-version == '3.8' && '--ignored-modules=mcp' || '' }}
run: npm run lint

- name: Run unit tests
Expand Down Expand Up @@ -193,7 +195,7 @@ jobs:
test-typing:
name: Typing Tests
runs-on: ubuntu-latest
if: github.ref_name != 'master'
if: github.ref_name != 'master' && github.base_ref != 'master'
needs: build
timeout-minutes: 30
strategy:
Expand Down Expand Up @@ -229,7 +231,7 @@ jobs:
run: |
python -m pip install --upgrade pip wheel
python -m pip install "setuptools<80.0.0"
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev]"' \;
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev,diskcache]"' \;

- name: Build/Setup test components
run: npm run setup-tests.py # TODO build the packages and save them to packages/ in build job
Expand Down Expand Up @@ -620,6 +622,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -654,6 +664,7 @@ jobs:
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev,celery,diskcache]"' \;

- name: Setup Chrome and ChromeDriver
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
Expand All @@ -678,6 +689,7 @@ jobs:
with:
command: pytest --headless --nopercyfinalize --junitxml=test-reports/junit_intg.xml tests/integration --splits 3 --group ${{ matrix.test-group }}
percy-token: ${{ secrets.PERCY_TOKEN }}
browser-executable: ${{ steps.setup-chrome.outputs.chrome-path }}

- name: Upload test results
if: always()
Expand Down Expand Up @@ -713,6 +725,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -747,6 +767,7 @@ jobs:
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev]"' \;

- name: Setup Chrome and ChromeDriver
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
Expand All @@ -773,6 +794,7 @@ jobs:
with:
command: pytest --headless --nopercyfinalize --junitxml=test-reports/junit_html.xml
percy-token: ${{ secrets.PERCY_TOKEN }}
browser-executable: ${{ steps.setup-chrome.outputs.chrome-path }}
working-directory: components/dash-html-components

- name: Upload test results
Expand Down Expand Up @@ -899,6 +921,14 @@ jobs:
PERCY_TOKEN: ${{ matrix.python-version == '3.12' && secrets.PERCY_TOKEN || '' }}
PERCY_ENABLE: ${{ matrix.python-version == '3.12' && '1' || '0' }}
PERCY_PARALLEL_TOTAL: -1
# Pin the build identity so every shard joins the same parallel build and
# Percy links it to the PR. Auto-detection otherwise uses the ephemeral
# merge SHA (refs/pull/N/merge), so the build never shows up on the PR.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -1016,6 +1046,7 @@ jobs:
find packages -name dash-*.whl -print -exec sh -c 'pip install "{}[ci,testing,dev]"' \;

- name: Setup Chrome and ChromeDriver
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
Expand All @@ -1034,6 +1065,10 @@ jobs:
- name: Run Table visual tests
if: env.PERCY_TOKEN != ''
working-directory: components/dash-table
# percy-storybook bundles an old puppeteer whose Chromium is absent on
# the runner; point it at the system Chrome installed above.
env:
PUPPETEER_EXECUTABLE_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}
run: npm run test.visual

- name: Skip Table visual tests (fork PR)
Expand All @@ -1056,6 +1091,13 @@ jobs:
if: always()
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
# Must match the snapshot jobs so finalize targets the same parallel build
# and the result is attached to the PR head commit, not the merge SHA.
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
PERCY_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
PERCY_TARGET_BRANCH: ${{ github.base_ref }}
steps:
- name: Finalize Main Percy Build
if: |
Expand Down Expand Up @@ -1093,8 +1135,9 @@ jobs:

- name: Publish Test Report
uses: dorny/test-reporter@v1
# Skip for fork PRs - handled by post-test-status.yml workflow_run
if: always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
# Skip for fork PRs and Dependabot PRs - both run with a read-only
# GITHUB_TOKEN, so they're handled by post-test-status.yml workflow_run.
if: always() && (github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'))
with:
name: Test Results Summary
path: 'test-results/**/*.xml'
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ max-returns=6
max-statements=50

# Minimum number of public methods for a class (see R0903).
min-public-methods=2
min-public-methods=1


[IMPORTS]
Expand Down
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,32 @@
All notable changes to `dash` will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).

## [UNRELEASED]
## [4.3.0] - 2026-06-18

## Added
- [#3796](https://github.com/plotly/dash/pull/3796) MCP: Add `configure_mcp_server()` to toggle which content the MCP server exposes (`include_layout`, `include_callbacks`, `include_clientside_callbacks`, `include_pages`, `expose_callback_docstrings`). Only the parameters explicitly passed are updated; omitted parameters retain their current value.

## Changed
- [#3796](https://github.com/plotly/dash/pull/3796) MCP: Remove the `mcp_expose_docstrings` `Dash()` constructor argument; callback docstring exposure is now controlled via `configure_mcp_server(expose_callback_docstrings=...)`.

## Fixed
- [#3817](https://github.com/plotly/dash/pull/3817) Fix background callback context serialisation for non-dict request args on the FastAPI and Quart backends. Fixes [#3816](https://github.com/plotly/dash/issues/3816).
- [#3805](https://github.com/plotly/dash/pull/3805) Fix FastAPI POST routes deadlock caused by middleware consuming request body. Fixes [#3801](https://github.com/plotly/dash/issues/3801).
- [#3813](https://github.com/plotly/dash/pull/3813) Fix websockets using incorrect path when deployed behind a proxy
- [#3830](https://github.com/plotly/dash/pull/3830) MCP: Respond to the Streamable HTTP `GET` (SSE) request with an empty event stream instead of `405 Method Not Allowed`

## [4.3.0rc0] - 2026-05-21

## Added
- [#3710](https://github.com/plotly/dash/pull/3710) MCP: Framework utilities, types for interacting with layout
- [#3711](https://github.com/plotly/dash/pull/3711) MCP: `CallbackAdapter` for representing callback-related data in MCP-friendly format
- [#3712](https://github.com/plotly/dash/pull/3712) MCP: `Resources` for exposing app layout, components, and pages
- [#3731](https://github.com/plotly/dash/pull/3731) MCP: Expose callbacks as `Tools`
- [#3747](https://github.com/plotly/dash/pull/3747) MCP: Support pattern-matching callbacks in Tools
- [#3748](https://github.com/plotly/dash/pull/3748) MCP: Format callback results for LLM consumption (rendered graphs, markdown tables)
- [#3749](https://github.com/plotly/dash/pull/3749) MCP: `get_dash_component` Tool and callback execution
- [#3750](https://github.com/plotly/dash/pull/3750) MCP: Server routes, `mcp_enabled` function decorator, and Streamable HTTP transport
- [#3766](https://github.com/plotly/dash/pull/3766) MCP: Support background callbacks in Tools

## [4.2.0] - 2026-06-01 - *The Freedom Update*

Expand Down
Loading
Loading