# MCP Gateway Engineering Guide ## Ownership This repository owns the Python MCP Gateway boundary: - MCP tool names, descriptions, input Schema, local/public registration, and HTTP route mapping. - MCP protocol adaptation, safe display DTOs, request/session forwarding, and Gateway operations. - The cross-repository integration entry point and operator-facing runbook. Business ownership remains outside this repository: - `Y:/fmsoperate`: tool routes, Validate/Logic/Model, registry state, business permissions, data scope, exports, and access logs. - `Y:/base`: employee identity, Gateway device sessions, MCP token lifecycle, and authentication decisions. - `Y:/home`: employee UI and thin proxy only. - `Y:/settlement_tests`: cross-repository PHP contract tests. Other repositories should link to this repository's README and project docs instead of copying the Gateway contract. ## Hard Boundaries - Keep the Gateway thin. It must not query business databases or reproduce logistics rules. - Never decide employee, company, menu, or data permissions in Python. Forward the authenticated context to ThinkPHP. - Never accept caller-supplied employee, company, role, permission, or internal identity overrides. - Public requests use a `GWS_xxx` device credential to load a Redis Gateway session and its server-side `mcp_token`. - Never log tokens, full Gateway credentials, cookies, authorization headers, or raw backend responses. - Local and public tool registries must stay identical. Actual visibility is the intersection with the enabled-tool list returned by fmsoperate; failures close access. - `query_order` is the legacy display exception. All other registered tools use `services/output_presenter.py` and must fail closed on unknown fields, malformed responses, or unknown errors. - `initialize` and `tools/list` are not rate limited. `tools/call` is limited per authenticated device session and tool. - The retired authorization-code binding flow must not return to the runtime without a new security review. ## Documentation Routes - `README.md`: current tool catalog, routes, configuration, operations, and troubleshooting. - `Y:/all_project_docs/mcp/overview.md`: current system summary and cross-repository ownership map. - The same directory's `requirements.md`, `tech-specs.md`, `user-structure.md`, and `timeline.md`: current contracts, architecture, flows, and operational handoff. - `Y:/all_project_docs/mcp/guides/mcp-team-sharing.md`: current team onboarding and sharing guide. - `docs/superpowers/specs/`: dated design decisions and ADR-like context. The following are not authoritative and are not read by default: - `.planning/**`: temporary session state; archive or remove from the active workspace after delivery. - Completed `docs/superpowers/plans/**`: execution history, not the current contract. When a temporary plan finishes, promote durable facts into README/project docs, record the milestone once, then retire the plan. Do not keep completed checklists as active instructions. If `Y:/all_project_docs` is unavailable, stop changes to contracts, architecture, databases, or deployment behavior and report the missing documentation repository instead of relying on stale information. ## Change Rules - Update tool metadata, both registries, CLI forwarding, Presenter mapping, and tests together when adding or changing a tool. - Keep tool selection zero-inference: ambiguous result intent or number type requires a user question before any call. - Keep `request_id` across Gateway, PHP, responses, and logs; public ingress generates the trusted trace ID. - Changes that affect fmsoperate or base contracts require matching changes and tests in those owning repositories. - Do not run registry SQL or restart a shared Gateway process unless the task explicitly authorizes that operational action. ## Verification Run from `Y:/mcp`: ```powershell python -m unittest discover -s tests -p "test_*.py" python -m coverage run -m unittest discover -s tests -p "test_*.py" python -m coverage report -m --fail-under=100 git diff --check ``` Verify the code registry without relying on documentation: ```powershell python -c "from app import GatewayApp; print('\n'.join(GatewayApp().registered_tool_names()))" ```