Skip to content

feat(mcp): add MCP server plugin for natural language SQL queries on DevLake normalized schema#10

Open
irfanuddinahmad wants to merge 4 commits into
feature/hubspot-notion-pluginsfrom
feature/claude-connector
Open

feat(mcp): add MCP server plugin for natural language SQL queries on DevLake normalized schema#10
irfanuddinahmad wants to merge 4 commits into
feature/hubspot-notion-pluginsfrom
feature/claude-connector

Conversation

@irfanuddinahmad

Copy link
Copy Markdown
Collaborator

Summary

Adds a new DevLake backend plugin (backend/plugins/mcp/) that exposes a Model Context Protocol (MCP) server over Streamable HTTP. This enables AI assistants (Claude Code, Cursor, or any MCP-compatible client) to query DevLake's normalized domain data using natural language — the assistant discovers the schema, writes SQL, and executes it, all through the MCP tool protocol.

Architecture

MCP Client (Claude Code / IDE)
        │  JSON-RPC 2.0 over HTTP
        ▼
POST http://localhost:8080/api/plugins/mcp/mcp
        │
        ▼
  mcp plugin (PluginMeta + PluginInit + PluginApi)
        │
        ├── list_tables   → schema registry (embedded)
        ├── get_schema    → column details per table
        └── execute_query → RawCursor on DevLake DB (read-only)

The plugin follows the MCP Streamable HTTP stateless transport — each POST is a complete, self-contained JSON-RPC 2.0 exchange with no session state.

Plugin structure

backend/plugins/mcp/
├── mcp.go               # PluginEntry var (package main)
├── impl/
│   └── impl.go          # PluginMeta + PluginInit + PluginApi
└── api/
    ├── init.go          # Stores dal.Dal + log.Logger from basicRes
    └── mcp_handler.go   # MCP JSON-RPC dispatcher + 3 tools + schema registry

No new database tables, no migrations, no subtasks — this is a pure API plugin.

MCP Tools exposed

Tool Description
list_tables Lists all ~35 normalized domain tables grouped by domain (code, ticket, devops, crossdomain, codequality, ai). Accepts optional domain filter.
get_schema Returns column details for one or more requested tables from the embedded schema registry.
execute_query Executes a read-only SELECT (or WITH … SELECT) query against the DevLake database. Results capped at 500 rows.

Security

  • Only SELECT and WITH … SELECT statements are accepted; all DDL and DML keywords (INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, TRUNCATE, EXEC, etc.) are rejected.
  • A LIMIT 500 subquery wrapper is added automatically when no LIMIT clause is present.
  • []byte columns (MySQL text/blob) are converted to strings for clean JSON output.

Normalized schema coverage

The embedded schema registry covers all major domain layer tables:

  • code: repos, commits, pull_requests, pull_request_commits, pull_request_labels, pull_request_reviewers, refs, repo_commits, commit_files
  • ticket: issues, issue_labels, issue_changelogs, issue_worklogs, boards, sprints, sprint_issues, board_issues
  • devops: cicd_scopes, cicd_pipelines, cicd_tasks, cicd_deployment_commits, cicd_pipeline_commits, cicd_releases
  • crossdomain: users, accounts, teams, pull_request_issues, issue_commits, project_mapping
  • codequality: cq_projects, cq_issues, cq_file_metrics
  • ai: ai_activities

Usage

1. Build and enable the plugin

cd backend
make build
# or for the .so file directly:
go build -buildmode=plugin -o bin/plugins/mcp.so ./plugins/mcp/

2. Configure MCP client (Claude Code example)

Add to ~/.claude.json or project .mcp.json:

{
  "mcpServers": {
    "devlake": {
      "url": "http://localhost:8080/api/plugins/mcp/mcp"
    }
  }
}

Or via CLI:

claude mcp add devlake -s user -- http://localhost:8080/api/plugins/mcp/mcp

3. Example queries

Once connected, an AI assistant can answer questions like:

  • "What's our average PR cycle time this month?"
  • "Show deploy frequency by week for the last quarter"
  • "Which issues have been in-progress for more than 14 days?"
  • "What is our DORA lead time for change?"
  • "How many bugs were resolved vs opened each sprint?"

The assistant calls list_tablesget_schemaexecute_query automatically.

Test plan

  • go build ./plugins/mcp/... passes with no errors
  • go vet ./plugins/mcp/... passes clean
  • Start DevLake server; confirm POST /api/plugins/mcp/mcp with {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}} returns a valid initializeResult
  • tools/list returns all three tool definitions
  • tools/call with list_tables returns domain-grouped table list
  • tools/call with get_schema for pull_requests returns correct columns
  • tools/call with execute_query and a valid SELECT returns rows as JSON
  • execute_query with DROP TABLE issues is rejected with a clear error
  • execute_query without a LIMIT clause gets capped to 500 rows automatically
  • Connect Claude Code via MCP and ask a natural language metrics question end-to-end

🤖 Generated with Claude Code

…normalized schema

Adds a new DevLake plugin at backend/plugins/mcp/ that exposes an MCP
(Model Context Protocol) server over Streamable HTTP, allowing AI assistants
such as Claude Code to query DevLake's normalized domain data using natural
language.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@irfanuddinahmad
irfanuddinahmad changed the base branch from main to feature/hubspot-notion-plugins May 18, 2026 12:59
raza-bukhari and others added 3 commits May 20, 2026 02:57
- replace stale hard-coded schema registry with domain-model-driven schema discovery
- expose QA tables in MCP table listing
- harden read-only SQL validation and reject multiple statements
- add MCP plugin to plugin coverage test
- add focused handler tests
…ancements

fix(mcp): derive schema from domain models and harden MCP handler
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.

3 participants