Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-mcp/src/lexigram/ai/mcp/module.py: 79%
19 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
1"""MCP module for Lexigram."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Any
7from lexigram.di.module import DynamicModule, Module, module
9if TYPE_CHECKING:
10 from lexigram.ai.mcp.config import MCPConfig
13@module(name="lexigram-ai-mcp")
14class MCPModule(Module):
15 """Module for MCP server.
17 Provides MCP server, handlers, and transports to the application.
19 Usage::
21 app = LexigramApplication(
22 modules=[..., MCPModule.configure()],
23 )
25 # With MCPController subclasses::
27 app = LexigramApplication(
28 modules=[..., MCPModule.configure(controllers=[DataToolsController])],
29 )
31 # Auto-expose existing services as MCP tools::
33 app = LexigramApplication(
34 modules=[
35 ...,
36 MCPModule.from_services(
37 services=[UserService, AnalyticsService],
38 include_methods=["search", "get_*"],
39 ),
40 ],
41 )
42 """
44 @classmethod
45 def from_services(
46 cls,
47 services: list[type],
48 *,
49 include_methods: list[str] | None = None,
50 config: MCPConfig | None = None,
51 ) -> DynamicModule:
52 """Create an MCPModule that auto-exposes service methods as MCP tools.
54 Args:
55 services: Service classes whose public methods are exposed as tools.
56 include_methods: Optional glob patterns to restrict which methods are
57 exposed (e.g. ``["search", "get_*"]``).
58 config: Optional :class:`~lexigram.ai.mcp.config.MCPConfig` override.
60 Returns:
61 A :class:`~lexigram.di.module.DynamicModule` descriptor.
62 """
63 return cls.configure(
64 config=config,
65 services=services,
66 include_methods=include_methods,
67 )
69 @classmethod
70 def configure(
71 cls,
72 *,
73 config: MCPConfig | None = None,
74 controllers: list[type] | None = None,
75 services: list[type] | None = None,
76 include_methods: list[str] | None = None,
77 enable_streaming: bool = True,
78 **provider_kwargs: Any,
79 ) -> DynamicModule:
80 """Create an MCPModule with explicit provider configuration.
82 Args:
83 config: Optional :class:`~lexigram.ai.mcp.config.MCPConfig`.
84 controllers: :class:`~lexigram.ai.mcp.controllers.MCPController`
85 subclasses to register with the server.
86 services: Service classes to auto-expose as MCP tools.
87 include_methods: Glob patterns to restrict auto-exposed methods.
88 enable_streaming: Enable SSE streaming transport support. Defaults
89 to ``True``; set to ``False`` to restrict the server to
90 stdio-only transport.
91 **provider_kwargs: Additional keyword arguments forwarded to
92 :class:`~lexigram.ai.mcp.di.provider.MCPProvider`.
94 Returns:
95 A :class:`~lexigram.di.module.DynamicModule` descriptor.
96 """
97 from lexigram.ai.mcp.di.provider import MCPProvider
98 from lexigram.ai.mcp.server import MCPServer
100 return DynamicModule(
101 module=cls,
102 providers=[
103 MCPProvider(
104 config=config,
105 controllers=controllers,
106 services=services,
107 include_methods=include_methods,
108 enable_streaming=enable_streaming,
109 **provider_kwargs,
110 )
111 ],
112 exports=[MCPServer],
113 )
115 @classmethod
116 def stub(cls, config: MCPConfig | None = None) -> DynamicModule:
117 """Create an MCPModule suitable for unit and integration testing.
119 Uses in-memory transport with no external MCP server connections.
120 Streaming is disabled by default to simplify test assertions.
122 Args:
123 config: Optional :class:`~lexigram.ai.mcp.config.MCPConfig`
124 override. Uses safe test defaults when ``None``.
126 Returns:
127 A :class:`~lexigram.di.module.DynamicModule` descriptor.
128 """
129 from lexigram.ai.mcp.di.provider import MCPProvider
130 from lexigram.ai.mcp.server import MCPServer
132 return DynamicModule(
133 module=cls,
134 providers=[MCPProvider(config=config, enable_streaming=False)],
135 exports=[MCPServer],
136 )
139__all__ = ["MCPModule"]