refactor(core): Full hexagonal architecture modularization, secure session handler & mock testing suite#93
refactor(core): Full hexagonal architecture modularization, secure session handler & mock testing suite#93randall-vx wants to merge 4 commits intochigwell:mainfrom
Conversation
|
Hey @chigwell ! Quick update: I've successfully rebased this PR on top of the latest During the rebase, I integrated the recent graceful disconnect fix meant to prevent the Specifically:
This ensures we still get the reliable, graceful disconnection benefit on exit, but without polluting the FastMCP routing layer with network connection lifecycle management or catching silent exceptions ( Everything is up-to-date and ready for review/merge. Let me know if there's anything else! |
|
|
||
| @contextlib.asynccontextmanager | ||
| async def telegram_client_lifespan(): | ||
| import sys |
There was a problem hiding this comment.
I suggest removing this line, as it is already presented at the top level.
| from . import chats | ||
| from . import messages | ||
| from . import media | ||
| from . import contacts |
There was a problem hiding this comment.
I suggest using:
from . import contacts
from . import contacts as contacts_module
| """ | ||
| Import a list of contacts. Each contact should be a dict with phone, first_name, last_name. | ||
| """ | ||
| return await contacts.import_contacts(contacts) |
There was a problem hiding this comment.
It should be something like:
return await contacts_module.import_contacts(contacts)
in terms that when the import_contacts tool is called, its contacts parameter hides the imported contacts module, so contacts.import_contacts(...) resolves against the input list instead of telegram_mcp.contacts and raises an attribute error. This breaks the tool for every import-contacts request, whereas the pre-refactor implementation worked.
There was a problem hiding this comment.
@chigwell Thanks for the detailed review!
I've addressed your feedback and just force-pushed the updates, keeping the commit history clean by squashing the fixes directly into the core refactor commit.
Here is what was updated based on your findings:
- Redundant Import Cleanup (
client.py): Removed the localimport sysinsidetelegram_client_lifespan()since it is already properly imported at the module top level. - Variable Shadowing Fix (
mcp_server.py): You were completely right about thecontactsparameter shadowing thecontactsmodule namespace and causing theAttributeError.- Instead of trying to rename the parameter (which would risk changing the expected
FastMCPJSON Schema signature public contract), applied your exact suggestion. - Reintroduced the module alias
from . import contacts as contacts_moduleto handle the specific tool internal call, ensuringasync def import_contacts(contacts: list)stays immutable externally.
- Instead of trying to rename the parameter (which would risk changing the expected
Let me know if there's anything else needed before we move forward !
…architecture This commit unifies the documentation and AI agent system prompts to strictly respect our recent architectural refactoring. 1. **README Surgical Purge:** - Removed ~300 lines of obsolete, monolithic code examples that promoted direct `TelegramClient` manipulation inside the MCP handlers. - Introduced the `Architecture` section, explicitly detailing the Hexagonal boundary guidelines (Tools -> Domain -> Infrastructure). - Added a `Development Workflow` section documenting CI rules (`pytest`, `black`, `flake8`) to prevent regressions. - Replaced outdated 'Database lock' troubleshooting advice, redirecting logic to the new `telegram_client_lifespan`. 2. **AI Agent Skills (Executable Debt Elimination):** - Implemented `.agents/skills/telegram_mcp_update/SKILL.md` to prevent "executable debt." - Forbade the use of hard process killing (`pkill -f`) in favor of respecting the internal context manager lifecycle. - Replaced static `upstream/fork` Git topological assumptions with adaptive `git remote -v` checks. - Unified system instructions into a single language (English) to preserve deterministic modeling.
|
Thanks for the substantial refactor - the modularization effort is appreciated, but I’m not comfortable approving this in the current state. This PR touches the core architecture and replaces the previous monolithic implementation with a new package layout, new entrypoints, and new abstractions. Given that scope, I think we still need a bit more confidence before merge. Requested changes:
Also, since one breaking regression ( Happy to re-review after that. |
|
Hi @l1v0n1, I've investigated the variable shadowing issue you caught in review. You were spot on. I built a lightweight AST validator ( To validate that this approach is viable end-to-end and resolve it cleanly, I've pushed a proof-of-concept to this branch refactoring If you approve this direction, I'll extend the same pattern to the remaining tools in this PR. If you'd prefer a different approach, for example, a structural linter rule instead of DTOs let me know before I expand the refactor. Crucial Findings: As a follow-up to the DTO refactor, I ran a simulated JSON-RPC test (
Both of these endpoints were completely broken prior to the shadowing issue, I only caught them because the DTO POC forced me to exercise the actual client-to-server roundtrip instead of the unit test mocks. I haven't attempted to fix these Let me know your call. You can run PS: All CI checks are passing on the latest commit ( |
Thanks for the investigation. I’d like to keep this PR focused and avoid expanding scope further. Please keep this PR limited to:
For the runtime bugs you found ( Also agreed that we need better end-to-end coverage, but I’d prefer that as a separate change too. |
Rename contacts and groups parameters in import_contacts and create_folder to avoid shadowing global module names. This focuses the PR on the core hexagonal refactor without expanding the scope to DTOs.
Overview
This PR transitions the monolithic
main.pyTelegram MCP server into a fully modular, scalable, and testable Hexagonal Architecture. It extracts over 34+ domain functions into isolated modules (chats.py,messages.py,media.py, etc.) inside asrc/telegram_mcppackage structure with nativepipxintegration capabilities (mcp[cli]).Key Advancements & Features
1. Hexagonal Architecture & Decoupling
client.py,messages.py,media.py,contacts.py,chats.py,folders.py,groups.py,utils.py, andsecurity.py.2. Security & Context Hardening
session_generator.pyoffering secure, interactive QR-code and dual-factor phone login capabilities, writing explicitly localizedtelegram.sessionartifacts without source code pollution.os.path.abspathjail).3. Comprehensive Mock Testing Suite & CI/CD
conftest.py): Added a secureAsyncMockoverriding Telethon'sTelegramClient, allowing test logic to pass locally and in CI runners without real Telegram credentials.3.11,3.12,3.13, plus rigorousflake8andblackstatic linting ensuring modern PEP 8 compliance.4. Native Pipx Ready Distribution
pyproject.toml): Addedproject.scripts.telegram-mcpmapping, replacing direct python script invocation with native cross-platform binaries. The application can now be safely distributed.Architectural Map
Verification
blackorflake8errors in the tree)