Skip to content

Feat/add plugin grpc#2685

Merged
crivetimihai merged 13 commits intomainfrom
feat/add_plugin_grpc
Feb 7, 2026
Merged

Feat/add plugin grpc#2685
crivetimihai merged 13 commits intomainfrom
feat/add_plugin_grpc

Conversation

@terylt
Copy link
Copy Markdown
Collaborator

@terylt terylt commented Feb 3, 2026

📝 Summary

Add gRPC and Unix Socket Transports for External Plugins

Adds two new high-performance transport options for external plugins alongside the existing MCP/HTTP transport:

Transport Throughput Use Case
MCP/HTTP ~600 calls/sec Remote plugins, cross-platform
gRPC ~4,700 calls/sec Remote/local plugins, mTLS support
Unix Socket ~9,000 calls/sec Local plugins only, maximum performance

Both new transports use Protocol Buffers for serialization, sharing the same plugin_service.proto schema.

gRPC Transport

Full-featured gRPC transport with optional mTLS authentication.

  plugins:                                                                                                                                            
    - name: "MyPlugin"                                                                                                                                
      kind: "external"                                                                                                                                
      hooks: ["prompt_pre_fetch"]                                                                                                                     
      grpc:                                                                                                                                           
        target: "127.0.0.1:50051"                                                                                                                     
        # Optional mTLS                                                                                                                               
        tls:                                                                                                                                          
          certfile: "client-cert.pem"                                                                                                                 
          keyfile: "client-key.pem"                                                                                                                   
          ca_bundle: "ca-cert.pem"

Supports both TCP and Unix domain sockets:

  grpc:                                                                                                                                               
    uds: "/tmp/grpc-plugin.sock"  # Alternative to target                                                                                             

Unix Socket Transport

Lightweight, high-performance transport using length-prefixed protobuf messages directly over Unix sockets (no HTTP/2 framing overhead).

plugins:                                                                                                                                            
    - name: "MyPlugin"                                                                                                                                
      kind: "external"                                                                                                                                
      hooks: ["prompt_pre_fetch"]                                                                                                                     
      unix_socket:                                                                                                                                    
        path: "/tmp/plugin.sock"                                                                                                                      
        timeout: 30.0                                                                                                                                 
        reconnect_attempts: 3 

Wire format: [4-byte big-endian length][protobuf payload]

Files Added/Modified

  • mcpgateway/plugins/framework/external/grpc/ - gRPC client, server, TLS utilities
  • mcpgateway/plugins/framework/external/unix/ - Unix socket client, server, protocol
  • mcpgateway/plugins/framework/registry.py - External plugin detection
  • docs/docs/using/plugins/grpc-transport.md - gRPC documentation
  • docs/docs/using/plugins/unix-socket-transport.md - Unix socket documentation
  • tests/unit/mcpgateway/plugins/framework/external/grpc/ - gRPC tests
  • tests/unit/mcpgateway/plugins/framework/external/unix/ - Unix socket tests

🏷️ Type of Change

  • Bug fix
  • Feature / Enhancement
  • Documentation
  • Refactor
  • Chore (deps, CI, tooling)
  • Other (describe below)

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 80% make coverage

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes (optional)

Screenshots, design decisions, or additional context.

@crivetimihai
Copy link
Copy Markdown
Member

Thanks for the gRPC and Unix Socket transport work, @terylt! This looks like a substantial feature with good test coverage.

Since this is still in draft, just a couple of early notes:

Let us know when this is ready for a full review!

Copy link
Copy Markdown
Member

@araujof araujof left a comment

Choose a reason for hiding this comment

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

Nice work on this PR, @terylt !

Architecturally, the PR looks sound.

While still in draft, here are a few comments worth looking into:

1. Security: Unix Domain Socket Permissions
The UnixSocketPluginServer creates a socket file on the filesystem to facilitate IPC.

Vulnerability: By default, Unix sockets are created using the process's umask, which often results in permissions like 0666 or 0644. This allows any local user on the system to connect to the plugin server, potentially intercepting sensitive context data or triggering unauthorized hooks. Note: asyncio.start_unix_server does not guarantee secure permissions on the created Unix domain socket file by default.

Recommendation: Explicitly set the socket file permissions to 0600 (read/write only by the owner) immediately after binding.

# After starting the server
os.chmod(self.socket_path, 0o600)

2. Portability: Makefile gRPC Generation
The Makefile uses sed -i '' to fix imports in the generated gRPC Python stubs.

Logic Error: The syntax -i '' is specific to BSD sed (macOS). On GNU sed (Linux), this will fail because Linux sed does not expect a space between -i and the extension, or it will interpret the empty string as the script and the actual script as the file path.

Recommendation: Use a portable approach to handle both macOS and Linux, or use a Python script for post-processing the imports.

# Portable sed -i example
sed -i.bak 's/old/new/' file && rm file.bak

@crivetimihai crivetimihai self-assigned this Feb 4, 2026
@terylt terylt marked this pull request as ready for review February 4, 2026 22:50
@terylt
Copy link
Copy Markdown
Collaborator Author

terylt commented Feb 4, 2026

Okay I address the comments. Note @crivetimihai I made grpc an optional package, and the unit tests will only run if grpc is installed. I don't see a way to install optional packages in the CICD, so they don't get run as part of it.

@crivetimihai crivetimihai added this to the Release 1.0.0-RC1 milestone Feb 7, 2026
Teryl Taylor added 11 commits February 7, 2026 14:58
Signed-off-by: Teryl Taylor <terylt@ibm.com>
…socket.

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
…alled.

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Teryl Taylor <terylt@ibm.com>
@crivetimihai
Copy link
Copy Markdown
Member

Review Summary

Rebased onto main (clean, no merge commits). Two conflicts resolved in docs/docs/using/plugins/index.md and mcpgateway/plugins/framework/external/mcp/server/runtime.py.

Tests

  • 171 new tests pass (gRPC + Unix socket)
  • 796 total plugin tests pass (78 skipped — Rust/copier not available)
  • Pre-existing failures in test_translate_grpc.py are unrelated (confirmed same on main)

Architecture

Well-designed — follows existing external plugin patterns exactly. Both GrpcExternalPlugin and UnixSocketExternalPlugin implement invoke_hook(), integrating seamlessly with PluginInstanceRegistry and ExternalHookRef. Shared .proto schema between gRPC and Unix socket transports is good code reuse.

Security

  • mTLS support for gRPC (client certs + CA bundle)
  • UDS file permissions set to 0o600 (owner-only)
  • Parent directory permission checks on UDS paths
  • TLS + UDS combination properly rejected
  • Server-side client_auth defaults to "require"

Minor Items (tracked in follow-up issue)

  1. Unix socket message dispatch (unix/server/server.py:158-202): Trial-and-error protobuf parsing to determine message type. Works for current 3-message API but fragile — a discriminator byte or envelope message would be more robust.
  2. TLS verify=False (tls_utils.py:89-99): Comment says passing None for root_certificates disables verification, but actually uses system trust store. Safer than documented.
  3. No Prometheus metrics on gRPC/Unix socket server runtimes (MCP runtime has them).

Overall: production-quality addition, recommended for merge after follow-up items are tracked.

…gin files

Add grpcio to dev dependencies so CI installs it and grpc/unix plugin
tests run during coverage checks. Exclude generated proto _pb2 files
from coverage measurement. Add comprehensive tests for proto_convert,
unix runtime, and extend existing test suites to cover exception
handling, error dispatch, reconnection, and lifecycle edge cases.

Signed-off-by: Mihai Criveti <crmihai1@ie.ibm.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
…lures

Adding grpcio without grpcio-reflection caused grpc_service.py to set
GRPC_AVAILABLE=True but reflection_pb2 remained None, breaking all
gRPC reflection tests.

Signed-off-by: Mihai Criveti <crmihai1@ie.ibm.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai merged commit 1c201ef into main Feb 7, 2026
51 checks passed
@crivetimihai crivetimihai deleted the feat/add_plugin_grpc branch February 7, 2026 15:48
kcostell06 pushed a commit to kcostell06/mcp-context-forge that referenced this pull request Feb 24, 2026
* feat: added grpc capabilities to plugin framework.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added test cases, documentation and features for gRPC and unix socket.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: added proto files to manifest.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: CI/CD failings.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: lint issues, test cases etc.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: skip grpc tests if grpc not available.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* cicd: excluded generated pb files from vulture.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* cicd: exclude pb files from main linter.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: flake8 issue.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: added conftest.py to ignore grpc doc tests when grpc is not installed.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* docs: updated the docs and template to support tls.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: add grpc to dev deps and boost test coverage to 90%+ for new plugin files

Add grpcio to dev dependencies so CI installs it and grpc/unix plugin
tests run during coverage checks. Exclude generated proto _pb2 files
from coverage measurement. Add comprehensive tests for proto_convert,
unix runtime, and extend existing test suites to cover exception
handling, error dispatch, reconnection, and lifecycle edge cases.

Signed-off-by: Mihai Criveti <crmihai1@ie.ibm.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* fix: add grpcio-reflection to dev deps to fix test_translate_grpc failures

Adding grpcio without grpcio-reflection caused grpc_service.py to set
GRPC_AVAILABLE=True but reflection_pb2 remained None, breaking all
gRPC reflection tests.

Signed-off-by: Mihai Criveti <crmihai1@ie.ibm.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Mihai Criveti <crmihai1@ie.ibm.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
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