ArchVanguard-MCP
by OxManifesto
README.md
<!--
GitHub topics: ai-agent llm-tools mcp langchain openai-function-calling pydantic
architecture static-analysis import-linter dependency-graph code-quality
-->
# ArchVanguard-MCP
Framework-agnostic architecture-rule enforcement for AI agents: analyze a Python codebase's import graph against a declarative ruleset and report layer, forbidden-import, and cycle violations with file and line.
[](https://github.com/MrGuevara4/ArchVanguard-MCP/actions/workflows/ci.yml)
[](https://github.com/MrGuevara4/ArchVanguard-MCP)
[](https://pypi.org/project/archvanguard-mcp/)
[](https://www.python.org/)
[](LICENSE)
[](https://github.com/astral-sh/ruff)
[](https://pypi.org/project/archvanguard-mcp/)
## Abstract
Autonomous coding agents refactor, generate, and merge code faster than humans can review architecture. ArchVanguard-MCP gives an agent (or a CI job) one deterministic question: *does this codebase obey its declared architecture?* It parses a Python package's imports with the standard-library `ast` module — **never executing the target code** — builds the module dependency graph, and evaluates a declarative ruleset for layer-dependency violations, forbidden imports, and import cycles, returning each finding with a precise file and line. The core is a pure, framework-free Python library wrapped by thin optional adapters for OpenAI, Anthropic, LangChain, LlamaIndex, an MCP stdio server, and a CLI, so the same engine binds to any agent stack without conditionals.
## Feature matrix
| Framework | Status | Extra | Entry point |
|-----------|--------|-------|-------------|
| Core library (sync + async) | ✅ | *(none)* | `archvanguard_mcp.core.execute` |
| OpenAI function-calling | ✅ | `openai` | `adapters.openai_tool.tool_spec` / `run_tool_call` |
| Anthropic tool-use | ✅ | `anthropic` | `adapters.anthropic_tool.tool_spec` / `handle_tool_use` |
| LangChain | ✅ | `langchain` | `adapters.langchain_tool.build_tool` |
| LlamaIndex | ✅ | `llamaindex` | `adapters.llamaindex_tool.build_tool` |
| MCP (stdio, JSON-RPC 2.0) | ✅ | *(none; stdlib)* | `python -m archvanguard_mcp.adapters.mcp_server` |
| CLI | ✅ | *(none)* | `archvanguard` |
## Architecture
```mermaid
flowchart TD
A[AI Agent / CI / Human] -->|tool call| S[Generated Tool Schema]
S --> AD[Adapter layer<br/>openai · anthropic · langchain · llamaindex · mcp · cli]
AD -->|typed args| V[Validation & sanitization<br/>paths · limits · rules]
V -->|invalid| E[Structured error envelope<br/>stable code + details]
V -->|valid| C[Core engine<br/>ast parse → graph → rule eval]
C --> R[Response envelope<br/>violations + summary]
C -->|failure| E
E --> AD
R --> AD
AD --> A
```
The core (`archvanguard_mcp.core`) imports no AI framework. Framework code lives only in adapters, behind optional extras that fail with a clear, actionable error if not installed.
## Quickstart
```bash
# 1. Install
pip install archvanguard-mcp
# 2. Write a ruleset (rules.json)
cat > rules.json <<'JSON'
{
"layers": [
{"name": "core", "patterns": ["myapp.core", "myapp.core.*"]},
{"name": "adapters", "patterns": ["myapp.adapters", "myapp.adapters.*"]}
],
"allowed_dependencies": [{"from_layer": "adapters", "to_layer": "core"}],
"forbidden_imports": [{"importer": "myapp.core.*", "forbidden": "langchain*"}],
"allow_cycles": false
}
JSON
# 3. Enforce (exit code 1 if any violation — use it as a merge gate)
archvanguard --root ./src/myapp --rules rules.json
```
## Framework integration
### OpenAI (native function-calling)
```python
from openai import OpenAI
from archvanguard_mcp.adapters import openai_tool
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Check ./src/myapp against rules.json"}],
tools=[openai_tool.tool_spec()],
)
for call in response.choices[0].message.tool_calls or []:
tool_message = openai_tool.run_tool_call(call) # dispatches to the engine
# append tool_message to your messages and continue the loop
```
### Anthropic (native tool-use)
```python
import anthropic
from archvanguard_mcp.adapters import anthropic_tool
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=[anthropic_tool.tool_spec()],
messages=[{"role": "user", "content": "Verify the layering of ./src/myapp"}],
)
for block in message.content:
if block.type == "tool_use":
tool_result = anthropic_tool.handle_tool_use(block) # -> tool_result block
```
### LangChain
```python
from archvanguard_mcp.adapters import langchain_tool
tool = langchain_tool.build_tool() # a StructuredTool with args_schema
# agent = create_react_agent(llm, [tool]) ; agent.invoke(...)
```
### LlamaIndex
```python
from archvanguard_mcp.adapters import llamaindex_tool
tool = llamaindex_tool.build_tool() # a FunctionTool
# agent = ReActAgent.from_tools([tool], llm=llm) ; agent.chat(...)
```
### MCP server
Run `python -m archvanguard_mcp.adapters.mcp_server`, and register it in your MCP
client (`claude_desktop_config.json` or `mcp.json`):
```json
{
"mcpServers": {
"archvanguard": {
"command": "python",
"args": ["-m", "archvanguard_mcp.adapters.mcp_server"]
}
}
}
```
## API reference
Tool name: **`enforce_architecture`**. Full field tables are in
[`docs/SCHEMA.md`](docs/SCHEMA.md); the machine schemas are generated into
[`schemas/`](schemas/).
| Input field | Type | Required | Notes |
|-------------|------|----------|-------|
| `root_path` | string | yes | Existing directory to scan. |
| `language` | `"python"` | no | Only Python is supported. |
| `rules` | object | no | `layers`, `allowed_dependencies`, `forbidden_imports`, `allow_cycles`. |
| `include` / `exclude` | string[] | no | Module-name globs. |
| `strict_parse` | bool | no | Abort on first unparseable file. |
| `config` | object | no | Hard-bounded `max_files`, `max_file_bytes`, `wall_clock_ms`, `max_dir_depth`, `parallel`. |
The response contains `status`, `correlation_id`, `violations[]` (`rule_type`,
`file`, `line`, `from_module`, `to_module`, `message`), a `summary`, and an
`error` envelope when `status == "error"`.
## Error codes
| Code | Meaning | Retryable | Remediation |
|------|---------|-----------|-------------|
| `VALIDATION_ERROR` | Arguments failed schema/semantic validation | no | Fix the request per `details`. |
| `PATH_NOT_FOUND` | `root_path` does not exist | no | Provide an existing directory. |
| `PATH_NOT_ALLOWED` | Not a directory, or symlink/traversal escape | no | Point at a real directory inside the tree. |
| `LIMIT_EXCEEDED` | A hard cap (files, size, patterns, concurrency) was hit | no | Narrow scope or lower the workload. |
| `PARSE_ERROR` | A file failed to parse (only fatal with `strict_parse`) | no | Fix the file or disable `strict_parse`. |
| `TIMEOUT` | Wall-clock budget exceeded | yes | Raise `wall_clock_ms` (≤30000) or narrow scope. |
| `DEPENDENCY_MISSING` | An adapter extra is not installed | no | `pip install "archvanguard-mcp[<extra>]"`. |
| `INTERNAL_ERROR` | Unexpected fault (details redacted) | yes | Retry; report if persistent. |
## Performance
Measured on 16 cores, Linux, Python 3.13 (see [`docs/BENCHMARKS.md`](docs/BENCHMARKS.md);
reproduce with `python scripts/benchmark.py`):
| Modules | p50 | p95 |
|--------:|----:|----:|
| 250 | 18.5 ms | 19.6 ms |
| 1000 | 125 ms | 132 ms |
| 3000 | 374 ms | 390 ms |
| 4500 | 547 ms | 565 ms |
p95 stays under the 2000 ms budget across the full supported range (up to the
5000-file hard cap).
## Security
The analyzer never executes target code, rejects path traversal and symlink
escape, enforces hard resource caps, and accepts only `fnmatch` globs (no raw
regex, so no ReDoS surface). See [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md).
Report vulnerabilities privately per [`SECURITY.md`](SECURITY.md) — acknowledgement
within 3 business days.
## Contributing
See [`CONTRIBUTING.md`](CONTRIBUTING.md). Dev setup:
```bash
pip install -e ".[all,dev]" && pre-commit install
make all # lint + type + coverage(≥90%) + schema + security + build
```
Commits follow [Conventional Commits](https://www.conventionalcommits.org/). The
core must stay framework-free (INV-1); schemas are generated, never hand-edited.
## Roadmap
- [ ] Additional target languages (JavaScript/TypeScript, Go) behind the `language` enum.
- [ ] Allowlist for statically resolvable dynamic imports.
- [ ] Optional per-rule severity and baseline/ratchet mode for legacy repos.
- [ ] SARIF output for code-scanning integration.
## Citation
```bibtex
@software{fatih_archvanguard_mcp_2026,
author = {Farhang Fatih},
title = {ArchVanguard-MCP: Framework-agnostic architecture-rule enforcement for AI agents},
year = {2026},
version = {0.1.0},
license = {MIT},
url = {https://github.com/MrGuevara4/ArchVanguard-MCP}
}
```
## License
MIT © Farhang Fatih. See [`LICENSE`](LICENSE).
---
Author & Principal Architect: **Farhang Fatih**
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues