-
Notifications
You must be signed in to change notification settings - Fork 2
Night Nurse: MCP Server Implementation (WIP) #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,3 +17,11 @@ venv/ | |
| dist/ | ||
| build/ | ||
| *.egg-info/ | ||
|
|
||
| # Ralph Wiggum | ||
| logs/ralph/ | ||
| state/ | ||
| *.tmp | ||
|
|
||
| # Night Nurse | ||
| logs/night-nurse.log | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "name": "brand-os", | ||
| "path": "/home/deploy/scty-repos/brand-os", | ||
| "agents": { | ||
| "review": "claude", | ||
| "implement": "codex" | ||
| }, | ||
| "maxIterations": 25, | ||
| "priorities": { | ||
| "sources": [ | ||
| "sentry", | ||
| "specs", | ||
| "backlog" | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Priorities | ||
|
|
||
| Items listed here will be picked up by Night Nurse (highest first). | ||
|
|
||
| ## High Priority | ||
| <!-- Critical bugs, blockers --> | ||
|
|
||
| ## Medium Priority | ||
| <!-- Features, improvements --> | ||
|
|
||
| ## Low Priority | ||
| <!-- Nice to have, tech debt --> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "initialized": "2026-01-28T17:26:09Z", | ||
| "lastLearn": "2026-02-01T03:01:03Z", | ||
| "lastTreat": null, | ||
| "stats": { | ||
| "specsCompleted": 0, | ||
| "specsInProgress": 0, | ||
| "totalIterations": 0, | ||
| "learnings": 3 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Constitution - brand-os | ||
|
|
||
| ## Project Purpose | ||
| CLI-first brand operations toolkit - unified personas, intel, content, and publishing | ||
|
|
||
| ## Tech Stack | ||
| Python | ||
|
|
||
| ## Build & Test | ||
| ```bash | ||
| # npm run build | ||
| pytest | ||
| ``` | ||
|
|
||
| ## Principles | ||
| 1. Keep changes minimal and focused | ||
| 2. Don't break existing functionality | ||
| 3. Add tests for new behavior | ||
|
|
||
| ## Boundaries | ||
| - Don't modify production data directly | ||
| - Don't commit secrets | ||
| - Don't change CI/CD without review |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ai-review.sh: not found | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ai-review.sh: not found | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ai-review.sh: not found |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ralph-loop-ai.sh: not found | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ralph-loop-ai.sh: not found | ||
| /bin/sh: 1: /home/deploy/clawd/skills/ralph-wiggum/scripts/ralph-loop-ai.sh: not found |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,7 @@ publish = [ | |
| server = [ | ||
| "fastapi>=0.115", | ||
| "uvicorn>=0.32", | ||
| "fastmcp<3", | ||
| ] | ||
| email = [ | ||
| "resend>=2.0", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Log: MCP Server Implementation - Complete the MCP server to expose brand operations (personas, content, intel, decisions) as tools for AI assistants using FastMCP | ||
|
|
||
| ## 2026-02-01 | ||
| - Spec created | ||
|
|
||
| ### Iteration 1 - 15:18:22 | ||
| Task: 1.1 [Task] | ||
| Result: ✓ Complete | ||
|
|
||
| ### Iteration 2 - 15:20:47 | ||
| Task: 1.1 [Task] | ||
| Result: ✓ Complete |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Proposal: MCP Server Implementation - Complete the MCP server to expose brand operations (personas, content, intel, decisions) as tools for AI assistants using FastMCP | ||
|
|
||
| ## Intent | ||
| <!-- Why we're doing this. The problem we're solving. --> | ||
|
|
||
| ## Scope | ||
| **In scope:** | ||
| - | ||
|
|
||
| **Out of scope:** | ||
| - | ||
|
|
||
| ## Approach | ||
| <!-- High-level how we'll tackle it. --> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Spec: MCP Server Implementation - Complete the MCP server to expose brand operations (personas, content, intel, decisions) as tools for AI assistants using FastMCP | ||
|
|
||
| ## Requirements | ||
|
|
||
| ### Requirement: [Name] | ||
| The system SHALL [behavior]. | ||
|
|
||
| #### Scenario: [Happy path] | ||
| - GIVEN [context] | ||
| - WHEN [action] | ||
| - THEN [result] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Tasks: MCP Server Implementation - Complete the MCP server to expose brand operations (personas, content, intel, decisions) as tools for AI assistants using FastMCP | ||
|
|
||
| ## 1. Setup | ||
| - [ ] 1.1 [Task] | ||
|
|
||
| ## 2. Implementation | ||
| - [ ] 2.1 [Task] | ||
|
|
||
| ## 3. Testing | ||
| - [ ] 3.1 [Task] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Log: Content Producer Agent - Implement agent that takes Market Analyst outputs and generates brand-aligned content for publishing | ||
|
|
||
| ## 2026-02-01 | ||
| - Spec created |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Proposal: Content Producer Agent - Implement agent that takes Market Analyst outputs and generates brand-aligned content for publishing | ||
|
|
||
| ## Intent | ||
| <!-- Why we're doing this. The problem we're solving. --> | ||
|
|
||
| ## Scope | ||
| **In scope:** | ||
| - | ||
|
|
||
| **Out of scope:** | ||
| - | ||
|
|
||
| ## Approach | ||
| <!-- High-level how we'll tackle it. --> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Spec: Content Producer Agent - Implement agent that takes Market Analyst outputs and generates brand-aligned content for publishing | ||
|
|
||
| ## Requirements | ||
|
|
||
| ### Requirement: [Name] | ||
| The system SHALL [behavior]. | ||
|
|
||
| #### Scenario: [Happy path] | ||
| - GIVEN [context] | ||
| - WHEN [action] | ||
| - THEN [result] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Tasks: Content Producer Agent - Implement agent that takes Market Analyst outputs and generates brand-aligned content for publishing | ||
|
|
||
| ## 1. Setup | ||
| - [ ] 1.1 [Task] | ||
|
|
||
| ## 2. Implementation | ||
| - [ ] 2.1 [Task] | ||
|
|
||
| ## 3. Testing | ||
| - [ ] 3.1 [Task] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 2026-01-28 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # [FIX] Implement notification in approval.py | ||
|
|
||
| ## Task | ||
| In `src/brand_os/workflows/approval.py` line 114, replace the TODO comment with actual Slack notification code. | ||
|
|
||
| ## Current Code (line 112-115) | ||
| ```python | ||
| def _notify(self, message: str) -> None: | ||
| """Send notification (placeholder for Slack/email integration).""" | ||
| # TODO: Implement notification via slack-sdk or email | ||
| pass | ||
| ``` | ||
|
|
||
| ## Required Change | ||
| Replace the TODO and `pass` with code that sends a Slack webhook notification using httpx (already imported in the project). Use env var `SLACK_WEBHOOK_URL`. If not set, just log the message. | ||
|
|
||
| ## Example Implementation | ||
| ```python | ||
| def _notify(self, message: str) -> None: | ||
| """Send notification via Slack webhook.""" | ||
| import os | ||
| webhook_url = os.getenv("SLACK_WEBHOOK_URL") | ||
| if webhook_url: | ||
| try: | ||
| import httpx | ||
| httpx.post(webhook_url, json={"text": f"[BrandOS] {message}"}, timeout=10) | ||
| except Exception: | ||
| pass # Silent fail - notification is best-effort | ||
| ``` | ||
|
|
||
| ## Completion Signal | ||
| ```bash | ||
| grep -rn "# TODO: Implement notification via slack-sdk or email" src/brand_os/workflows/approval.py && exit 1 || echo "TODO resolved" | ||
| ``` | ||
|
|
||
| ## Constraints | ||
| - Only modify the `_notify` method | ||
| - Keep it simple - just Slack webhook, no email |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,9 +110,21 @@ def _save(self) -> None: | |
| get_decision_log().update(self.decision) | ||
|
|
||
| def _notify(self, message: str) -> None: | ||
| """Send notification (placeholder for Slack/email integration).""" | ||
| # TODO: Implement notification via slack-sdk or email | ||
| pass | ||
| """Send notification via Slack webhook.""" | ||
| import os | ||
|
|
||
| webhook_url = os.getenv("SLACK_WEBHOOK_URL") | ||
| if not webhook_url: | ||
| logger.info("Approval notification: %s", message) | ||
| return | ||
| try: | ||
| httpx.post( | ||
| webhook_url, | ||
| json={"text": f"[BrandOS] {message}"}, | ||
| timeout=10, | ||
|
Comment on lines
+120
to
+124
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
| ) | ||
| except Exception: | ||
| pass # Best-effort notification | ||
|
|
||
| else: | ||
| # Fallback implementation without statemachine dependency | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
SLACK_WEBHOOK_URLis unset,_notifycallslogger.info(...), but this module never defineslogger. That means normal approval flows without a webhook will raiseNameErrorinstead of logging. This breaks the state machine paths that call_notifyin non-webhook environments. Import and initialize a logger (or use the existing logging setup) before calling it.Useful? React with 👍 / 👎.