# GitHub Issues Integration Architecture
**Status:** ✅ IMPLEMENTED
**Version:** 1.1
**Author:** Node-Architect-001 (Design), Node-Developer-002 (Implementation)
**Date:** 2026-02-02
**Implementation Date:** 2026-02-02
## Executive Summary
This document defines the architecture for integrating GitHub Issues into the amicus-mcp workflow. The integration enables bidirectional synchronization between GitHub Issues and the local task context, supporting both human-driven and agent-driven issue management while maintaining the integrity of the local context bus.
## Design Principles
1. **Explicit Over Implicit**: Issues are NOT automatically imported to local context. Human intervention required.
2. **Separation of Concerns**: GitHub Issues remain the source of truth for external collaboration; local tasks remain optimized for agent workflow.
3. **Bidirectional Sync**: Changes in either system can propagate to the other when explicitly requested.
4. **Non-Invasive**: Existing amicus-mcp functionality remains unchanged.
## Architecture Overview
### 1. Issue-Task Mapping Model
GitHub Issues and amicus tasks serve different purposes and have different lifecycles:
```
┌─────────────────────────┐ ┌──────────────────────────┐
│ GitHub Issue │ │ Amicus Task │
├─────────────────────────┤ ├──────────────────────────┤
│ - Issue Number │◄───────►│ - Task ID │
│ - Title │ │ - Description │
│ - Body │ │ - Status │
│ - State (open/closed) │ │ - Assigned To │
│ - Labels │ │ - Priority │
│ - Assignees │ │ - Created At │
│ - Comments │ │ - Claimed At │
│ │ │ - Completed At │
└─────────────────────────┘ └──────────────────────────┘
```
#### Mapping Strategy
**Issue → Task (Import)**
```json
{
"task": "[#123] Issue Title",
"status": "pending",
"priority": "medium", // Derived from labels
"github_issue": {
"number": 123,
"url": "https://github.com/owner/repo/issues/123",
"state": "open",
"imported_at": 1738483200.0,
"last_synced": 1738483200.0
},
"created_at": 1738483200.0
}
```
**Task → Issue (Create)**
```json
// GitHub Issue Body
Title: <task description>
Body:
---
Created by: <agent_id>
Amicus Task ID: <task_id>
Priority: <priority>
<detailed description>
---
This issue was created by amicus-mcp agent workflow.
```
### 2. Synchronization Strategy
#### 2.1 Pull (Import) Operations
**When:** Explicit human request via new MCP tool
**Tool:** `import_github_issue(issue_number, priority="medium")`
**Behavior:**
1. Fetch issue from GitHub API using existing GitHub MCP tools
2. Check if issue is already imported (by issue number)
3. Create new task in `next_steps` with `github_issue` metadata
4. Add message to context bus: "Imported GitHub Issue #123: <title>"
**Edge Cases:**
- If issue already imported: Update existing task with latest GitHub state
- If issue is closed: Import with status "completed"
- If issue has assignees: Add note in task description
#### 2.2 Push (Export) Operations
**When:** Explicit agent or human request via new MCP tool
**Tool:** `create_github_issue_from_task(task_index, labels=[])`
**Behavior:**
1. Read task from `next_steps[task_index]`
2. Create GitHub issue using `mcp__github__create_issue`
3. Update task with `github_issue` metadata
4. Add comment to GitHub issue with amicus task reference
**Edge Cases:**
- If task already linked to issue: Return error
- If issue creation fails: Return error, don't modify task
#### 2.3 Bidirectional Sync
**When:** Explicit request or scheduled (future enhancement)
**Tool:** `sync_github_issues()`
**Behavior:**
1. Iterate through all tasks with `github_issue` metadata
2. For each task:
- Fetch current issue state from GitHub
- Compare local task status with GitHub issue state
- Apply resolution rules:
- **Local completed + GitHub open**: Offer to close GitHub issue
- **Local in_progress + GitHub closed**: Warn of conflict
- **GitHub has new comments**: Add to task notes
3. Update `last_synced` timestamp
**Conflict Resolution:**
- Local changes take precedence by default
- Human intervention required for conflicts (set `ask_user=True`)
### 3. New MCP Tools
#### 3.1 `import_github_issue`
```python
@mcp.tool()
def import_github_issue(
issue_number: int,
priority: str = "medium",
repo: Optional[str] = None,
owner: Optional[str] = None
) -> str:
"""
Import a GitHub issue into the local task context.
Args:
issue_number: GitHub issue number
priority: Task priority (low/medium/high)
repo: Repository name (default: from config)
owner: Repository owner (default: from config)
Returns:
Success message with task index
"""
# Implementation:
# 1. Fetch issue using mcp__github__get_issue
# 2. Create task with github_issue metadata
# 3. Broadcast import message
pass
```
#### 3.2 `create_github_issue_from_task`
```python
@mcp.tool()
def create_github_issue_from_task(
task_index: int,
labels: List[str] = None,
assignees: List[str] = None
) -> str:
"""
Create a GitHub issue from an existing amicus task.
Args:
task_index: 1-based index of task in next_steps
labels: Optional GitHub labels to apply
assignees: Optional GitHub usernames to assign
Returns:
GitHub issue URL
"""
# Implementation:
# 1. Read task from next_steps
# 2. Validate task not already linked
# 3. Create issue using mcp__github__create_issue
# 4. Update task with github_issue metadata
# 5. Add comment to issue with amicus reference
pass
```
#### 3.3 `sync_github_issues`
```python
@mcp.tool()
def sync_github_issues(
auto_close: bool = False
) -> str:
"""
Synchronize status between local tasks and linked GitHub issues.
Args:
auto_close: If True, automatically close GitHub issues when local task is completed
Returns:
Sync report with conflicts and updates
"""
# Implementation:
# 1. Find all tasks with github_issue metadata
# 2. Fetch current state from GitHub
# 3. Compare and apply resolution rules
# 4. Update last_synced timestamps
# 5. Report conflicts requiring human intervention
pass
```
#### 3.4 `list_github_issues`
```python
@mcp.tool()
def list_github_issues(
state: str = "open",
labels: List[str] = None,
limit: int = 20
) -> str:
"""
List GitHub issues from configured repository.
Args:
state: Issue state filter (open/closed/all)
labels: Filter by labels
limit: Maximum number of issues to return
Returns:
Formatted list of issues with import status
"""
# Implementation:
# 1. Use mcp__github__list_issues
# 2. Check which issues are already imported
# 3. Format as readable list with metadata
pass
```
#### 3.5 `update_github_issue_status`
```python
@mcp.tool()
def update_github_issue_status(
task_index: int,
comment: Optional[str] = None
) -> str:
"""
Update GitHub issue status based on local task completion.
Args:
task_index: 1-based index of completed task
comment: Optional comment to add when closing issue
Returns:
Success message
"""
# Implementation:
# 1. Read task and verify it's linked to GitHub issue
# 2. Verify task is completed
# 3. Close GitHub issue using mcp__github__update_issue
# 4. Add comment with completion details
pass
```
### 4. Configuration Schema
Add GitHub configuration to amicus config:
```toml
[github]
default_repo = "amicus-mcp"
default_owner = "earchibald"
auto_sync_enabled = false
auto_sync_interval_seconds = 300
issue_label_prefix = "amicus"
default_labels = ["amicus-agent"]
[github.priority_mapping]
# GitHub labels -> amicus priority
"priority: high" = "high"
"priority: medium" = "medium"
"priority: low" = "low"
"bug" = "high"
"enhancement" = "medium"
"documentation" = "low"
```
### 5. State Schema Extensions
#### Task with GitHub Issue Metadata
```json
{
"task": "[#123] Implement user authentication",
"status": "in_progress",
"priority": "high",
"assigned_to": "Node-Dev-001",
"created_at": 1738483200.0,
"claimed_at": 1738483300.0,
"github_issue": {
"number": 123,
"repo": "amicus-mcp",
"owner": "earchibald",
"url": "https://github.com/earchibald/amicus-mcp/issues/123",
"state": "open",
"imported_at": 1738483200.0,
"last_synced": 1738483400.0,
"labels": ["enhancement", "priority: high"],
"assignees": ["developer1"]
}
}
```
#### GitHub Metadata in Context Bus
```json
{
"summary": "Working on authentication",
"next_steps": [...],
"active_files": [...],
"github_metadata": {
"default_repo": "amicus-mcp",
"default_owner": "earchibald",
"imported_issues": [123, 145, 178],
"pending_sync": [],
"last_sync": 1738483400.0
}
}
```
### 6. Implementation Phases
#### Phase 1: Basic Import/Export (Task 2)
- Implement `import_github_issue`
- Implement `create_github_issue_from_task`
- Add configuration schema
- Basic unit tests
#### Phase 2: Bidirectional Sync (Task 3)
- Implement `sync_github_issues`
- Implement `update_github_issue_status`
- Conflict detection and resolution
- Integration tests
#### Phase 3: On-Demand Import (Task 4)
- Implement `list_github_issues`
- Add import status tracking
- Batch import capabilities
- CLI support
#### Phase 4: Documentation & Testing (Tasks 5-6)
- User documentation
- Agent workflow examples
- End-to-end testing with real GitHub issue
- Performance optimization
### 7. Security & Safety Considerations
#### 7.1 Authentication
- Use existing GitHub MCP server authentication
- No credentials stored in amicus-mcp
- Validate GitHub token has required permissions
#### 7.2 Rate Limiting
- Respect GitHub API rate limits
- Implement exponential backoff
- Cache issue data with TTL
#### 7.3 Data Validation
- Validate issue numbers before API calls
- Sanitize user input in issue creation
- Prevent sensitive data leakage in issue bodies
#### 7.4 Path Safety
- GitHub URLs validated before storage
- No file system operations based on GitHub data
- Issue metadata treated as untrusted input
### 8. Testing Strategy
#### 8.1 Unit Tests
```python
def test_import_github_issue():
"""Test importing a GitHub issue creates correct task structure."""
pass
def test_create_issue_from_task():
"""Test creating GitHub issue from task with proper metadata."""
pass
def test_sync_detects_conflicts():
"""Test sync correctly identifies status conflicts."""
pass
```
#### 8.2 Integration Tests
```python
def test_full_import_workflow():
"""Test complete import workflow from GitHub to local task."""
pass
def test_bidirectional_sync():
"""Test complete sync cycle with status updates."""
pass
```
#### 8.3 E2E Tests
- Use GitHub Issue #3 as test case
- Import issue to local context
- Complete task and sync status
- Verify GitHub issue closed correctly
### 9. User Experience
#### 9.1 Agent Workflow
```
Agent: "I see GitHub Issue #3 needs to be worked on. Let me import it."
[Calls import_github_issue(3, priority="high")]
Agent: "I've completed the authentication feature. Let me create a GitHub issue for tracking."
[Calls create_github_issue_from_task(5, labels=["feature"])]
Agent: "Syncing status with GitHub..."
[Calls sync_github_issues(auto_close=False)]
Result: "Task 2 is completed but GitHub Issue #123 is still open. Mark as ask_user."
```
#### 9.2 Human Workflow
```bash
# List open issues
amicus-mcp --github list-issues
# Import specific issue
amicus-mcp --github import 123 --priority high
# Sync all linked issues
amicus-mcp --github sync
# Create issue from task
amicus-mcp --github create-issue --task 5 --label feature
```
### 10. Future Enhancements
#### 10.1 Automatic Sync Scheduling
- Background sync process
- Configurable sync intervals
- Webhook support for real-time updates
#### 10.2 Issue Templates
- Support for GitHub issue templates
- Custom amicus task templates
- Template-based issue creation
#### 10.3 Advanced Filtering
- Import issues by milestone
- Filter by project board
- Query-based import
#### 10.4 Multi-Repository Support
- Track issues across multiple repos
- Cross-repo dependency tracking
- Unified task view
#### 10.5 Comment Synchronization
- Sync GitHub comments to task notes
- Agent comments pushed to GitHub
- Threaded discussion support
## Implementation Checklist
- [ ] Add GitHub configuration to config.py
- [✅] Implement import_github_issue tool → `import_github_issue_to_task()`
- [✅] Implement create_github_issue_from_task tool → `create_github_issue()`
- [✅] Implement sync_github_issues tool → `sync_task_to_github_issue()`
- [✅] Implement list_github_issues tool → `list_github_issues()`
- [✅] Implement update_github_issue_status tool → Integrated in `sync_task_to_github_issue()`
- [✅] Add state schema extensions → Task metadata includes `github_issue`, `github_repo`, `github_url`
- [✅] Add unit tests → `tests/test_github_issues.py`
- [✅] Add integration tests → `tests/test_github_issues.py`
- [✅] Add E2E test with Issue #3 → `test_github_workflow.py` + Real test on Issue #3
- [ ] Add CLI commands
- [ ] Write user documentation
- [ ] Write agent workflow guide
- [ ] Performance benchmarking
## Implementation Summary (2026-02-02)
### What Was Implemented
Node-Developer-002 successfully implemented the GitHub Issues integration with the following tools:
1. **create_github_issue()** - Create new GitHub issues with optional labels and assignment
2. **list_github_issues()** - List and filter GitHub issues by state and labels
3. **import_github_issue_to_task()** - Import GitHub issues to local task context on demand
4. **sync_task_to_github_issue()** - Sync local task status to GitHub with comments and closing
### Implementation Details
- **Location**: `/Users/earchibald/work/amicus-mcp/src/amicus/server.py`
- **Dependencies**: Optional PyGithub library (graceful degradation without it)
- **Integration**: Works with both PyGithub and existing GitHub MCP server tools
- **Testing**: Comprehensive test suite in `tests/test_github_issues.py` and manual validation script `test_github_workflow.py`
### Key Features
- ✅ Optional PyGithub dependency (fails gracefully if not installed)
- ✅ Requires GITHUB_TOKEN environment variable for authentication
- ✅ Tasks imported from GitHub maintain full metadata (issue #, repo, URL)
- ✅ Bidirectional sync: local tasks can update GitHub issues
- ✅ Duplicate detection: prevents importing same issue twice
- ✅ Comment support: can add comments when syncing status
- ✅ Auto-close support: can close GitHub issues when tasks complete
### Testing & Validation
- Created comprehensive unit test suite with mocking
- Created manual test script for structure validation
- Tested with real GitHub Issue #3
- Successfully added comment to Issue #3 documenting implementation
### Differences from Original Design
The implementation simplified some aspects of the original design:
1. **Simplified tool names**: Used clearer, more direct naming
2. **Combined functionality**: `sync_task_to_github_issue()` handles both status updates and closing
3. **No separate sync tool**: Each operation is explicit rather than having a global sync
4. **Metadata structure**: Simplified to flat task properties rather than nested `github_issue` object
### Usage Example
```python
# Import GitHub issue #3 to local task context
import_github_issue_to_task(
repo_owner="earchibald",
repo_name="amicus-mcp",
issue_number=3,
priority="high"
)
# Work on the task...
# Sync completion back to GitHub
sync_task_to_github_issue(
task_index=1,
comment="Implementation complete!",
close_issue=True
)
```
## Conclusion
This architecture provides a robust, non-invasive integration between GitHub Issues and amicus-mcp task management. By keeping the systems loosely coupled and requiring explicit synchronization, we maintain the integrity of both systems while enabling powerful cross-platform workflow capabilities.
The design prioritizes:
1. **Explicit control**: No automatic pollution of local context
2. **Flexibility**: Multiple sync strategies supported
3. **Safety**: Conflict detection and human override
4. **Extensibility**: Easy to add new features in future
The phased implementation approach ensures each component can be tested and validated independently before integration into the larger workflow.