Skip to content

feat(mcp): Add MCP server for Querybook#1698

Open
baumandm wants to merge 1 commit intopinterest:masterfrom
baumandm:external/mcp-server
Open

feat(mcp): Add MCP server for Querybook#1698
baumandm wants to merge 1 commit intopinterest:masterfrom
baumandm:external/mcp-server

Conversation

@baumandm
Copy link
Copy Markdown
Contributor

Adds a Model Context Protocol (MCP) server to Querybook, enabling AI agents to easily interact with Querybook programmatically. Built on FastMCP, the server runs as a standalone stateless HTTP service that can be horizontally scaled alongside the existing web, worker, and scheduler services.

The server is opt-in and has no impact on existing deployments. It runs as a separate container a separate port.

We've been using this server internally at Expedia for a while now with great success.

Usage

In Claude Code, something like this:

claude mcp add --scope user --transport http \
  querybook "https://querybook.expedia.biz/mcp" \
  --header "Authorization: Bearer <API_ACCESS_TOKEN>"

Implementation

It is designed to mirror Querybook's existing REST API surface, reusing the same foundational layers and sharing as much code as possible. There are a handful of deviations from the REST API, specifically to simplify things for AI agents to reduce API calls and token use.

Resources

The MCP server exposes both Tools and Resources:

  • Tools include actions, search, and mutations:
    • DataDocs: full CRUD for docs, cells (query/text/chart/python), editors, and template variables
    • Query Execution: run cells, execute ad-hoc queries, run full DataDocs, list executions with status/engine filters
    • Lists: CRUD for lists, items (data_doc/table/list/query types), and editors with permission control
    • Comments & Reactions: threaded comments on cells with emoji reactions
    • Schedules: cron-based DataDoc scheduling with notifications, retries, and result exports
    • Users: current user, batch lookup, search
    • Environments & Engines: discovery and enumeration
  • Resources are for read-only data retrieval, follow a querybook:// URI scheme, and are discoverable through tool responses
    • querybook://datadoc/{id}, datadoc-cell/{id}, query-execution/{id}, statement-execution/{id}/results, comment/{id}, schedule/{id}, list/{id}, environment/{id}, query-engine/{id}, user/{id}
    • Paginated sub-resources for cell executions, schedule runs, and cell comments
    • Static resource guide at querybook://resource-guide

Auth

Querybook's existing API token implementation is used here, with a QuerybookTokenVerifier that validates Bearer tokens. The authenticated user's identity flows through to all permission checks as expected.

Event Logging

Both tools and resources are wired up with the existing Event Log system, recording all actions with EventType.MCP, capturing timing, user, operation details, and status for audit purposes.

There is one Alembic migration to add this EventType to the schema.

Notes

  • Boards are called Lists in the UI, so we went with Lists in the MCP server so it would match the terminology our users would be familiar with. This is a spot where the REST API differs.

  • Some of the responses have been humanized compared to the REST API counterparts

  • Missing functionality:

    • Tables and related metadata: currently not included, as we have other data discovery tools that we didn't want to conflict with. We will probably add this soon due to the overwhelming demand for it.
    • Admin functionality is also not included currently (although it should be possible to expose different tools to different users based on the API Access Token roles)
    • Snippets are also omitted

Adds a Model Context Protocol (MCP) server that exposes Querybook's
core functionality as structured tools and resources, enabling AI
agents to easily interact with Querybook programmatically.

Tools (42):
- DataDocs: full CRUD for docs, cells (query/text/chart/python),
  editors, and template variables
- Query Execution: run cells, execute ad-hoc queries, run full
  DataDocs, list executions with status/engine filters
- Lists: CRUD for lists, items (data_doc/table/list/query types),
  and editors with permission control
- Comments & Reactions: threaded comments on cells with emoji reactions
- Schedules: cron-based DataDoc scheduling with notifications,
  retries, and result exports
- Users: current user, batch lookup, search
- Environments & Engines: discovery and enumeration

Resources (15 URI templates):
- querybook://datadoc/{id}, datadoc-cell/{id}, query-execution/{id},
  statement-execution/{id}/results, comment/{id}, schedule/{id},
  list/{id}, environment/{id}, query-engine/{id}, user/{id}
- Paginated sub-resources for cell executions, schedule runs, and
  cell comments
- Static resource guide at querybook://resource-guide

Infrastructure:
- Built with FastMCP 3.0
- Authentication with existing API token
- MCP event logging middleware for all tool and resource operations
- Docker Compose service and runservice integration
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.

1 participant