Skip to content

feat: reimplement MCP connection for Electron#945

Open
lockrush-dev wants to merge 23 commits intomoeru-ai:mainfrom
lockrush-dev:lockrush-dev/feat/electron-mcp-connection
Open

feat: reimplement MCP connection for Electron#945
lockrush-dev wants to merge 23 commits intomoeru-ai:mainfrom
lockrush-dev:lockrush-dev/feat/electron-mcp-connection

Conversation

@lockrush-dev
Copy link
Contributor

@lockrush-dev lockrush-dev commented Jan 13, 2026

Description

This PR reimplements the MCP (Model Context Protocol) connection feature that was missing after migrating from Tauri to Electron. The implementation supports multiple concurrent MCP server connections and follows a clean two-layer architecture pattern.

Changes

Architecture

  • Two-Layer Design: Refactored MCP service into McpManager (manages connections) and McpServerSession (handles individual server operations)
    • McpManager: Manages lifecycle of all MCP server connections (connect, disconnect, session access)
    • McpServerSession: Handles operations on a specific MCP server (list tools, call tools, cleanup)

Core Implementation

  • MCP Service: Created apps/stage-tamagotchi/src/main/services/electron/mcp.ts with:
    • Multiple concurrent connection support using Map<string, McpServerSession>
    • Unique server ID generation using nanoid() instead of Math.random() for better collision resistance
    • Runtime validation for inputSchema and content parts instead of unsafe type assertions
    • Resource leak prevention using Promise.allSettled in cleanup operations
    • Proper environment variable handling using Object.fromEntries

Type Safety & IPC

  • Eventa Definitions: Added Eventa event definitions in apps/stage-tamagotchi/src/shared/electron/mcp.ts for type-safe IPC communication
  • Discriminated Union: Introduced McpContentPart discriminated union type for better content type handling (text, image, and catch-all)
  • Shared Types: All Eventa definitions consolidated in shared location for consistency

Package Updates

  • tauri-plugin-mcp:
    • Removed Electron support (Tauri-only as intended)
    • Removed @moeru/eventa dependency
    • Deleted packages/tauri-plugin-mcp/src/electron.ts
    • Updated pnpm-lock.yaml to reflect dependency removal

UI Components

  • MCP Settings: Created MCP settings component (packages/stage-ui/src/components/modules/Mcp.vue) and settings page
  • Integration: Added MCP module to settings modules list and routing

Code Quality

  • Import Organization: Fixed import order to comply with linting rules
  • Type Annotations: Added explicit type annotations where needed
  • Process Environment: Properly imports process.env from node:process

Technical Details

  • Uses StdioClientTransport from MCP SDK to spawn and communicate with MCP server processes
  • Supports multiple concurrent MCP server connections (each identified by unique serverId)
  • Connection state is stored in Pinia store with localStorage persistence
  • Automatic cleanup of all connections on app quit
  • Error handling and user feedback implemented in UI
  • Runtime validation ensures type safety for MCP SDK responses

Testing

To test:

  1. Start the Electron app: pnpm -F @proj-airi/stage-tamagotchi app:dev
  2. Navigate to Settings > Modules > MCP Server
  3. Enter MCP server command (e.g., npx) and arguments (e.g., -y @modelcontextprotocol/server-filesystem)
  4. Click Connect to establish connection (returns serverId)
  5. Tools should be listed automatically
  6. Multiple connections can be established concurrently

Linked Issues

Closes #783

- Implement MCP service in Electron main process using @modelcontextprotocol/sdk
- Add Eventa-based IPC communication for MCP commands
- Create MCP settings UI component and page
- Update tauri-plugin-mcp package to support Electron runtime
- Add i18n translations for MCP server settings
- Integrate MCP module into settings modules list

Closes moeru-ai#783
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @lockrush-dev, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request reintroduces the Model Context Protocol (MCP) connection capability into the Electron version of the application, a feature that was previously available in the Tauri build. The changes enable the application to seamlessly communicate with external MCP servers, providing users with a robust interface to configure and manage these connections. This ensures that the application maintains its functionality for interacting with AI models and tools, regardless of the underlying desktop framework.

Highlights

  • MCP Service Reimplementation: The core Model Context Protocol (MCP) connection logic has been reimplemented for the Electron runtime, allowing the application to connect to and interact with external MCP servers. This includes handling server connections, disconnections, listing available tools, and calling specific tools.
  • Eventa IPC Integration: Type-safe Inter-Process Communication (IPC) for MCP operations has been established using Eventa, defining specific events for connecting, disconnecting, listing tools, and calling tools between the renderer and main Electron processes.
  • User Interface for MCP Settings: A dedicated settings page and a Vue component have been created to allow users to configure and manage their MCP server connections directly within the application's UI. This includes input fields for server commands and arguments, along with connect/disconnect functionality and status display.
  • Cross-Platform Compatibility for MCP Plugin: The @proj-airi/tauri-plugin-mcp package has been updated to support both Electron and Tauri runtimes. It now includes platform detection to dynamically route MCP calls to the appropriate backend implementation (Eventa for Electron, Tauri invoke for Tauri), ensuring backward compatibility while enabling new Electron features.
  • Module Integration: The new MCP module has been integrated into the application's settings modules list, making it discoverable and configurable by users, and its connection status is reflected in the UI.
Ignored Files
  • Ignored by pattern: packages/i18n/src/** (1)
    • packages/i18n/src/locales/en/settings.yaml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully re-implements the MCP connection feature for the Electron environment, which is a great step forward after the migration from Tauri. The code is well-structured, introducing a unified plugin that supports both runtimes through platform detection. My review includes a few suggestions to enhance robustness, particularly around resource cleanup, and to improve code clarity and maintainability by refactoring some repetitive logic and simplifying certain implementations. One comment has been updated to reference a guideline about using programmatic identifiers for extensibility. Overall, this is a solid contribution.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 16, 2026

✅ Deploy to Cloudflare Workers (Preview) for stage-web ready!

Name Link
🔍 Latest deploy log https://github.com/moeru-ai/airi/actions/runs/21151471642?target=https://github.com
😎 Deploy Preview https://c0551fba-moeru-ai-airi.kwaa.workers.dev
🚀 Pull Request Preview https://pr-945-moeru-ai-airi.kwaa.workers.dev

autofix-ci bot and others added 2 commits January 16, 2026 16:22
- Fix resource leak in disconnectServer using Promise.allSettled and finally block
  Prevents zombie processes if client.close() fails before transport.close()

- Simplify process.env copying using Object.fromEntries and Object.entries
  Replaces manual for...in loop with modern JavaScript approach

- Replace JSON.stringify with discriminated union for content types
  Improves type safety and client-side handling of MCP tool results
  Adds support for text, image, and other content types

- Make isElectron and isTauri synchronous
  Removes unnecessary async/await overhead for platform detection

- Refactor platform detection to eliminate code duplication (DRY)
  Centralizes platform-specific logic in getMcpApi factory function

- Simplify tauri-plugin-mcp to only serve Tauri
  Removes Electron support as package should be Tauri-only

- Support multiple concurrent MCP server connections
  Refactors from single state to Map-based connection management
  Adds serverId to all API calls for connection isolation
  Improves cleanup on app quit to disconnect all servers
@lockrush-dev lockrush-dev marked this pull request as ready for review January 16, 2026 17:13
@lockrush-dev
Copy link
Contributor Author

@gemini-code-assist review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request successfully reimplements the MCP connection for Electron, addressing the missing feature after the migration from Tauri. The changes are well-structured, introducing a new Electron service, IPC event definitions, and a UI component for settings. The use of Promise.allSettled and AggregateError for robust disconnection handling is commendable. The lazy loading of the Tauri invoke module is also a good optimization. However, there are a few areas that could be improved for better maintainability and type safety, particularly regarding consistent ID generation and explicit type handling for external data.

lockrush-dev and others added 5 commits January 16, 2026 12:27
- Import process.env from node:process to fix linting error
- Add explicit type annotation for tool parameter in listTools
- Add @ts-expect-error comments for MCP SDK imports (type resolution)
- Fix import order to comply with linting rules

Fixes TypeScript compilation errors in the MCP service implementation.
- Fix electron.ts connectServer return type to match main process (returns string/serverId)
- Replace Math.random() with nanoid() for generateServerId to prevent collisions
- Add runtime validation for inputSchema and content parts instead of unsafe type assertions
- Update electron.ts API to support serverId parameters for multi-connection support
  - disconnectServer(serverId): Promise<void>
  - listTools(serverId): Promise<Tool[]>
  - callTool(serverId, name, args): Promise<CallToolResult>
- Fix TypeScript errors:
  - Import process.env from node:process
  - Add explicit type annotations
  - Remove unused @ts-expect-error directives

Addresses review comments from PR moeru-ai#945.
lockrush-dev and others added 8 commits January 16, 2026 15:00
…om tauri-plugin-mcp

- Refactor Electron MCP service into two-layer architecture:
  - McpServerSession: handles operations on a single MCP server (listTools, callTool, close)
  - McpManager: manages multiple MCP server connections (connectServer, disconnectServer)
- Remove Electron support from tauri-plugin-mcp package:
  - Delete packages/tauri-plugin-mcp/src/electron.ts
  - Remove @moeru/eventa dependency from tauri-plugin-mcp
  - Keep tauri-plugin-mcp Tauri-only as intended
- Eventa definitions remain in apps/stage-tamagotchi/src/shared/electron/mcp.ts

Addresses PR review comments from @nekomeowww.
…plugin-mcp

Remove @moeru/eventa dependency entry from lockfile to match package.json changes.
@nekomeowww
Copy link
Member

@nekomeowww
Copy link
Member

Conflict.

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.

feature request: reimplement the MCP connection

3 participants