# Implementation Plan: Google Ads MCP Architecture Refactor
## Overview
This document outlines the phased implementation plan to refactor the Google Ads MCP server from the current 3-layer architecture to the improved 4-layer architecture described in [architecture.md](architecture.md).
**Current State:** Knowledge (Resources), Actions (Tools), Memory (Tools only)
**Target State:** Knowledge (Resources), Actions (Tools), Memory (Resources + Tools), Prompts (Workflows), Governance (Approval & Autonomy)
**Related Documents:**
- [architecture.md](architecture.md) - System architecture
- [governance.md](governance.md) - Autonomy framework and permission tiers
---
## Phase Summary
| Phase | Description | Estimated Complexity |
|-------|-------------|---------------------|
| 1 | Split Memory Layer into Resources + Tools | Medium |
| 2 | Create Prompts Layer | Medium |
| 3 | Update Server Registration | Low |
| 4 | Update Documentation | Low |
| 5 | Testing & Validation | Medium |
| 6 | Implement Governance Layer | High |
---
## Phase 1: Split Memory Layer into Resources + Tools
### Objective
Refactor the Memory layer to properly separate read operations (Resources) from write operations (Tools), aligning with MCP semantics.
### Current State
All memory operations are registered as Tools in individual files:
- `change_log.py` → `get_change_history` (read) exposed as Tool
- `report_history.py` → `get_historical_reports`, `compare_reports` (read) exposed as Tools
- `decisions.py` → `get_decision_history` (read) exposed as Tool
- `learnings.py` → `get_insights`, `get_actionable_insights` (read) exposed as Tools
### Target State
- Read operations moved to `memory/resources.py` as MCP Resources
- Write operations consolidated in `memory/tools.py` as MCP Tools
- Original files retain internal logic functions only (no MCP registration)
### Files to Modify
- `src/memory/resources.py` - Implement resource registration
- `src/memory/tools.py` - Implement tool registration
- `src/memory/change_log.py` - Remove `register_change_log_tools`, keep internal functions
- `src/memory/report_history.py` - Remove `register_report_history_tools`, keep internal functions
- `src/memory/decisions.py` - Remove `register_decision_tools`, keep internal functions
- `src/memory/learnings.py` - Remove `register_learning_tools`, keep internal functions
- `src/memory/__init__.py` - Update exports
---
### Agent Prompt: Phase 1
```
You are implementing Phase 1 of the Google Ads MCP architecture refactor.
OBJECTIVE: Split the Memory layer into Resources (read operations) and Tools (write operations).
CONTEXT:
- Read the architecture document at memory-bank/architecture.md for the target architecture
- Currently, all memory operations are registered as Tools
- MCP Resources are for read-only data; Tools are for actions that change state
INSTRUCTIONS:
1. First, read these files to understand current implementation:
- src/memory/__init__.py
- src/memory/change_log.py
- src/memory/report_history.py
- src/memory/decisions.py
- src/memory/learnings.py
- src/knowledge/resources.py (reference for how Resources are registered)
2. Implement src/memory/resources.py:
- Register these as MCP Resources with URIs:
- memory://changes/recent → Recent change log entries
- memory://reports/history → Historical report snapshots
- memory://decisions/history → Past decisions with rationale
- memory://insights → Accumulated learnings
- memory://insights/actionable → High-confidence actionable insights
- Use the existing internal functions (get_recent_changes, get_report_history, etc.)
- Return JSON-serialized content
3. Implement src/memory/tools.py:
- Consolidate these write operations as MCP Tools:
- save_report_snapshot (from report_history.py)
- log_decision (from decisions.py)
- update_decision_outcome (from decisions.py)
- record_learning (from learnings.py)
- Include clear docstrings explaining when to use each tool
4. Update the original files (change_log.py, report_history.py, decisions.py, learnings.py):
- Remove the register_*_tools functions
- Keep the internal logic functions (get_recent_changes, store_report, etc.)
- These are now pure data access functions, not MCP registrations
5. Update src/memory/__init__.py:
- Export register_memory_resources from resources.py
- Export register_memory_tools from tools.py
- Remove or update register_all_memory_tools
IMPORTANT:
- Do NOT modify src/knowledge/resources.py
- Do NOT modify any files in src/actions/
- Do NOT modify src/server.py yet (that's Phase 3)
- Preserve all existing functionality - this is a refactor, not a rewrite
OUTPUT: Provide a summary of changes made to each file.
```
---
## Phase 2: Create Prompts Layer
### Objective
Implement the Prompts layer with workflow templates that guide Claude through common Google Ads management tasks.
### Target State
- `src/prompts/__init__.py` - Module exports
- `src/prompts/workflows.py` - Prompt definitions and registration
### Prompts to Implement
1. `weekly_review` - Comprehensive weekly performance analysis
2. `optimize_campaign` - Deep-dive campaign optimization (requires campaign_id)
3. `keyword_expansion` - Research new keyword opportunities (requires campaign_id)
4. `budget_reallocation` - Cross-campaign budget optimization
5. `new_campaign_setup` - Guided campaign creation (requires campaign_name, daily_budget)
6. `diagnose_performance_drop` - Investigate performance issues (optional campaign_id)
---
### Agent Prompt: Phase 2
```
You are implementing Phase 2 of the Google Ads MCP architecture refactor.
OBJECTIVE: Create the Prompts layer with workflow templates for common Google Ads tasks.
CONTEXT:
- Read the architecture document at memory-bank/architecture.md for prompt descriptions
- MCP Prompts are pre-defined templates that guide Claude through multi-step workflows
- Prompts can have required and optional arguments
INSTRUCTIONS:
1. First, read these files to understand the available tools and resources:
- src/memory/resources.py (memory resources available)
- src/knowledge/resources.py (knowledge resources available)
- src/actions/*.py (tools available)
2. Implement src/prompts/__init__.py:
- Export register_prompts function from workflows.py
3. Implement src/prompts/workflows.py:
- Import from mcp.server and mcp.types as needed
- Create register_prompts(server: Server) function
- Register @server.list_prompts() handler returning list of available prompts
- Register @server.get_prompt() handler that returns prompt messages
4. Implement these prompts:
a) weekly_review (no arguments)
- Steps: gather context from memory, pull 7-day reports, compare to history,
identify wins/concerns, record insights, recommend next actions, save snapshot
b) optimize_campaign (required: campaign_id)
- Steps: get campaign details, analyze ad groups, analyze keywords,
review search terms, check historical context, provide recommendations
c) keyword_expansion (required: campaign_id)
- Steps: read knowledge resources, analyze current keywords, review search terms,
brainstorm based on archetypes, recommend new keywords with match types
d) budget_reallocation (no arguments)
- Steps: pull all campaign metrics, identify efficiency gaps, model scenarios,
recommend specific changes with rationale
e) new_campaign_setup (required: campaign_name, daily_budget)
- Steps: gather context, plan structure, design ad groups and keywords,
create campaign and components, set up monitoring
f) diagnose_performance_drop (optional: campaign_id)
- Steps: quantify the problem, check for changes in memory, analyze external factors,
drill down to root cause, provide diagnosis and recommendations
5. Each prompt message should:
- Be clear and actionable
- Reference specific resources (memory://*, knowledge://*)
- Reference specific tools to use
- Include numbered steps for Claude to follow
- Specify what to document/record at the end
IMPORTANT:
- Do NOT modify any other files
- Prompts should be comprehensive enough for Claude to follow without ambiguity
- Use PromptMessage and TextContent types from mcp.types
OUTPUT: Provide a summary of prompts implemented with their arguments.
```
---
## Phase 3: Update Server Registration
### Objective
Update the main server to register all resources, tools, and prompts from all layers.
### Challenge
MCP Python SDK allows only one handler per decorator type (`@server.list_resources`, etc.). Need to combine Knowledge and Memory resources into unified handlers.
### Files to Modify
- `src/server.py` - Update registration logic
- `src/knowledge/resources.py` - May need to refactor to return data instead of registering
---
### Agent Prompt: Phase 3
```
You are implementing Phase 3 of the Google Ads MCP architecture refactor.
OBJECTIVE: Update the server to properly register all resources, tools, and prompts.
CONTEXT:
- MCP Python SDK only allows ONE @server.list_resources() and ONE @server.read_resource() handler
- Currently, knowledge/resources.py registers resource handlers
- Now memory/resources.py also needs to register resource handlers
- We need to combine these into unified handlers
INSTRUCTIONS:
1. First, read these files:
- src/server.py (current registration)
- src/knowledge/resources.py (current resource registration)
- src/memory/resources.py (new resource registration from Phase 1)
- src/prompts/__init__.py (prompt registration from Phase 2)
2. Choose ONE of these approaches:
OPTION A: Centralized Registration (Recommended)
- Create src/resources.py that combines all resource handlers
- Knowledge and Memory modules export data functions, not registration functions
- Single @server.list_resources() returns combined list
- Single @server.read_resource() routes to appropriate module
OPTION B: Registration Aggregation
- Modify server.py to manually build combined resource lists
- Call data functions from knowledge and memory modules
- Register unified handlers in server.py
3. Update src/server.py to:
- Initialize database (already done)
- Register combined resources (knowledge + memory)
- Register action tools (already done via register_all_action_tools)
- Register memory tools (new: register_memory_tools)
- Register prompts (new: register_prompts)
- Log registration status for each layer
4. If using Option A, update:
- src/knowledge/resources.py - Export get_knowledge_resources() and read_knowledge_resource(uri) functions
- src/memory/resources.py - Export get_memory_resources() and read_memory_resource(uri) functions
- Create src/resources.py - Unified registration
5. Update src/memory/__init__.py if needed to export new functions
IMPORTANT:
- Ensure all existing functionality continues to work
- Test that resources are listable and readable
- Test that tools are callable
- Test that prompts are listable and retrievable
OUTPUT: Describe the approach taken and list all registration calls in server.py.
```
---
## Phase 4: Update Documentation
### Objective
Update README.md to reflect the new architecture and available prompts.
### Files to Modify
- `README.md` - Update architecture section, add prompts documentation
---
### Agent Prompt: Phase 4
```
You are implementing Phase 4 of the Google Ads MCP architecture refactor.
OBJECTIVE: Update documentation to reflect the new 4-layer architecture.
INSTRUCTIONS:
1. Read the current README.md
2. Update the Architecture section to reflect:
- 4 layers instead of 3 (add Prompts layer)
- Memory layer now has both Resources and Tools
- Include the updated architecture diagram from memory-bank/architecture.md
3. Add a new "Available Prompts" section documenting:
- weekly_review
- optimize_campaign
- keyword_expansion
- budget_reallocation
- new_campaign_setup
- diagnose_performance_drop
For each, include: name, description, required arguments (if any)
4. Update the "Available Tools" section:
- Add a "Memory Tools" subsection
- List: save_report_snapshot, log_decision, update_decision_outcome, record_learning
5. Add an "Available Resources" section:
- Knowledge Resources: app context, user archetypes, keyword research
- Memory Resources: changes, reports, decisions, insights
6. Update the Project Structure section to match the new file structure
IMPORTANT:
- Keep the README concise and scannable
- Maintain existing sections (Setup, Installation, etc.)
- Use consistent formatting with the rest of the document
OUTPUT: Summarize the sections updated.
```
---
## Phase 5: Testing & Validation
### Objective
Verify all components work correctly after the refactor.
### Test Cases
1. Resources: Can list and read all knowledge and memory resources
2. Tools: Can call all action and memory tools
3. Prompts: Can list and retrieve all workflow prompts
4. Integration: Prompts correctly reference existing resources and tools
---
### Agent Prompt: Phase 5
```
You are implementing Phase 5 of the Google Ads MCP architecture refactor.
OBJECTIVE: Test and validate the refactored MCP server.
INSTRUCTIONS:
1. Create a test script at tests/test_refactor.py that verifies:
a) Server starts without errors
- Import and call create_server()
- Verify no exceptions
b) Resources are registered correctly
- Call list_resources handler
- Verify all expected URIs are present:
- knowledge://app/context
- knowledge://users/archetypes
- knowledge://keywords/research
- memory://changes/recent
- memory://reports/history
- memory://decisions/history
- memory://insights
- memory://insights/actionable
c) Resources are readable
- Call read_resource for each URI
- Verify returns valid JSON
d) Tools are registered correctly
- Verify action tools exist (list_campaigns, etc.)
- Verify memory tools exist (save_report_snapshot, log_decision, etc.)
e) Prompts are registered correctly
- Call list_prompts handler
- Verify all 6 prompts are present
- Call get_prompt for each
- Verify returns valid PromptMessage list
2. Run the test script and fix any issues found
3. Manual validation:
- Start the server: python src/server.py
- Verify startup logs show all layers registered
- Test with Claude Desktop if available
IMPORTANT:
- Tests should be runnable without Google Ads credentials
- Mock external API calls if necessary
- Document any issues found and fixes applied
OUTPUT: Provide test results and any fixes made.
```
---
## Phase 6: Implement Governance Layer
### Objective
Implement the governance framework that controls agent autonomy, approval workflows, and audit logging as defined in [governance.md](governance.md).
### Core Requirements
1. **Permission tiers** - Classify each tool into Tier 0-3
2. **Approval workflow** - Intercept Tier 1-2 actions for approval
3. **Enhanced changelog** - Log all actions with approval status and rationale
4. **Autonomy limits** - Enforce bounds on autonomous actions
5. **Configuration** - Allow users to customize tier assignments
### Files to Create
- `src/governance/__init__.py` - Module exports
- `src/governance/permissions.py` - Permission tier definitions and tool classification
- `src/governance/approval.py` - Approval workflow logic
- `src/governance/limits.py` - Autonomy limits and bounds checking
- `src/governance/config.py` - User-configurable governance settings
### Files to Modify
- `src/memory/change_log.py` - Extend changelog schema for governance fields
- `src/memory/database.py` - Add approval_log table
- `src/actions/*.py` - Wrap tools with governance checks
- `src/server.py` - Initialize governance layer
---
### Agent Prompt: Phase 6
```
You are implementing Phase 6 of the Google Ads MCP architecture refactor.
OBJECTIVE: Implement the governance layer that controls agent autonomy and approval workflows.
CONTEXT:
- Read governance.md for the complete framework specification
- The governance layer sits between tool invocation and execution
- It enforces permission tiers, approval workflows, and autonomy limits
INSTRUCTIONS:
1. First, read these documents and files:
- memory-bank/governance.md (full specification)
- memory-bank/architecture.md (system context)
- src/actions/*.py (tools that need governance)
- src/memory/change_log.py (changelog to extend)
2. Create src/governance/__init__.py:
- Export key functions: check_permission, request_approval, enforce_limits
3. Create src/governance/permissions.py:
- Define PermissionTier enum (READ_ONLY, SUGGEST, APPROVE, AUTONOMOUS)
- Create TOOL_TIERS dict mapping tool names to their default tier
- Classify all existing tools per governance.md:
- Tier 0: list_*, get_* (read operations)
- Tier 2: ALL modification actions (default) including:
- update_campaign (budget) - LOCKED
- change_bid_strategy - LOCKED
- create_campaign, set_campaign_status
- add_keywords, update_keyword_bid, pause_keyword
- create_ad, update_ad_status, create_ad_group
- Tier 3: log_decision, record_learning, save_report_snapshot
- Define LOCKED_ACTIONS list (actions that cannot be promoted past Tier 2)
4. Create src/governance/approval.py:
- Implement ApprovalRequest dataclass with fields:
- action_name, parameters, rationale, expected_impact, timestamp
- Implement request_approval(action, params, rationale) -> ApprovalResponse
- Implement log_approval(request, response, executed) -> None
- For Tier 1: Format suggestion for human execution
- For Tier 2: Format approval request with execute/reject options
5. Create src/governance/limits.py:
- Implement check_limits(action, params) -> (allowed: bool, reason: str)
- Enforce limits from governance.md:
- max_bid_change_percent: 20
- max_daily_keyword_additions: 20
- max_daily_keyword_pauses: 10
- daily_spend_impact_threshold: 50
- Track daily action counts in database
6. Create src/governance/config.py:
- Define GovernanceConfig dataclass with user-configurable options
- Load from data/governance_config.json if exists
- Provide defaults matching governance.md specification
7. Update src/memory/database.py:
- Add approval_log table:
- id, timestamp, action_name, parameters, rationale
- tier, approval_status (pending/approved/rejected/autonomous)
- approved_by, response_timestamp
- Add daily_action_counts table for limit tracking
8. Update src/memory/change_log.py:
- Extend log_change() to include:
- approval_status (autonomous/approved/suggested)
- approved_by (user/autonomous)
- rationale (why action was taken)
- Ensure backwards compatibility with existing entries
9. Create wrapper for action tools:
- Implement governance_wrapped(tool_func) decorator
- Before execution: check tier, check limits, request approval if needed
- After execution: log to changelog with governance metadata
- Apply to all tools in src/actions/
10. Update src/server.py:
- Initialize governance layer
- Load governance config
- Log governance status on startup
IMPORTANT:
- Do NOT block read operations (Tier 0) - these should always pass through
- Tier 3 (autonomous) actions execute immediately but still log
- Tier 1-2 actions must have approval mechanism (even if stub for now)
- All actions MUST be logged - no silent operations
- Maintain backwards compatibility with existing changelog entries
OUTPUT:
- List of files created/modified
- Summary of permission tier assignments
- Description of approval workflow implementation
```
---
### Scaffolding for Phase 6
Create these empty files before implementation:
```
src/governance/
├── __init__.py
├── permissions.py
├── approval.py
├── limits.py
└── config.py
```
---
## Execution Order
```
┌─────────┐
│ Phase 1 │ Split memory layer
└────┬────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ │
┌─────────┐ ┌─────────┐ │
│ Phase 2 │ │ Phase 6 │ │
│ Prompts │ │Governance│ │
└────┬────┘ └────┬────┘ │
│ │ │
└────────┬───────┘ │
│ │
▼ │
┌─────────┐ │
│ Phase 3 │ Server registration
└────┬────┘ │
│ │
▼ │
┌─────────┐ │
│ Phase 4 │ Documentation │
└────┬────┘ │
│ │
▼ │
┌─────────┐ │
│ Phase 5 │ Testing │
└─────────┘ │
```
**Dependencies:**
- Phase 1 must complete first (memory layer split)
- Phase 2 and Phase 6 can run in parallel (no shared files)
- Phase 3 requires Phase 1, 2, and 6 to be complete
- Phase 4 can start after Phase 3
- Phase 5 requires all previous phases
**Parallel Execution Opportunity:**
Phases 2 and 6 are independent and can be assigned to different agents simultaneously.
---
## Rollback Plan
If issues arise, the refactor can be rolled back by:
1. Restoring the original `register_*_tools` functions in memory files
2. Removing `src/memory/resources.py` and `src/memory/tools.py`
3. Removing `src/prompts/` directory
4. Removing `src/governance/` directory
5. Reverting `src/server.py` changes
6. Reverting `src/memory/__init__.py` changes
7. Reverting `src/memory/change_log.py` schema changes (if any data exists, migrate first)
All original functionality is preserved in the internal functions, so rollback only requires reverting MCP registration changes.
**Note:** If governance changes modified the changelog schema and data exists, run a migration script before rollback to preserve existing records.