Skip to content

Add MCP server endpoint at /-/mcp - #168

Open
simonw wants to merge 4 commits into
mainfrom
claude/mcp-integration-datasette-5atl75
Open

Add MCP server endpoint at /-/mcp#168
simonw wants to merge 4 commits into
mainfrom
claude/mcp-integration-datasette-5atl75

Conversation

@simonw

@simonw simonw commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Implements a Model Context Protocol server for the dashboard, inspired
by https://github.com/datasette/datasette-mcp - so LLM tools can explore
the database and answer questions with read-only SQL.

  • New dependency-free stateless MCP Streamable HTTP endpoint (JSON
    responses) served at -/mcp under the dashboard URLs
  • Three read-only tools: list_tables, get_schema and execute_sql, with
    input/output schemas and readOnlyHint annotations
  • Requires an authenticated user with the execute_sql permission, and
    runs SQL through the same protected pattern as the dashboard views:
    dashboard database alias, rolled-back transaction, single statement
    only, DASHBOARD_ROW_LIMIT truncation and %(name)s parameter support
  • Documentation in docs/mcp.md
  • conftest.py now lets tests declare their own django_db marker, used
    by new transactional tests that verify read-only enforcement

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_017ZRFpnuD9tZKWb19Ffg8iF

claude added 4 commits August 1, 2026 02:14
Implements a Model Context Protocol server for the dashboard, inspired
by https://github.com/datasette/datasette-mcp - so LLM tools can explore
the database and answer questions with read-only SQL.

- New dependency-free stateless MCP Streamable HTTP endpoint (JSON
  responses) served at -/mcp under the dashboard URLs
- Three read-only tools: list_tables, get_schema and execute_sql, with
  input/output schemas and readOnlyHint annotations
- Requires an authenticated user with the execute_sql permission, and
  runs SQL through the same protected pattern as the dashboard views:
  dashboard database alias, rolled-back transaction, single statement
  only, DASHBOARD_ROW_LIMIT truncation and %(name)s parameter support
- Documentation in docs/mcp.md
- conftest.py now lets tests declare their own django_db marker, used
  by new transactional tests that verify read-only enforcement

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZRFpnuD9tZKWb19Ffg8iF
Headless MCP clients cannot easily obtain a Django session cookie. The
new optional DASHBOARD_MCP_TOKENS setting maps secret tokens to
usernames, letting clients authenticate to the /-/mcp endpoint with an
Authorization: Bearer header.

- Tokens are compared with secrets.compare_digest, resolved with
  get_by_natural_key so custom user models work, and rejected for
  missing or inactive users
- The mapped user must still hold the execute_sql permission
- A request carrying a Bearer header never falls back to session auth
- Documented in docs/mcp.md and the settings list in docs/setup.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZRFpnuD9tZKWb19Ffg8iF
Two new MCP tools that follow saved dashboard view policies instead of
requiring the execute_sql permission:

- list_dashboards returns the dashboards the current user can view.
  Unlisted dashboards are excluded, matching the dashboard index page.
- execute_dashboard runs every query saved on a dashboard by slug and
  returns per-query results or errors, with %(name)s parameter support.
  Unlisted dashboards work for anyone who knows the slug; dashboards
  that are missing or not visible produce the same error so private
  slugs are not disclosed.

This makes the MCP endpoint useful to anonymous clients with no
credentials at all: they can list and execute public dashboards. The
SQL tools (list_tables, get_schema, execute_sql) still require the
execute_sql permission, now enforced per tool call, and tools/list
only advertises the tools the current user is allowed to use.

The dashboard view policy logic is extracted from the dashboard view
into a new Dashboard.user_can_view() model method shared by both the
web view and the MCP tools.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZRFpnuD9tZKWb19Ffg8iF
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZRFpnuD9tZKWb19Ffg8iF
simonw added a commit to simonw/simonwillisonblog that referenced this pull request Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants