Repository navigation
feat(mcp): MCP server in the app and the querya-mcp stdio shim - #1140
Merged
Merged
Conversation
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second part of the MCP epic #1133, on top of
McpQueryService(#1134).Server in the app
QueryaMcpServer(dart_mcp0.5.2): toolslist_connections,list_tables,describe_table,sample_rows,run_query,explain_query, all markedreadOnlyHint; resource templateschema://{connection_id}. Instructions tell the model that results are data, not instructions.isErrorresults with a readable text; every call is reported asMcpCallRecord(client, tool, connection, SQL, rows, duration, error) onMcpServerController.callsfor the activity log in feat(mcp): Settings page, per-connection access and activity log #1136.McpSocketHost:127.0.0.1only, random port. The first line of each connection must be the token (constant-time compare), otherwise a JSON-RPC error and the socket is closed; 5 s handshake timeout. Each client gets its own MCP session.McpEndpoint:{port, token, pid, version}in$XDG_RUNTIME_DIR/querya/mcp-endpoint.json(Linux, fallback~/.cache/querya),~/Library/Caches/Querya(macOS),%LOCALAPPDATA%\Querya(Windows); overrideQUERYA_MCP_ENDPOINT. Written atomically, directory 0700, file 0600; deleted on stop. Kept outside the profile dir so the shim does not need the portable-mode logic.McpServerController: off by default (mcp_server_enabledinapp_settings), started at launch when enabled, stopped before the pools close on app exit (AppLifecycleCleanup). Not tied to "Disconnect all", which must not kill the MCP server.querya-mcpshimpackages/querya_mcp_bridge(McpEndpoint+runMcpShim, puredart:io); the app uses it as a path dependency. Reason: in the app packagedart compile exerefuses to build becausesqlite3/objective_chave build hooks (dart build cliworks but dragslibsqlite3.soalong). The separate package compiles to one static ~7 MB binary.Release
Code Analysisjob):dart analyze --fatal-infosanddart compile exeof the bridge package on every PR, plus a--helprun.build-ext-testermatrix (linux-x64, macos-arm64/x64, windows-x64), smoke-tested (--helpand the not-running answer), published asquerya-mcp-v<ver>-<target>assets./opt/querya-desktop/querya-mcp) and the Windows build (zip and setup)..app(needs codesigning of a second binary) and Flatpak (sandboxed runtime dir); both get the standalone asset for now.Tests (
test/core/mcp/mcp_server_test.dart)Real sockets, the real shim function and a
dart_mcpclient: initialize, tool list and annotations, calls incl. a refused write and a missing argument, the schema resource, call records, client count; endpoint permissions and removal on stop; wrong token refused; shim without the app; stopping the server disconnects a live client.Also:
publish_to: 'none'in the apppubspec.yaml(needed for the path dependency; the app is never published).Settings UI (enable toggle, per-connection access, copy-config) is #1136.
Written without running locally; CI is the first run.
Closes #1135