adforge 0.1.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.
- adforge-0.1.0/.claude/settings.local.json +8 -0
- adforge-0.1.0/.env.example +17 -0
- adforge-0.1.0/.gitignore +26 -0
- adforge-0.1.0/.python-version +1 -0
- adforge-0.1.0/CLAUDE.md +68 -0
- adforge-0.1.0/Makefile +56 -0
- adforge-0.1.0/PKG-INFO +161 -0
- adforge-0.1.0/README.md +133 -0
- adforge-0.1.0/pyproject.toml +64 -0
- adforge-0.1.0/skills/solution-architect/SKILL.md +104 -0
- adforge-0.1.0/src/adforge/__init__.py +3 -0
- adforge-0.1.0/src/adforge/models/__init__.py +24 -0
- adforge-0.1.0/src/adforge/models/common.py +23 -0
- adforge-0.1.0/src/adforge/models/cost.py +42 -0
- adforge-0.1.0/src/adforge/models/dag.py +48 -0
- adforge-0.1.0/src/adforge/models/problem.py +21 -0
- adforge-0.1.0/src/adforge/models/solution.py +49 -0
- adforge-0.1.0/src/adforge/models/sub_problem.py +28 -0
- adforge-0.1.0/src/adforge/persistence/__init__.py +20 -0
- adforge-0.1.0/src/adforge/persistence/db.py +84 -0
- adforge-0.1.0/src/adforge/persistence/migrations/001_initial.sql +103 -0
- adforge-0.1.0/src/adforge/persistence/repositories/__init__.py +1 -0
- adforge-0.1.0/src/adforge/persistence/repositories/cost_repository.py +172 -0
- adforge-0.1.0/src/adforge/persistence/repositories/dag_repository.py +110 -0
- adforge-0.1.0/src/adforge/persistence/repositories/problem_repository.py +72 -0
- adforge-0.1.0/src/adforge/persistence/repositories/solution_repository.py +98 -0
- adforge-0.1.0/src/adforge/persistence/repositories/sub_problem_repository.py +99 -0
- adforge-0.1.0/src/adforge/pricing/__init__.py +20 -0
- adforge-0.1.0/src/adforge/pricing/aws.py +151 -0
- adforge-0.1.0/src/adforge/pricing/azure.py +95 -0
- adforge-0.1.0/src/adforge/pricing/base.py +39 -0
- adforge-0.1.0/src/adforge/pricing/databricks.py +52 -0
- adforge-0.1.0/src/adforge/pricing/gcp.py +53 -0
- adforge-0.1.0/src/adforge/pricing/manager.py +40 -0
- adforge-0.1.0/src/adforge/pricing/roles.py +79 -0
- adforge-0.1.0/src/adforge/prompts/__init__.py +40 -0
- adforge-0.1.0/src/adforge/prompts/problem_decomposition.py +41 -0
- adforge-0.1.0/src/adforge/resources/__init__.py +40 -0
- adforge-0.1.0/src/adforge/server.py +88 -0
- adforge-0.1.0/src/adforge/tools/__init__.py +40 -0
- adforge-0.1.0/src/adforge/tools/cost.py +101 -0
- adforge-0.1.0/src/adforge/tools/decompose.py +153 -0
- adforge-0.1.0/src/adforge/tools/problem.py +101 -0
- adforge-0.1.0/src/adforge/tools/solution.py +169 -0
- adforge-0.1.0/src/adforge/tools/solution_cost.py +125 -0
- adforge-0.1.0/src/adforge/utils/__init__.py +1 -0
- adforge-0.1.0/src/adforge/utils/logging.py +10 -0
- adforge-0.1.0/tests/conftest.py +43 -0
- adforge-0.1.0/tests/test_models.py +29 -0
- adforge-0.1.0/tests/test_pricing.py +68 -0
- adforge-0.1.0/tests/test_repositories.py +113 -0
- adforge-0.1.0/tests/test_server.py +26 -0
- adforge-0.1.0/tests/test_tools.py +107 -0
- adforge-0.1.0/uv.lock +1106 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# .env.example — copy to .env and fill in real values
|
|
2
|
+
|
|
3
|
+
# Optional: override server name
|
|
4
|
+
MCP_SERVER_NAME=adforge
|
|
5
|
+
|
|
6
|
+
# Optional: log level (DEBUG, INFO, WARN, ERROR)
|
|
7
|
+
LOG_LEVEL=INFO
|
|
8
|
+
|
|
9
|
+
# Persistent storage path (defaults to project root: adforge.db)
|
|
10
|
+
# Use an absolute path if the server is launched from varying directories.
|
|
11
|
+
ADFORGE_DB_PATH=adforge.db
|
|
12
|
+
|
|
13
|
+
# Pricing cache TTL in seconds (default: 86400 = 24 hours)
|
|
14
|
+
ADFORGE_CACHE_TTL=86400
|
|
15
|
+
|
|
16
|
+
# Optional AWS region for pricing queries (default: us-east-1)
|
|
17
|
+
AWS_PRICING_REGION=us-east-1
|
adforge-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Testing / coverage
|
|
13
|
+
.pytest_cache
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
|
|
17
|
+
# Environment
|
|
18
|
+
.env
|
|
19
|
+
|
|
20
|
+
# IDE
|
|
21
|
+
.vscode/
|
|
22
|
+
.idea/
|
|
23
|
+
*.swp
|
|
24
|
+
|
|
25
|
+
# Lock files (optional — keep if you want reproducible builds)
|
|
26
|
+
# uv.lock
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
adforge-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
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 context
|
|
6
|
+
|
|
7
|
+
**AD Forge** (`adforge`) is a runtime-agnostic MCP (Model Context Protocol) server for data-driven solution architecture, written in Python 3.13 and managed with `uv`. It is designed to work with Claude Desktop, Hermes, OpenClaw, and any other MCP stdio client.
|
|
8
|
+
|
|
9
|
+
It ships with:
|
|
10
|
+
- An MCP stdio server exposing tools, resources, and prompts.
|
|
11
|
+
- A Hermes-compatible skill under `skills/solution-architect/SKILL.md`.
|
|
12
|
+
- Plain importable Python packages (`models`, `persistence`, `pricing`) so other agents can reuse the logic directly without running the MCP server.
|
|
13
|
+
|
|
14
|
+
Authors: Amirthanathan R (`amirth300324@gmail.com`) and Dhivya GL (`gldhivya1@gmail.com`).
|
|
15
|
+
|
|
16
|
+
## Common commands
|
|
17
|
+
|
|
18
|
+
Use `uv run` for all project-local Python commands. It resolves the locked environment from `uv.lock`.
|
|
19
|
+
|
|
20
|
+
- **Install dev dependencies and editable package:** `uv pip install -e ".[dev]"`
|
|
21
|
+
- **Run the server locally:** `uv run python -m adforge.server`
|
|
22
|
+
- **Run the console-script entry point:** `uv run adforge-mcp`
|
|
23
|
+
- **Run all tests:** `uv run pytest tests/ -q`
|
|
24
|
+
- **Run a single test file:** `uv run pytest tests/test_tools.py -v`
|
|
25
|
+
- **Lint:** `uv run ruff check src/ tests/`
|
|
26
|
+
- **Format:** `uv run ruff format src/ tests/`
|
|
27
|
+
- **Type check:** `uv run mypy src/`
|
|
28
|
+
|
|
29
|
+
The `Makefile` provides the same targets (`install-dev`, `test`, `test-verbose`, `lint`, `format`, `check`, `clean`), but the project default is `uv run`.
|
|
30
|
+
|
|
31
|
+
To configure the server, copy `.env.example` to `.env`. Useful variables:
|
|
32
|
+
- `ADFORGE_DB_PATH` — SQLite file path (default: project root `adforge.db`).
|
|
33
|
+
- `ADFORGE_CACHE_TTL` — pricing cache TTL in seconds (default: 86400).
|
|
34
|
+
- `AWS_PRICING_REGION` — AWS region for pricing queries (default: `us-east-1`).
|
|
35
|
+
- `LOG_LEVEL`, `MCP_SERVER_NAME`.
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
The package lives at `src/adforge/`.
|
|
40
|
+
|
|
41
|
+
- **`server.py`** is the thin MCP entry point. It creates a single `mcp.server.Server` instance and wires the decorators (`list_tools`, `call_tool`, `list_resources`, `read_resource`, `list_prompts`, `get_prompt`) to the corresponding registries. Tool/prompt modules are imported at module load time so they self-register.
|
|
42
|
+
- **`tools/`**, **`resources/`**, and **`prompts/`** each contain a registry (`__init__.py`) and feature modules. A feature module imports the global `registry` and calls `registry.register(mcp_object, handler)` at import time. Tool/prompt handlers are async and accept flat JSON Schema input shapes for broad agent compatibility.
|
|
43
|
+
- **`models/`** holds Pydantic models: `Problem`, `Solution`, `SubProblem`, `SolutionNode`/`SolutionEdge` (DAG), and `CostLineItem`/`CostSummary`.
|
|
44
|
+
- **`persistence/`** is a SQLite-backed repository layer using plain `sqlite3`. `db.py` handles connections and SQL migrations under `persistence/migrations/`. Repositories: `ProblemRepository`, `SolutionRepository`, `SubProblemRepository`, `DagRepository`, `CostRepository`, plus `PricingCache`.
|
|
45
|
+
- **`pricing/`** contains provider wrappers: `aws` (public AWS Price List API), `azure` (Azure Retail Prices API), `gcp`/`databricks` (stubs accepting `manual_rate`), and `roles` (public/free role-pricing defaults). `PricingManager` dispatches across providers and uses the SQLite `PricingCache`.
|
|
46
|
+
- **`utils/logging.py`** is a thin `structlog` wrapper.
|
|
47
|
+
|
|
48
|
+
To add a new tool, resource, or prompt: create a module under the appropriate directory, import the registry, call `registry.register(...)`, and import the module in `server.py`. Add a matching test under `tests/`. Keep tool input schemas flat and JSON Schema-compatible.
|
|
49
|
+
|
|
50
|
+
## Key workflow
|
|
51
|
+
|
|
52
|
+
1. `create_problem` stores a problem statement with tags.
|
|
53
|
+
2. `decompose_problem` breaks it into `SubProblem`s and, if given a `solution_id`, builds a sequential DAG.
|
|
54
|
+
3. `create_solution` produces a PR/issue-shaped `Solution` document.
|
|
55
|
+
4. `attach_cost_to_solution` fetches a price (AWS/Azure/role/etc.) and stores a `CostLineItem`.
|
|
56
|
+
5. `summarize_solution_cost` rolls up line items and writes a `CostSummary` back to the solution.
|
|
57
|
+
6. `add_solution_comment`, `add_solution_review`, and `update_solution_status` mirror GitHub PR/issue interactions.
|
|
58
|
+
|
|
59
|
+
## Hermes skill
|
|
60
|
+
|
|
61
|
+
`skills/solution-architect/SKILL.md` is a Hermes-compatible skill that describes the architecture workflow, design checklist, diagram conventions, and cost heuristics. It can be copied/symlinked into `~/.hermes/skills/solution-architect/` or loaded directly by clients that support in-repo skills.
|
|
62
|
+
|
|
63
|
+
## Notes
|
|
64
|
+
|
|
65
|
+
- Python 3.13 is required (`requires-python = ">=3.13"` in `pyproject.toml`, pinned in `.python-version`).
|
|
66
|
+
- `pyproject.toml` configures `ruff`, `mypy` (strict), and `pytest` (asyncio mode auto).
|
|
67
|
+
- `ruff check src/ tests/` and `mypy src/` are expected to pass.
|
|
68
|
+
- The README references `main.py` and `scripts/run_tests.sh`, but neither file currently exists in the repository; use the Makefile targets or `uv run` commands above instead.
|
adforge-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
.PHONY: install install-dev test test-verbose lint format check clean help
|
|
2
|
+
|
|
3
|
+
# Default target
|
|
4
|
+
.DEFAULT_GOAL := help
|
|
5
|
+
|
|
6
|
+
# Python binary: prefer .venv if it exists, otherwise system python
|
|
7
|
+
PYTHON := $(shell [ -f .venv/bin/python ] && echo .venv/bin/python || echo python)
|
|
8
|
+
|
|
9
|
+
# Virtual environment path
|
|
10
|
+
VENV := .venv
|
|
11
|
+
|
|
12
|
+
# Detect uv or fallback to pip
|
|
13
|
+
UV := $(shell command -v uv 2>/dev/null)
|
|
14
|
+
|
|
15
|
+
help: ## Show this help message
|
|
16
|
+
@echo "Available targets:"
|
|
17
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
|
18
|
+
awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'
|
|
19
|
+
|
|
20
|
+
install: ## Install production dependencies
|
|
21
|
+
ifdef UV
|
|
22
|
+
uv pip install -e .
|
|
23
|
+
else
|
|
24
|
+
$(PYTHON) -m pip install -e .
|
|
25
|
+
endif
|
|
26
|
+
|
|
27
|
+
install-dev: ## Install with dev dependencies (linting, testing, formatting)
|
|
28
|
+
ifdef UV
|
|
29
|
+
uv pip install -e ".[dev]"
|
|
30
|
+
else
|
|
31
|
+
$(PYTHON) -m pip install -e ".[dev]"
|
|
32
|
+
endif
|
|
33
|
+
|
|
34
|
+
test: ## Run the test suite (quiet)
|
|
35
|
+
$(PYTHON) -m pytest tests/ -q
|
|
36
|
+
|
|
37
|
+
test-verbose: ## Run the test suite (verbose)
|
|
38
|
+
$(PYTHON) -m pytest tests/ -v
|
|
39
|
+
|
|
40
|
+
lint: ## Run ruff and mypy
|
|
41
|
+
ruff check src/ tests/
|
|
42
|
+
mypy src/
|
|
43
|
+
|
|
44
|
+
format: ## Auto-format code with ruff
|
|
45
|
+
ruff format src/ tests/
|
|
46
|
+
|
|
47
|
+
check: lint test ## Run linting + tests (CI gate)
|
|
48
|
+
|
|
49
|
+
clean: ## Remove build artifacts, caches, and the virtual environment
|
|
50
|
+
rm -rf build/ dist/ wheels/ *.egg-info
|
|
51
|
+
rm -rf .pytest_cache .coverage htmlcov/
|
|
52
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
53
|
+
find . -type f -name "*.py[oc]" -delete 2>/dev/null || true
|
|
54
|
+
|
|
55
|
+
distclean: clean ## Full clean including virtual environment
|
|
56
|
+
rm -rf $(VENV)
|
adforge-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adforge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AD Forge — data-driven solution architecture with live cost estimates
|
|
5
|
+
Author-email: Amirthanathan R <amirth300324@gmail.com>, Dhivya GL <gldhivya1@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Requires-Python: >=3.13
|
|
14
|
+
Requires-Dist: boto3>=1.43.50
|
|
15
|
+
Requires-Dist: httpx>=0.27
|
|
16
|
+
Requires-Dist: mcp>=1.0.0
|
|
17
|
+
Requires-Dist: pydantic>=2.0
|
|
18
|
+
Requires-Dist: python-dotenv>=1.0
|
|
19
|
+
Requires-Dist: structlog>=24.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
22
|
+
Requires-Dist: pre-commit>=3.8; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# AD Forge
|
|
30
|
+
|
|
31
|
+
Runtime-agnostic MCP server for data-driven solution architecture, with bundled Hermes skills.
|
|
32
|
+
|
|
33
|
+
Works with any MCP stdio client (Claude Desktop, Hermes, OpenClaw, etc.). The core logic is also importable as plain Python packages.
|
|
34
|
+
|
|
35
|
+
Authors: Amirthanathan R (`amirth300324@gmail.com`) and Dhivya GL (`gldhivya1@gmail.com`).
|
|
36
|
+
|
|
37
|
+
## Project Structure
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
├── pyproject.toml # Package metadata, deps, tool config
|
|
41
|
+
├── README.md # This file
|
|
42
|
+
├── CLAUDE.md # Guidance for Claude Code
|
|
43
|
+
├── .env.example # Template for local env vars
|
|
44
|
+
├── Makefile # Common development targets
|
|
45
|
+
├── src/
|
|
46
|
+
│ └── adforge/
|
|
47
|
+
│ ├── __init__.py
|
|
48
|
+
│ ├── server.py # MCP stdio server wiring
|
|
49
|
+
│ ├── models/ # Pydantic domain models
|
|
50
|
+
│ │ ├── problem.py
|
|
51
|
+
│ │ ├── solution.py
|
|
52
|
+
│ │ ├── sub_problem.py
|
|
53
|
+
│ │ ├── dag.py
|
|
54
|
+
│ │ └── cost.py
|
|
55
|
+
│ ├── persistence/ # SQLite repositories + migrations
|
|
56
|
+
│ │ ├── db.py
|
|
57
|
+
│ │ ├── migrations/
|
|
58
|
+
│ │ └── repositories/
|
|
59
|
+
│ ├── pricing/ # Cloud/role pricing provider wrappers
|
|
60
|
+
│ │ ├── aws.py
|
|
61
|
+
│ │ ├── azure.py
|
|
62
|
+
│ │ ├── gcp.py
|
|
63
|
+
│ │ ├── databricks.py
|
|
64
|
+
│ │ ├── roles.py
|
|
65
|
+
│ │ ├── cache.py (in repositories)
|
|
66
|
+
│ │ └── manager.py
|
|
67
|
+
│ ├── tools/ # MCP tool modules
|
|
68
|
+
│ │ ├── problem.py
|
|
69
|
+
│ │ ├── solution.py
|
|
70
|
+
│ │ ├── decompose.py
|
|
71
|
+
│ │ ├── cost.py
|
|
72
|
+
│ │ └── solution_cost.py
|
|
73
|
+
│ ├── prompts/ # MCP prompt modules
|
|
74
|
+
│ │ └── problem_decomposition.py
|
|
75
|
+
│ └── utils/
|
|
76
|
+
│ └── logging.py
|
|
77
|
+
├── skills/
|
|
78
|
+
│ └── solution-architect/
|
|
79
|
+
│ └── SKILL.md # Hermes skill for architecture work
|
|
80
|
+
└── tests/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Quick Start
|
|
84
|
+
|
|
85
|
+
Install dependencies (uses `uv` or `pip`):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv pip install -e ".[dev]"
|
|
89
|
+
# or
|
|
90
|
+
pip install -e ".[dev]"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Run the server manually:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python -m adforge.server
|
|
97
|
+
# or
|
|
98
|
+
adforge-mcp
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Run tests:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
uv run pytest tests/ -q
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Workflow
|
|
108
|
+
|
|
109
|
+
1. **Capture a problem** — `create_problem(title, description, tags_csv)`.
|
|
110
|
+
2. **Decompose it** — use the `problem_decomposition` prompt, then call `decompose_problem(...)` to create sub-problems and a DAG.
|
|
111
|
+
3. **Create a solution** — `create_solution(problem_id, title, body)`.
|
|
112
|
+
4. **Attach costs** — `attach_cost_to_solution(...)` for each service/role/region.
|
|
113
|
+
5. **Summarize** — `summarize_solution_cost(solution_id)`.
|
|
114
|
+
6. **Review** — `add_solution_comment`, `add_solution_review`, `update_solution_status`.
|
|
115
|
+
|
|
116
|
+
## Pricing Sources
|
|
117
|
+
|
|
118
|
+
- **aws** — public AWS Price List Query API (`us-east-1`), no credentials required.
|
|
119
|
+
- **azure** — Azure Retail Prices API, no credentials required.
|
|
120
|
+
- **gcp** / **databricks** — stub providers; supply `manual_rate` in `parameters_json`.
|
|
121
|
+
- **role** — public/free role-pricing defaults; override with `manual_rate`.
|
|
122
|
+
|
|
123
|
+
## Hermes Skill
|
|
124
|
+
|
|
125
|
+
The `skills/solution-architect/SKILL.md` is a Hermes-compatible skill. To use it:
|
|
126
|
+
|
|
127
|
+
- Copy or symlink it into `~/.hermes/skills/solution-architect/SKILL.md`, or
|
|
128
|
+
- Keep it in-repo and load it directly if your agent supports in-repo skills.
|
|
129
|
+
|
|
130
|
+
## MCP Configuration
|
|
131
|
+
|
|
132
|
+
Add to your MCP client config:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"mcpServers": {
|
|
137
|
+
"adforge": {
|
|
138
|
+
"command": "uvx",
|
|
139
|
+
"args": ["adforge"]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Or for local development:
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
mcp_servers:
|
|
149
|
+
adforge:
|
|
150
|
+
command: "uv"
|
|
151
|
+
args: ["run", "python", "-m", "adforge.server"]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Environment Variables
|
|
155
|
+
|
|
156
|
+
Copy `.env.example` to `.env` and adjust:
|
|
157
|
+
|
|
158
|
+
- `ADFORGE_DB_PATH` — SQLite file path.
|
|
159
|
+
- `ADFORGE_CACHE_TTL` — pricing cache TTL in seconds.
|
|
160
|
+
- `AWS_PRICING_REGION` — AWS region for pricing queries.
|
|
161
|
+
- `LOG_LEVEL`, `MCP_SERVER_NAME`.
|
adforge-0.1.0/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# AD Forge
|
|
2
|
+
|
|
3
|
+
Runtime-agnostic MCP server for data-driven solution architecture, with bundled Hermes skills.
|
|
4
|
+
|
|
5
|
+
Works with any MCP stdio client (Claude Desktop, Hermes, OpenClaw, etc.). The core logic is also importable as plain Python packages.
|
|
6
|
+
|
|
7
|
+
Authors: Amirthanathan R (`amirth300324@gmail.com`) and Dhivya GL (`gldhivya1@gmail.com`).
|
|
8
|
+
|
|
9
|
+
## Project Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
├── pyproject.toml # Package metadata, deps, tool config
|
|
13
|
+
├── README.md # This file
|
|
14
|
+
├── CLAUDE.md # Guidance for Claude Code
|
|
15
|
+
├── .env.example # Template for local env vars
|
|
16
|
+
├── Makefile # Common development targets
|
|
17
|
+
├── src/
|
|
18
|
+
│ └── adforge/
|
|
19
|
+
│ ├── __init__.py
|
|
20
|
+
│ ├── server.py # MCP stdio server wiring
|
|
21
|
+
│ ├── models/ # Pydantic domain models
|
|
22
|
+
│ │ ├── problem.py
|
|
23
|
+
│ │ ├── solution.py
|
|
24
|
+
│ │ ├── sub_problem.py
|
|
25
|
+
│ │ ├── dag.py
|
|
26
|
+
│ │ └── cost.py
|
|
27
|
+
│ ├── persistence/ # SQLite repositories + migrations
|
|
28
|
+
│ │ ├── db.py
|
|
29
|
+
│ │ ├── migrations/
|
|
30
|
+
│ │ └── repositories/
|
|
31
|
+
│ ├── pricing/ # Cloud/role pricing provider wrappers
|
|
32
|
+
│ │ ├── aws.py
|
|
33
|
+
│ │ ├── azure.py
|
|
34
|
+
│ │ ├── gcp.py
|
|
35
|
+
│ │ ├── databricks.py
|
|
36
|
+
│ │ ├── roles.py
|
|
37
|
+
│ │ ├── cache.py (in repositories)
|
|
38
|
+
│ │ └── manager.py
|
|
39
|
+
│ ├── tools/ # MCP tool modules
|
|
40
|
+
│ │ ├── problem.py
|
|
41
|
+
│ │ ├── solution.py
|
|
42
|
+
│ │ ├── decompose.py
|
|
43
|
+
│ │ ├── cost.py
|
|
44
|
+
│ │ └── solution_cost.py
|
|
45
|
+
│ ├── prompts/ # MCP prompt modules
|
|
46
|
+
│ │ └── problem_decomposition.py
|
|
47
|
+
│ └── utils/
|
|
48
|
+
│ └── logging.py
|
|
49
|
+
├── skills/
|
|
50
|
+
│ └── solution-architect/
|
|
51
|
+
│ └── SKILL.md # Hermes skill for architecture work
|
|
52
|
+
└── tests/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
Install dependencies (uses `uv` or `pip`):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv pip install -e ".[dev]"
|
|
61
|
+
# or
|
|
62
|
+
pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Run the server manually:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python -m adforge.server
|
|
69
|
+
# or
|
|
70
|
+
adforge-mcp
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Run tests:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run pytest tests/ -q
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Workflow
|
|
80
|
+
|
|
81
|
+
1. **Capture a problem** — `create_problem(title, description, tags_csv)`.
|
|
82
|
+
2. **Decompose it** — use the `problem_decomposition` prompt, then call `decompose_problem(...)` to create sub-problems and a DAG.
|
|
83
|
+
3. **Create a solution** — `create_solution(problem_id, title, body)`.
|
|
84
|
+
4. **Attach costs** — `attach_cost_to_solution(...)` for each service/role/region.
|
|
85
|
+
5. **Summarize** — `summarize_solution_cost(solution_id)`.
|
|
86
|
+
6. **Review** — `add_solution_comment`, `add_solution_review`, `update_solution_status`.
|
|
87
|
+
|
|
88
|
+
## Pricing Sources
|
|
89
|
+
|
|
90
|
+
- **aws** — public AWS Price List Query API (`us-east-1`), no credentials required.
|
|
91
|
+
- **azure** — Azure Retail Prices API, no credentials required.
|
|
92
|
+
- **gcp** / **databricks** — stub providers; supply `manual_rate` in `parameters_json`.
|
|
93
|
+
- **role** — public/free role-pricing defaults; override with `manual_rate`.
|
|
94
|
+
|
|
95
|
+
## Hermes Skill
|
|
96
|
+
|
|
97
|
+
The `skills/solution-architect/SKILL.md` is a Hermes-compatible skill. To use it:
|
|
98
|
+
|
|
99
|
+
- Copy or symlink it into `~/.hermes/skills/solution-architect/SKILL.md`, or
|
|
100
|
+
- Keep it in-repo and load it directly if your agent supports in-repo skills.
|
|
101
|
+
|
|
102
|
+
## MCP Configuration
|
|
103
|
+
|
|
104
|
+
Add to your MCP client config:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"mcpServers": {
|
|
109
|
+
"adforge": {
|
|
110
|
+
"command": "uvx",
|
|
111
|
+
"args": ["adforge"]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or for local development:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
mcp_servers:
|
|
121
|
+
adforge:
|
|
122
|
+
command: "uv"
|
|
123
|
+
args: ["run", "python", "-m", "adforge.server"]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Environment Variables
|
|
127
|
+
|
|
128
|
+
Copy `.env.example` to `.env` and adjust:
|
|
129
|
+
|
|
130
|
+
- `ADFORGE_DB_PATH` — SQLite file path.
|
|
131
|
+
- `ADFORGE_CACHE_TTL` — pricing cache TTL in seconds.
|
|
132
|
+
- `AWS_PRICING_REGION` — AWS region for pricing queries.
|
|
133
|
+
- `LOG_LEVEL`, `MCP_SERVER_NAME`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "adforge"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "AD Forge — data-driven solution architecture with live cost estimates"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
requires-python = ">=3.13"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Amirthanathan R", email = "amirth300324@gmail.com" },
|
|
10
|
+
{ name = "Dhivya GL", email = "gldhivya1@gmail.com" },
|
|
11
|
+
]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"mcp>=1.0.0",
|
|
22
|
+
"pydantic>=2.0",
|
|
23
|
+
"structlog>=24.0",
|
|
24
|
+
"python-dotenv>=1.0",
|
|
25
|
+
"boto3>=1.43.50",
|
|
26
|
+
"httpx>=0.27",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest>=8.0",
|
|
32
|
+
"pytest-asyncio>=0.24",
|
|
33
|
+
"pytest-httpx>=0.30",
|
|
34
|
+
"ruff>=0.6",
|
|
35
|
+
"mypy>=1.10",
|
|
36
|
+
"pre-commit>=3.8",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
adforge-mcp = "adforge.server:run"
|
|
41
|
+
|
|
42
|
+
[build-system]
|
|
43
|
+
requires = ["hatchling"]
|
|
44
|
+
build-backend = "hatchling.build"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.build.targets.wheel]
|
|
47
|
+
packages = ["src/adforge"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
target-version = "py313"
|
|
51
|
+
line-length = 100
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = ["E", "F", "I", "N", "W", "UP", "B", "C4", "SIM"]
|
|
55
|
+
|
|
56
|
+
[tool.mypy]
|
|
57
|
+
python_version = "3.13"
|
|
58
|
+
strict = true
|
|
59
|
+
warn_return_any = true
|
|
60
|
+
warn_unused_configs = true
|
|
61
|
+
|
|
62
|
+
[tool.pytest.ini_options]
|
|
63
|
+
asyncio_mode = "auto"
|
|
64
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: solution-architect
|
|
3
|
+
description: "Use when designing system architectures, evaluating trade-offs, or producing AWS/Azure/GCP costed solution designs. Provides structured problem decomposition, DAG-based solution approaches, and live/public pricing data via MCP tools."
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Hermes Agent
|
|
6
|
+
license: MIT
|
|
7
|
+
metadata:
|
|
8
|
+
hermes:
|
|
9
|
+
tags: [architecture, aws, azure, gcp, cost, diagrams, infrastructure, design]
|
|
10
|
+
related_skills: [aws-architecture-diagrams, eraser-aws-diagrams]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Solution Architecture Skill
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
This skill anchors the agent's behavior when acting as a solution architect. It defines:
|
|
18
|
+
- A repeatable design-review checklist
|
|
19
|
+
- Data-driven problem decomposition into sub-problems
|
|
20
|
+
- DAG-based solution approach representation
|
|
21
|
+
- Live/public cloud pricing lookups (AWS, Azure)
|
|
22
|
+
- A PR/issue-shaped solution document with comments, reviews, and cost summaries
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- Designing greenfield systems or migrating existing ones
|
|
27
|
+
- Evaluating cloud provider services and their costs against requirements
|
|
28
|
+
- Creating or reviewing architecture diagrams
|
|
29
|
+
- Writing RFCs or design docs
|
|
30
|
+
- Estimating infrastructure and role/labor costs
|
|
31
|
+
|
|
32
|
+
Don't use for: purely frontend/UI design (use `claude-design` instead) or low-level algorithm optimization.
|
|
33
|
+
|
|
34
|
+
## Workflow
|
|
35
|
+
|
|
36
|
+
1. **Capture the problem** — use `create_problem` with title, description, and tags.
|
|
37
|
+
2. **Decompose** — use the `problem_decomposition` prompt, then call `decompose_problem` to store sub-problems and a solution DAG.
|
|
38
|
+
3. **Create solution documents** — use `create_solution` to produce PR/issue-shaped solution bodies.
|
|
39
|
+
4. **Cost sub-problems** — use `attach_cost_to_solution` for each service/region/role.
|
|
40
|
+
5. **Summarize** — call `summarize_solution_cost` to roll up line items and persist the summary.
|
|
41
|
+
6. **Review** — use `add_solution_review` and `add_solution_comment`, then `update_solution_status`.
|
|
42
|
+
|
|
43
|
+
## MCP Tools Available
|
|
44
|
+
|
|
45
|
+
- `create_problem`, `list_problems`, `get_problem`, `delete_problem`
|
|
46
|
+
- `create_solution`, `list_solutions`, `get_solution`, `update_solution_status`, `add_solution_comment`, `add_solution_review`
|
|
47
|
+
- `decompose_problem`, `get_solution_dag`
|
|
48
|
+
- `estimate_cost`, `attach_cost_to_solution`, `summarize_solution_cost`
|
|
49
|
+
- `list_pricing_providers`, `list_pricing_services`
|
|
50
|
+
|
|
51
|
+
## Pricing Sources
|
|
52
|
+
|
|
53
|
+
- **aws**: AWS Price List Query API (public, `us-east-1`), e.g. `AmazonEC2`, `AmazonS3`, `AWSLambda`.
|
|
54
|
+
- **azure**: Azure Retail Prices API, e.g. `Virtual Machines`, `Storage`.
|
|
55
|
+
- **gcp**, **databricks**: stub providers; use `manual_rate` in parameters for now.
|
|
56
|
+
- **role**: Public/free role pricing defaults (U.S. BLS OEWS source preferred; currently approximate defaults).
|
|
57
|
+
|
|
58
|
+
## Design Checklist
|
|
59
|
+
|
|
60
|
+
Before approving any architecture, verify:
|
|
61
|
+
|
|
62
|
+
1. **Scope clarity** — what is in scope vs out of scope?
|
|
63
|
+
2. **Single responsibility** — each component has one clear purpose
|
|
64
|
+
3. **Failure modes** — what happens when each dependency fails?
|
|
65
|
+
4. **Security layers** — auth, encryption, network segmentation, least privilege
|
|
66
|
+
5. **Observability** — metrics, logs, traces, health checks
|
|
67
|
+
6. **Scalability path** — how to grow 10x without redesign
|
|
68
|
+
7. **Cost ceiling** — rough monthly cost at 1x and 10x scale
|
|
69
|
+
8. **Operational burden** — who owns on-call and runbooks?
|
|
70
|
+
|
|
71
|
+
End each checklist with: "Document the top 3 risks and one mitigation per risk."
|
|
72
|
+
|
|
73
|
+
## Diagram Conventions
|
|
74
|
+
|
|
75
|
+
- Use full hierarchy: Region > VPC > AZ > Subnet
|
|
76
|
+
- Label every security group / NACL with ports and directions
|
|
77
|
+
- Tag data flows with protocol + approximate volume (MB/s or req/s)
|
|
78
|
+
- Use consistent colors: compute (blue), data (green), network (purple), security (red)
|
|
79
|
+
|
|
80
|
+
## Cost Heuristics
|
|
81
|
+
|
|
82
|
+
- Compute: Fargate/ECS vs EC2 — break-even around sustained 60% utilization
|
|
83
|
+
- Data: S3 Standard vs IA/Glacier — access-pattern driven, not volume driven
|
|
84
|
+
- Network: NAT Gateway is expensive at scale; prefer VPC endpoints or public subnets where acceptable
|
|
85
|
+
- Always include a "simpler/cheaper alternative" paragraph even if rejected
|
|
86
|
+
|
|
87
|
+
## Common Pitfalls
|
|
88
|
+
|
|
89
|
+
1. **Forgetting data residency** — some workloads require specific regions or on-prem
|
|
90
|
+
2. **Over-engineering for Day 1** — start with managed services, migrate to custom only when required
|
|
91
|
+
3. **Missing the blast radius** — single AZ or single region can be a total outage; document the trade-off
|
|
92
|
+
4. **Assuming infinite scale** — every service has a quota; list the ones you'll hit first
|
|
93
|
+
5. **No rollback plan** — every change should have a reverse procedure
|
|
94
|
+
|
|
95
|
+
## Verification Checklist
|
|
96
|
+
|
|
97
|
+
- [ ] Problem captured with clear tags
|
|
98
|
+
- [ ] Sub-problems created and DAG stored via `decompose_problem`
|
|
99
|
+
- [ ] Solution document created with PR/issue shape
|
|
100
|
+
- [ ] Cost line items attached and summarized
|
|
101
|
+
- [ ] Design checklist completed with documented risks
|
|
102
|
+
- [ ] Diagram follows hierarchy convention
|
|
103
|
+
- [ ] Simpler alternative is described
|
|
104
|
+
- [ ] Rollback / failure mode documented
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Core Pydantic models for solution architecture data."""
|
|
2
|
+
|
|
3
|
+
from adforge.models.common import Complexity, Status
|
|
4
|
+
from adforge.models.cost import CostLineItem, CostSummary
|
|
5
|
+
from adforge.models.dag import EdgeType, NodeType, SolutionEdge, SolutionNode
|
|
6
|
+
from adforge.models.problem import Problem
|
|
7
|
+
from adforge.models.solution import Comment, Review, Solution
|
|
8
|
+
from adforge.models.sub_problem import SubProblem
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Status",
|
|
12
|
+
"Complexity",
|
|
13
|
+
"Problem",
|
|
14
|
+
"Solution",
|
|
15
|
+
"Comment",
|
|
16
|
+
"Review",
|
|
17
|
+
"SubProblem",
|
|
18
|
+
"SolutionNode",
|
|
19
|
+
"SolutionEdge",
|
|
20
|
+
"NodeType",
|
|
21
|
+
"EdgeType",
|
|
22
|
+
"CostLineItem",
|
|
23
|
+
"CostSummary",
|
|
24
|
+
]
|