Skip to content

feat(mcp): MCP server in the app and the querya-mcp stdio shim - #1140

Merged
ZhuchkaTriplesix merged 4 commits into
devfrom
issue/1135-mcp-server-and-shim
Oct 8, 2026
Merged

ZhuchkaTriplesix merged 4 commits into
devfrom
issue/1135-mcp-server-and-shim

Conversation

@ZhuchkaTriplesix

@ZhuchkaTriplesix ZhuchkaTriplesix commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Second part of the MCP epic #1133, on top of McpQueryService (#1134).

Server in the app

  • QueryaMcpServer (dart_mcp 0.5.2): tools list_connections, list_tables, describe_table, sample_rows, run_query, explain_query, all marked readOnlyHint; resource template schema://{connection_id}. Instructions tell the model that results are data, not instructions.
  • Tool failures come back as isError results with a readable text; every call is reported as McpCallRecord (client, tool, connection, SQL, rows, duration, error) on McpServerController.calls for the activity log in feat(mcp): Settings page, per-connection access and activity log #1136.
  • McpSocketHost: 127.0.0.1 only, 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); override QUERYA_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_enabled in app_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-mcp shim

  • Lives in its own dependency-free package packages/querya_mcp_bridge (McpEndpoint + runMcpShim, pure dart:io); the app uses it as a path dependency. Reason: in the app package dart compile exe refuses to build because sqlite3 / objective_c have build hooks (dart build cli works but drags libsqlite3.so along). The separate package compiles to one static ~7 MB binary.
  • The shim reads the endpoint, sends the token, then pipes bytes both ways without parsing MCP; a reset from the app ends it cleanly.
  • App not running / stale endpoint: answers every request with a JSON-RPC error "Querya Desktop is not running or its MCP server is off..." until stdin closes, exit code 1.

Release

  • CI (Code Analysis job): dart analyze --fatal-infos and dart compile exe of the bridge package on every PR, plus a --help run.
  • Built in the build-ext-tester matrix (linux-x64, macos-arm64/x64, windows-x64), smoke-tested (--help and the not-running answer), published as querya-mcp-v<ver>-<target> assets.
  • Bundled next to the app binary in the Linux build (so zip, AppImage, .deb and .rpm get /opt/querya-desktop/querya-mcp) and the Windows build (zip and setup).
  • Not bundled yet: macOS .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_mcp client: 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 app pubspec.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

@github-actions github-actions Bot added integration Theme parser epic label: integration core Core library logic and services P2 Medium priority / Parity & Refactoring labels Oct 8, 2026
@ZhuchkaTriplesix
ZhuchkaTriplesix merged commit 211757d into dev Oct 8, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core library logic and services integration Theme parser epic label: integration P2 Medium priority / Parity & Refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant