mcp-common 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. mcp_common-0.2.0/.github/FUNDING.yml +1 -0
  2. mcp_common-0.2.0/.gitignore +72 -0
  3. mcp_common-0.2.0/.pre-commit-config.yaml +102 -0
  4. mcp_common-0.2.0/CLAUDE.md +528 -0
  5. mcp_common-0.2.0/LICENSE +28 -0
  6. mcp_common-0.2.0/PKG-INFO +568 -0
  7. mcp_common-0.2.0/README.md +508 -0
  8. mcp_common-0.2.0/docs/ACB_FOUNDATION.md +789 -0
  9. mcp_common-0.2.0/docs/ARCHITECTURE.md +1482 -0
  10. mcp_common-0.2.0/docs/EXCEPTION_SUPPRESSION_ACTION_PLAN.md +233 -0
  11. mcp_common-0.2.0/docs/IMPLEMENTATION_PLAN.md +1497 -0
  12. mcp_common-0.2.0/docs/IMPORT_DETECTION_MIGRATION.md +542 -0
  13. mcp_common-0.2.0/docs/INTEGRATION_TRACKING.md +672 -0
  14. mcp_common-0.2.0/docs/MCP_ECOSYSTEM_CRITICAL_AUDIT.md +1693 -0
  15. mcp_common-0.2.0/docs/MCP_SERVERS_INTEGRATION_SUMMARY.md +726 -0
  16. mcp_common-0.2.0/docs/PHASE3_3_M2_PROGRESS.md +263 -0
  17. mcp_common-0.2.0/docs/PHASE3_3_M3_RFC.md +338 -0
  18. mcp_common-0.2.0/docs/PHASE3_ARCHITECTURE_REVIEW.md +755 -0
  19. mcp_common-0.2.0/docs/PHASE3_COMPLETION_SUMMARY.md +451 -0
  20. mcp_common-0.2.0/docs/PHASE3_CONSOLIDATED_REVIEW.md +862 -0
  21. mcp_common-0.2.0/docs/PHASE4_10_RFC.md +793 -0
  22. mcp_common-0.2.0/docs/PLAN_STATUS.md +221 -0
  23. mcp_common-0.2.0/docs/RATE_LIMIT_CONFIG_MIGRATION.md +501 -0
  24. mcp_common-0.2.0/docs/RATE_LIMIT_LOAD_TESTING.md +455 -0
  25. mcp_common-0.2.0/docs/SECURITY_IMPLEMENTATION.md +531 -0
  26. mcp_common-0.2.0/examples/README.md +275 -0
  27. mcp_common-0.2.0/examples/settings/weather.yaml +26 -0
  28. mcp_common-0.2.0/examples/weather_server.py +241 -0
  29. mcp_common-0.2.0/mcp_common/__init__.py +74 -0
  30. mcp_common-0.2.0/mcp_common/adapters/__init__.py +10 -0
  31. mcp_common-0.2.0/mcp_common/adapters/http/__init__.py +10 -0
  32. mcp_common-0.2.0/mcp_common/adapters/http/client.py +266 -0
  33. mcp_common-0.2.0/mcp_common/config/__init__.py +11 -0
  34. mcp_common-0.2.0/mcp_common/config/base.py +367 -0
  35. mcp_common-0.2.0/mcp_common/config/validation_mixin.py +258 -0
  36. mcp_common-0.2.0/mcp_common/exceptions.py +241 -0
  37. mcp_common-0.2.0/mcp_common/health.py +188 -0
  38. mcp_common-0.2.0/mcp_common/http_health.py +322 -0
  39. mcp_common-0.2.0/mcp_common/middleware/__init__.py +25 -0
  40. mcp_common-0.2.0/mcp_common/middleware/rate_limit_config.py +222 -0
  41. mcp_common-0.2.0/mcp_common/py.typed +0 -0
  42. mcp_common-0.2.0/mcp_common/security/__init__.py +23 -0
  43. mcp_common-0.2.0/mcp_common/security/api_keys.py +342 -0
  44. mcp_common-0.2.0/mcp_common/security/sanitization.py +279 -0
  45. mcp_common-0.2.0/mcp_common/ui/__init__.py +10 -0
  46. mcp_common-0.2.0/mcp_common/ui/panels.py +333 -0
  47. mcp_common-0.2.0/pyproject.toml +294 -0
  48. mcp_common-0.2.0/tests/__init__.py +1 -0
  49. mcp_common-0.2.0/tests/conftest.py +80 -0
  50. mcp_common-0.2.0/tests/performance/test_rate_limits_load.py +334 -0
  51. mcp_common-0.2.0/tests/test_config.py +328 -0
  52. mcp_common-0.2.0/tests/test_config_security.py +466 -0
  53. mcp_common-0.2.0/tests/test_config_validation_mixin.py +359 -0
  54. mcp_common-0.2.0/tests/test_health.py +328 -0
  55. mcp_common-0.2.0/tests/test_http_client.py +267 -0
  56. mcp_common-0.2.0/tests/test_http_health.py +356 -0
  57. mcp_common-0.2.0/tests/test_rate_limit_config.py +329 -0
  58. mcp_common-0.2.0/tests/test_security_api_keys.py +381 -0
  59. mcp_common-0.2.0/tests/test_security_sanitization.py +446 -0
  60. mcp_common-0.2.0/tests/test_ui_panels.py +251 -0
  61. mcp_common-0.2.0/tests/test_version.py +8 -0
  62. mcp_common-0.2.0/uv.lock +4819 -0
@@ -0,0 +1 @@
1
+ github: [lesleslie]
@@ -0,0 +1,72 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual environments
25
+ venv/
26
+ ENV/
27
+ env/
28
+ .venv/
29
+
30
+ # Testing
31
+ .pytest_cache/
32
+ .coverage
33
+ .coverage.*
34
+ htmlcov/
35
+ .tox/
36
+ .nox/
37
+ coverage.xml
38
+ *.cover
39
+ .hypothesis/
40
+
41
+ # Type checking
42
+ .mypy_cache/
43
+ .dmypy.json
44
+ dmypy.json
45
+ .pytype/
46
+
47
+ # IDEs
48
+ .vscode/
49
+ .idea/
50
+ *.swp
51
+ *.swo
52
+ *~
53
+ .DS_Store
54
+
55
+ # Ruff
56
+ .ruff_cache/
57
+
58
+ # Environment
59
+ .env
60
+ .env.local
61
+ .env.*.local
62
+
63
+ # Documentation builds
64
+ docs/_build/
65
+ site/
66
+
67
+ # Hatch
68
+ .hatch/
69
+ /.benchmarks/
70
+ /.claude/
71
+ /.envrc
72
+ /.mcp.json
@@ -0,0 +1,102 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: validate-regex-patterns
5
+ name: validate-regex-patterns
6
+ entry: uv run python -m crackerjack.tools.validate_regex_patterns
7
+ language: system
8
+ files: \.py$
9
+ exclude: ^\.venv/|^src/
10
+ - id: skylos
11
+ name: skylos-dead-code-detection
12
+ entry: skylos
13
+ language: system
14
+ args: ["mcp_common", "--exclude", "tests"]
15
+ pass_filenames: false
16
+ exclude: ^tests/|^src/
17
+ stages: ["pre-push", "manual"]
18
+ - id: zuban
19
+ name: zuban-type-checking
20
+ entry: uv run zuban check
21
+ language: system
22
+ args: ["--config-file", "mypy.ini", "./mcp_common"]
23
+ pass_filenames: false
24
+ exclude: ^tests/|^src/
25
+ stages: ["pre-push", "manual"]
26
+ - repo: https://github.com/pre-commit/pre-commit-hooks
27
+ rev: v6.0.0
28
+ hooks:
29
+ - id: trailing-whitespace
30
+ name: trailing-whitespace
31
+ exclude: ^\.venv/|^src/
32
+ - id: end-of-file-fixer
33
+ name: end-of-file-fixer
34
+ exclude: ^\.venv/|^src/
35
+ - id: check-yaml
36
+ name: check-yaml
37
+ exclude: ^\.venv/|^src/
38
+ - id: check-toml
39
+ name: check-toml
40
+ exclude: ^\.venv/|^src/
41
+ - id: check-added-large-files
42
+ name: check-added-large-files
43
+ exclude: ^\.venv/|^src/
44
+ - repo: https://github.com/astral-sh/uv-pre-commit
45
+ rev: 0.9.0
46
+ hooks:
47
+ - id: uv-lock
48
+ files: ^ pyproject\.toml$
49
+ exclude: ^src/
50
+ - repo: https://github.com/gitleaks/gitleaks
51
+ rev: v8.28.0
52
+ hooks:
53
+ - id: gitleaks
54
+ exclude: uv\.lock|pyproject\.toml|tests/.*|docs/.*|\.claude/.*|.*\.md|^src/
55
+ - repo: https://github.com/PyCQA/bandit
56
+ rev: 1.8.6
57
+ hooks:
58
+ - id: bandit
59
+ args: ["-c", "pyproject.toml", "-r", "-ll"]
60
+ files: ^mcp_common/.*\.py$
61
+ exclude: ^tests/|^src/
62
+ stages: ["pre-push", "manual"]
63
+ - repo: https://github.com/codespell-project/codespell
64
+ rev: v2.4.1
65
+ hooks:
66
+ - id: codespell
67
+ exclude: ^\.venv/|^src/
68
+ additional_dependencies: ["tomli"]
69
+ - repo: https://github.com/astral-sh/ruff-pre-commit
70
+ rev: v0.14.0
71
+ hooks:
72
+ - id: ruff-check
73
+ exclude: ^\.venv/|^src/
74
+ - id: ruff-format
75
+ exclude: ^\.venv/|^src/
76
+ - repo: https://github.com/executablebooks/mdformat
77
+ rev: 0.7.22
78
+ hooks:
79
+ - id: mdformat
80
+ exclude: ^\.venv/|^src/
81
+ additional_dependencies: ["mdformat-ruff"]
82
+ - repo: https://github.com/fredrikaverpil/creosote
83
+ rev: v4.1.0
84
+ hooks:
85
+ - id: creosote
86
+ exclude: ^\.venv/|^src/
87
+ stages: ["pre-push", "manual"]
88
+ - repo: https://github.com/rohaquinlop/complexipy-pre-commit
89
+ rev: v3.3.0
90
+ hooks:
91
+ - id: complexipy
92
+ args: ["-d", "low", "--max-complexity-allowed", "15"]
93
+ files: ^mcp_common/.*\.py$
94
+ exclude: ^(\.venv/|tests/)|^src/
95
+ stages: ["pre-push", "manual"]
96
+ - repo: https://github.com/dosisod/refurb
97
+ rev: v2.2.0
98
+ hooks:
99
+ - id: refurb
100
+ files: ^mcp_common/.*\.py$
101
+ exclude: ^tests/|^src/
102
+ stages: ["pre-push", "manual"]
@@ -0,0 +1,528 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **mcp-common** is an ACB-native foundation library for building production-grade MCP (Model Context Protocol) servers. It provides battle-tested patterns extracted from 9 production servers including crackerjack, session-mgmt-mcp, and fastblocks.
8
+
9
+ **Current Status:** v2.0.0 - **Partially Implemented**
10
+
11
+ - ✅ Core package structure complete
12
+ - ✅ MCPBaseSettings with YAML + environment variable support
13
+ - ✅ HTTPClientAdapter with connection pooling (implemented)
14
+ - ✅ ServerPanels for Rich UI (implemented)
15
+ - ✅ Security utilities (API key validation, sanitization)
16
+ - ✅ Health check system (HTTP connectivity, component health)
17
+ - ✅ Exception hierarchy (MCPServerError, validation errors)
18
+ - ✅ ValidationMixin for Pydantic models
19
+ - ✅ Comprehensive test suite with 90%+ coverage
20
+ - 🚧 Rate limiting adapter (in middleware/rate_limit_config.py, needs ACB migration)
21
+ - 🚧 Complete example server (`examples/weather_server.py`)
22
+
23
+ ## Critical Prerequisites
24
+
25
+ ### ACB Framework Dependency
26
+
27
+ This library is **ACB-native**, meaning it is built **on top of ACB**, not as a standalone utility:
28
+
29
+ - **ACB (Asynchronous Component Base)** provides: adapters, dependency injection, structured logging, settings, console
30
+ - **mcp-common** provides: MCP-specific adapters built using ACB patterns
31
+ - **Relationship:** mcp-common extends ACB for MCP server use cases
32
+
33
+ **ACB is installed as an editable dependency** from `../acb`:
34
+
35
+ ```toml
36
+ [tool.uv.sources]
37
+ acb = { path = "../acb", editable = true }
38
+ ```
39
+
40
+ This means changes to the ACB project at `../acb` are immediately reflected in mcp-common.
41
+
42
+ **IMPORTANT:** Before implementing any adapter, read `docs/ACB_FOUNDATION.md` to understand:
43
+
44
+ - ACB adapter lifecycle (MODULE_ID, MODULE_STATUS, MODULE_METADATA)
45
+ - Dependency injection with `acb.depends`
46
+ - Logger injection via `LoggerProtocol`
47
+ - Settings extending `acb.config.Settings`
48
+
49
+ ### Reference Implementations
50
+
51
+ The design is extracted from these production servers (located in `../` relative to this repo):
52
+
53
+ **Primary Pattern Sources:**
54
+
55
+ - **crackerjack** (`../crackerjack/mcp/`) - Rate limiting adapter, Rich UI panels (ServerPanels), MCP server structure, tool organization
56
+ - **session-mgmt-mcp** (`../session-mgmt-mcp/`) - ACB Settings with YAML configuration, comprehensive DI usage, adapter lifecycle patterns
57
+ - **fastblocks** (`../fastblocks/`) - ACB adapter organization, module structure
58
+
59
+ **Key Patterns from Production Servers:**
60
+
61
+ - **Rate Limiting:** `crackerjack/mcp/rate_limiter.py` - Token bucket algorithm implementation
62
+ - **Rich UI Panels:** `crackerjack/ui/` - Professional console output with Rich library
63
+ - **Tool Registration:** `crackerjack/mcp/` - FastMCP tool organization patterns
64
+ - **Structured Logging:** Uses ACB logger with correlation IDs and context binding
65
+ - **MCP Server Structure:** Clean separation of concerns (tools, adapters, settings)
66
+
67
+ When implementing adapters, **always reference these codebases** for proven ACB patterns. Don't guess at ACB patterns - look at working production code.
68
+
69
+ ## Development Commands
70
+
71
+ ### Environment Setup
72
+
73
+ ```bash
74
+ # Install with development dependencies (recommended)
75
+ uv sync --group dev
76
+
77
+ # Or with pip
78
+ pip install -e ".[dev]"
79
+ ```
80
+
81
+ ### Testing
82
+
83
+ ```bash
84
+ # Run all tests with coverage (requires 90% minimum)
85
+ uv run pytest
86
+
87
+ # Run specific test file
88
+ uv run pytest tests/test_config.py -v
89
+
90
+ # Run with coverage report
91
+ uv run pytest --cov=mcp_common --cov-report=html
92
+
93
+ # Run only unit tests
94
+ uv run pytest -m unit
95
+
96
+ # Run only integration tests
97
+ uv run pytest -m integration
98
+
99
+ # Skip slow tests (performance benchmarks)
100
+ uv run pytest -m "not slow"
101
+
102
+ # Run specific test by name
103
+ uv run pytest tests/test_http_client.py::test_connection_pooling -v
104
+ ```
105
+
106
+ ### Code Quality
107
+
108
+ ```bash
109
+ # Format code (Ruff)
110
+ uv run ruff format
111
+
112
+ # Check formatting without changes
113
+ uv run ruff format --check
114
+
115
+ # Lint code
116
+ uv run ruff check
117
+
118
+ # Auto-fix linting issues
119
+ uv run ruff check --fix
120
+
121
+ # Type checking (MyPy with strict mode)
122
+ uv run mypy mcp_common tests
123
+
124
+ # Security scan (Bandit)
125
+ uv run bandit -r mcp_common
126
+
127
+ # Run all quality checks (format + lint + type check + test)
128
+ uv run ruff format && uv run ruff check && uv run mypy mcp_common tests && uv run pytest
129
+ ```
130
+
131
+ ### Using Hatch Scripts (Alternative)
132
+
133
+ ```bash
134
+ hatch run test # Run tests
135
+ hatch run test-cov # Tests with coverage
136
+ hatch run lint # Lint only
137
+ hatch run format # Format code
138
+ hatch run type-check # Type check
139
+ hatch run security # Security scan
140
+ hatch run all # All checks
141
+ ```
142
+
143
+ ## Package Structure
144
+
145
+ ```
146
+ mcp_common/
147
+ ├── __init__.py # Package registration, public API exports
148
+ ├── adapters/
149
+ │ ├── __init__.py # HTTPClientAdapter exports
150
+ │ └── http/
151
+ │ ├── __init__.py
152
+ │ └── client.py # ✅ HTTPClientAdapter (connection pooling)
153
+ ├── config/
154
+ │ ├── __init__.py # MCPBaseSettings, ValidationMixin exports
155
+ │ ├── base.py # ✅ MCPBaseSettings (YAML + env vars)
156
+ │ └── validation_mixin.py # ✅ ValidationMixin for Pydantic models
157
+ ├── middleware/
158
+ │ ├── __init__.py
159
+ │ └── rate_limit_config.py # 🚧 Rate limit configuration (needs ACB migration)
160
+ ├── security/
161
+ │ ├── __init__.py # Security utilities exports
162
+ │ ├── api_keys.py # ✅ APIKeyValidator (format validation)
163
+ │ └── sanitization.py # ✅ Sanitize user inputs, filter data
164
+ ├── ui/
165
+ │ ├── __init__.py # ServerPanels exports
166
+ │ └── panels.py # ✅ ServerPanels (Rich UI panels)
167
+ ├── exceptions.py # ✅ Custom exception hierarchy
168
+ ├── health.py # ✅ Health check models (HealthStatus, ComponentHealth)
169
+ └── http_health.py # ✅ HTTP health check functions
170
+
171
+ tests/
172
+ ├── conftest.py # Shared pytest fixtures
173
+ ├── test_config.py # MCPBaseSettings tests
174
+ ├── test_config_security.py # Security integration tests
175
+ ├── test_config_validation_mixin.py # ValidationMixin tests
176
+ ├── test_health.py # Health check system tests
177
+ ├── test_http_client.py # HTTPClientAdapter tests
178
+ ├── test_http_health.py # HTTP health check tests
179
+ ├── test_rate_limit_config.py # Rate limit configuration tests
180
+ ├── test_security_api_keys.py # API key validation tests
181
+ ├── test_security_sanitization.py # Sanitization tests
182
+ ├── test_ui_panels.py # ServerPanels tests
183
+ ├── test_version.py # Version import tests
184
+ └── performance/ # Performance benchmarks
185
+ └── test_http_pooling.py
186
+
187
+ examples/
188
+ ├── README.md # Example documentation
189
+ ├── settings/
190
+ │ └── weather.yaml # Example YAML configuration
191
+ └── weather_server.py # ✅ Complete working Weather MCP server
192
+ ```
193
+
194
+ **Note:** There is NO `logging/` directory - ACB logger is used directly via `LoggerProtocol` injection.
195
+
196
+ ## Architecture Overview
197
+
198
+ ### ACB-Native Adapter Pattern
199
+
200
+ All adapters in this library follow the ACB adapter pattern:
201
+
202
+ ```python
203
+ from acb.config import AdapterBase, Settings
204
+ from acb.adapters.logger import LoggerProtocol
205
+ from acb.adapters import AdapterStatus, AdapterMetadata, AdapterCapability
206
+ from uuid import UUID
207
+ from contextlib import suppress
208
+
209
+ # Static UUID7 - generated once, hardcoded forever (NEVER use uuid4())
210
+ MODULE_ID = UUID("01947e12-3b4c-7d8e-9f0a-1b2c3d4e5f6a")
211
+ MODULE_STATUS = AdapterStatus.STABLE # Enum, not string
212
+
213
+ MODULE_METADATA = AdapterMetadata(
214
+ module_id=MODULE_ID,
215
+ name="Example Adapter",
216
+ category="category",
217
+ provider="provider",
218
+ version="1.0.0",
219
+ acb_min_version="0.19.0",
220
+ status=MODULE_STATUS,
221
+ capabilities=[AdapterCapability.ASYNC_OPERATIONS],
222
+ required_packages=["package>=1.0.0"],
223
+ description="Adapter description",
224
+ )
225
+
226
+
227
+ class ExampleAdapter(AdapterBase):
228
+ settings: ExampleSettings | None = None
229
+ logger: LoggerProtocol # Injected by ACB - NEVER create Logger()
230
+
231
+ def __init__(self, **kwargs):
232
+ super().__init__(**kwargs) # REQUIRED: Call parent constructor
233
+ if self.settings is None:
234
+ self.settings = ExampleSettings()
235
+
236
+ async def _create_client(self):
237
+ """Lazy initialization lifecycle method."""
238
+ # Initialize resources
239
+ self.logger.info("Resource initialized")
240
+
241
+ async def _cleanup_resources(self):
242
+ """Cleanup on shutdown lifecycle method."""
243
+ # Close resources
244
+ self.logger.info("Resource closed")
245
+
246
+
247
+ # Auto-register with DI container at module level
248
+ with suppress(Exception):
249
+ depends.set(ExampleAdapter)
250
+ ```
251
+
252
+ ### Critical Pattern Rules
253
+
254
+ 1. **MODULE_ID must be static UUID7** - Generated once during implementation, then hardcoded forever (NOT `uuid4()`)
255
+ 1. **MODULE_STATUS is enum** - Use `AdapterStatus.STABLE`, not string `"stable"`
256
+ 1. **Logger is injected** - Type hint `logger: LoggerProtocol`, ACB injects automatically
257
+ 1. \*\*Always call super().__init__(**kwargs)** - Required for ACB lifecycle
258
+ 1. **Implement lifecycle methods** - `_create_client()` and `_cleanup_resources()`
259
+ 1. **DI registration at module level** - Use `with suppress(Exception): depends.set()`
260
+
261
+ ## Implementation Guidelines
262
+
263
+ ### When Implementing a New Adapter
264
+
265
+ 1. **Read `docs/ACB_FOUNDATION.md`** for ACB fundamentals (adapters, DI, lifecycle)
266
+ 1. **Read relevant documentation** in `docs/` for the specific feature
267
+ 1. **Generate static UUID7** for MODULE_ID (use `uuidv7` CLI or Python uuid7 library)
268
+ 1. **Create MODULE_METADATA** with all required fields
269
+ 1. **Reference production code** in `../crackerjack`, `../session-mgmt-mcp`, or `../fastblocks`
270
+ - For rate limiting: Study `crackerjack/mcp/rate_limiter.py`
271
+ - For Rich UI: Study `crackerjack/ui/panels.py`
272
+ - For ACB patterns: Study `session-mgmt-mcp/adapters/`
273
+ 1. **Implement lifecycle methods** (`_create_client()`, `_cleanup_resources()`)
274
+ 1. **Write tests first** (TDD approach, target 90%+ coverage)
275
+ 1. **Register at module level** with `suppress(Exception): depends.set()`
276
+ 1. **Run quality checks** with `uv run pytest` and linting
277
+
278
+ **Development Cycle:**
279
+
280
+ ```bash
281
+ # 1. Implement feature
282
+ vim mcp_common/adapters/rate_limit/limiter.py
283
+
284
+ # 2. Write tests
285
+ vim tests/test_rate_limiter.py
286
+
287
+ # 3. Run tests
288
+ uv run pytest tests/test_rate_limiter.py -v
289
+
290
+ # 4. Run quality checks
291
+ uv run ruff format
292
+ uv run ruff check
293
+ uv run mypy mcp_common tests
294
+
295
+ # 5. Run full test suite with coverage
296
+ uv run pytest --cov=mcp_common
297
+
298
+ # 6. Commit when all checks pass
299
+ git add . && git commit -m "feat: implement rate limiter adapter"
300
+ ```
301
+
302
+ ### Settings Pattern
303
+
304
+ All settings extend ACB's `acb.config.Settings`, not raw Pydantic:
305
+
306
+ ```python
307
+ from mcp_common.config import MCPBaseSettings
308
+ from pydantic import Field
309
+
310
+
311
+ class MyServerSettings(MCPBaseSettings):
312
+ """Server configuration using ACB Settings.
313
+
314
+ Loads from (in order):
315
+ 1. settings/local.yaml (gitignored)
316
+ 2. settings/my-server.yaml
317
+ 3. Environment variables MY_SERVER_*
318
+ 4. Defaults below
319
+ """
320
+
321
+ api_key: str = Field(description="API key")
322
+ timeout: int = Field(default=30, description="Timeout in seconds")
323
+ ```
324
+
325
+ ### Dependency Injection Usage
326
+
327
+ All adapters use ACB's dependency injection:
328
+
329
+ ```python
330
+ from acb.depends import depends
331
+ from mcp_common.adapters.http import HTTPClientAdapter
332
+
333
+
334
+ @mcp.tool()
335
+ async def my_tool():
336
+ # Get adapter from DI container (singleton)
337
+ http = depends(HTTPClientAdapter)
338
+ client = await http._create_client()
339
+ response = await client.get("https://api.example.com")
340
+ return response.json()
341
+ ```
342
+
343
+ ### Testing with DI
344
+
345
+ Tests can mock adapters via dependency injection:
346
+
347
+ ```python
348
+ from acb.depends import depends
349
+ import pytest
350
+
351
+
352
+ @pytest.fixture
353
+ def mock_http():
354
+ """Create mock HTTP adapter."""
355
+ mock = MockHTTPClientAdapter()
356
+ depends.set(HTTPClientAdapter, mock)
357
+ return mock
358
+
359
+
360
+ async def test_my_tool(mock_http):
361
+ """Test uses mock automatically via DI."""
362
+ result = await my_tool()
363
+ assert mock_http.called
364
+ ```
365
+
366
+ ## Quality Standards
367
+
368
+ This project follows **strict quality standards** enforced by test suite and linting:
369
+
370
+ - **Test Coverage:** Minimum 90% (enforced by pytest with `--cov-fail-under=90`)
371
+ - **Type Safety:** Strict MyPy (`strict = true` in pyproject.toml)
372
+ - Full type hints required for all functions and methods
373
+ - No `Any` types without justification
374
+ - Type stubs (`.pyi`) for external dependencies if needed
375
+ - **Code Style:** Ruff with comprehensive rule set (136 enabled rules - see pyproject.toml)
376
+ - Line length: 100 characters
377
+ - Python 3.13+ target
378
+ - Google-style docstrings
379
+ - **Security:** Bandit security scanning (no security issues tolerated)
380
+ - **Documentation:**
381
+ - Google-style docstrings required for all public APIs
382
+ - Type hints serve as primary documentation for parameters/returns
383
+ - Complex logic requires inline comments explaining "why", not "what"
384
+
385
+ **Before committing, always run:**
386
+
387
+ ```bash
388
+ # Format + lint + type check + test
389
+ uv run ruff format && uv run ruff check && uv run mypy mcp_common tests && uv run pytest
390
+ ```
391
+
392
+ ## Key Documentation Files
393
+
394
+ - **`README.md`** - User-facing documentation with quickstart and examples
395
+ - **`docs/ACB_FOUNDATION.md`** - **START HERE** - ACB prerequisite guide (MUST READ before implementing)
396
+ - **`docs/ARCHITECTURE.md`** - Complete technical design (if exists - check docs/)
397
+ - **`docs/IMPLEMENTATION_PLAN.md`** - Phased implementation roadmap (if exists)
398
+ - **`docs/MCP_ECOSYSTEM_CRITICAL_AUDIT.md`** - Analysis of 9 production servers that informed design
399
+ - **`docs/SECURITY_IMPLEMENTATION.md`** - Security features and patterns
400
+ - **`docs/PHASE3_*.md`** - Phase-specific implementation documentation
401
+ - **`examples/README.md`** - Example server documentation
402
+
403
+ ## Common Pitfalls to Avoid
404
+
405
+ 1. **Using `uuid4()` for MODULE_ID** - Must be static UUID7, generated once and hardcoded
406
+ 1. **Creating Logger manually** - Logger is injected by ACB via `LoggerProtocol`
407
+ 1. **String for MODULE_STATUS** - Must use `AdapterStatus.STABLE` enum
408
+ 1. **Forgetting `super().__init__(**kwargs)`** - Required for ACB lifecycle
409
+ 1. **Missing MODULE_METADATA** - Required for ACB component discovery
410
+ 1. **DI registration in `__init__`** - Must be at module level with `suppress(Exception)`
411
+ 1. **Not implementing lifecycle methods** - `_create_client()` and `_cleanup_resources()` required
412
+ 1. **Ignoring test coverage** - Must maintain 90%+ coverage (enforced by CI)
413
+ 1. **Skipping type hints** - Strict MyPy requires full type coverage
414
+
415
+ ## Implemented Components (v2.0.0)
416
+
417
+ ### ✅ Core Configuration (mcp_common/config/)
418
+
419
+ - **MCPBaseSettings** - YAML + environment variable configuration
420
+ - Extends `acb.config.Settings`
421
+ - Automatic YAML loading from `settings/{name}.yaml`
422
+ - Environment variable overrides
423
+ - Path expansion (`~` → home directory)
424
+ - API key validation methods (`get_api_key()`, `get_api_key_secure()`, `get_masked_key()`)
425
+ - **MCPServerSettings** - Extended settings with common MCP server fields
426
+ - **ValidationMixin** - Reusable Pydantic validation logic
427
+
428
+ ### ✅ HTTP Client Adapter (mcp_common/adapters/http/)
429
+
430
+ - **HTTPClientAdapter** - Connection pooling with httpx
431
+ - 11x performance improvement vs per-request clients
432
+ - Automatic lifecycle management
433
+ - Configurable pool size, timeouts, retries
434
+ - ACB-native with DI registration
435
+
436
+ ### ✅ Security Utilities (mcp_common/security/)
437
+
438
+ - **APIKeyValidator** - Format validation for API keys
439
+ - Provider-specific patterns (OpenAI, Anthropic, Mailgun, etc.)
440
+ - Format validation with detailed error messages
441
+ - Key masking for safe logging
442
+ - **Sanitization** - Input sanitization and data filtering
443
+ - HTML/SQL injection prevention
444
+ - Path traversal protection
445
+ - Data redaction for sensitive fields
446
+
447
+ ### ✅ Health Checks (mcp_common/health.py, mcp_common/http_health.py)
448
+
449
+ - **HealthStatus** - Enum for component health states
450
+ - **ComponentHealth** - Model for component health information
451
+ - **HealthCheckResponse** - Comprehensive health check responses
452
+ - **HTTP Health Functions** - Check HTTP connectivity and client health
453
+
454
+ ### ✅ Rich UI Panels (mcp_common/ui/panels.py)
455
+
456
+ - **ServerPanels** - Professional console output with Rich
457
+ - `startup_success()` - Startup panel with features list
458
+ - `error()` - Error display with suggestions
459
+ - `status_table()` - Status tables with health indicators
460
+ - `notification()` - General notification panels
461
+
462
+ ### ✅ Exception Hierarchy (mcp_common/exceptions.py)
463
+
464
+ - **MCPServerError** - Base exception for all MCP errors
465
+ - **ServerConfigurationError** - Configuration validation errors
466
+ - **ServerInitializationError** - Startup failures
467
+ - **DependencyMissingError** - Missing required dependencies
468
+ - **CredentialValidationError** - API key/credential errors
469
+ - **APIKeyMissingError** - Missing API keys
470
+ - **APIKeyFormatError** - Invalid API key format
471
+ - **APIKeyLengthError** - API key length validation
472
+
473
+ ### 🚧 Rate Limiting (mcp_common/middleware/rate_limit_config.py)
474
+
475
+ - **RateLimitConfig** - Configuration model for rate limiting
476
+ - **Needs Migration:** Convert to ACB adapter pattern with MODULE_ID/STATUS/METADATA
477
+ - **Reference:** `crackerjack/mcp/rate_limiter.py` for token bucket implementation
478
+
479
+ ## Working Example
480
+
481
+ See `examples/weather_server.py` for a complete working MCP server demonstrating:
482
+
483
+ - HTTPClientAdapter with connection pooling
484
+ - MCPBaseSettings with YAML configuration
485
+ - ServerPanels for startup UI
486
+ - ACB dependency injection
487
+ - FastMCP tool integration
488
+ - Error handling and validation
489
+
490
+ **Run the example:**
491
+
492
+ ```bash
493
+ cd examples
494
+ python weather_server.py
495
+ ```
496
+
497
+ ## Version and Release Information
498
+
499
+ - **Current Version:** 2.0.0 (partially implemented)
500
+ - **Breaking Changes from v1.x:**
501
+ - ACB is now required (was optional)
502
+ - HTTP client is `HTTPClientAdapter` via DI (was `get_http_client()` function)
503
+ - Logging uses ACB Logger (no `MCPLogger` wrapper)
504
+ - Rate limiting will be `RateLimiterAdapter` (migration in progress)
505
+ - Settings extend `acb.config.Settings` (not raw Pydantic)
506
+
507
+ ## External Dependencies and Their Roles
508
+
509
+ - **ACB (acb>=0.19.0)** - Core framework (adapters, DI, logger, settings, console) - **editable install from ../acb**
510
+ - **httpx>=0.27.0** - HTTP client with async support (used in HTTPClientAdapter)
511
+ - **pydantic>=2.10.0** - Data validation (used with ACB Settings)
512
+ - **pydantic-settings>=2.7.0** - Settings management
513
+ - **fastmcp>=0.2.0** - MCP protocol implementation
514
+ - **Rich** (via acb.console) - Terminal UI for ServerPanels
515
+
516
+ ## Development Dependencies
517
+
518
+ - **pytest>=8.3.0** - Test framework
519
+ - **pytest-asyncio>=0.24.0** - Async test support
520
+ - **pytest-cov>=6.0.0** - Coverage reporting
521
+ - **pytest-mock>=3.14.0** - Mocking utilities
522
+ - **hypothesis>=6.122.0** - Property-based testing
523
+ - **ruff>=0.8.0** - Linting and formatting
524
+ - **mypy>=1.13.0** - Static type checking
525
+ - **bandit>=1.8.0** - Security scanning
526
+ - **respx>=0.21.0** - HTTP mocking for httpx
527
+ - **crackerjack** - Reference implementation
528
+ - **session-mgmt-mcp** - Reference implementation