feat(mcp): create, update, log progress, and delete goals via MCP#8480
feat(mcp): create, update, log progress, and delete goals via MCP#8480ZachL111 wants to merge 15 commits into
Conversation
There was a problem hiding this comment.
1 issue found across 6 files
Confidence score: 3/5
- In
backend/utils/mcp_goals.py,get_goal_historynot translating missing goals toGoalNotFoundcan return a different error shape/status than other goal endpoints, which risks client-side handling regressions and inconsistent 404 vs-32001behavior in production—align this path with the sharedGoalNotFoundmapping before merging.
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Thanks cubic. Fixed: |
kodjima33
left a comment
There was a problem hiding this comment.
MCP feature: manage goals via MCP — approve only.
# Conflicts: # backend/routers/mcp.py # backend/routers/mcp_sse.py # backend/test.sh
Git-on-my-level
left a comment
There was a problem hiding this comment.
Thanks @ZachL111 — the core MCP goals-write implementation still looks directionally good (shared utils/mcp_goals.py, uid-scoped database calls, and coverage across REST + SSE are all the right shape).
I’m requesting changes on this revision before it should merge for two concrete reasons:
- CI is currently red:
Lint & Format Checkfails becausedart format --line-length 120 --set-exit-if-changedwould reformat 8 changed Dart files (app/lib/backend/http/api/conversations.dart,app/lib/backend/schema/bt_device/bt_device.dart,app/lib/pages/chat/page.dart,app/lib/providers/capture_provider.dart,app/lib/providers/conversation_provider.dart,app/lib/services/auth_service.dart,app/lib/services/devices/device_connection.dart, andapp/lib/utils/analytics/analytics_manager.dart). Please run the repo formatter and push the resulting formatting. - The latest revision broadened the diff from the MCP goals work into unrelated app and firmware formatting-only changes. For reviewability and safe rollback, please trim this PR back to the MCP goals surface (backend router/helper/tests) unless those app/firmware formatting changes are intentionally part of this feature.
Separately, this still opens a new user-data write capability through MCP (goals.write), so I’d keep it under human maintainer/product review even after the mechanical issues are fixed. No formal approval from me under the automation policy.
… to the backend MCP goals surface
|
Thanks David. I reverted the unrelated app and firmware formatting churn, so the diff is now limited to the backend MCP goals surface:
The app Dart and firmware C files are back to their main versions, which also clears the Lint and Format Check failure (the 8 dart format files were all in that reverted set). The goals tests still pass locally (29 passed), and the shared utils/mcp_goals.py orchestration plus the REST and SSE coverage are unchanged. |
… and assert every supported scope has it
|
Preemptively added the consent permission text for goals.write to SCOPE_PERMISSION_TEXT (commit 41b6c9d), plus a unit test asserting every supported scope has a permission string. Same OAuth authorize KeyError gap David flagged on the folders PR #8489, so the consent page now renders for this scope too. |
Git-on-my-level
left a comment
There was a problem hiding this comment.
Thanks @ZachL111 — the latest revision does address the earlier mechanical blockers: the unrelated app/firmware formatting churn is gone, the lint/backend checks are green, and the goals.write consent text gap is now covered.
I’m still requesting one small change before this should merge: please put the new REST POST /v1/mcp/goals create endpoint behind the same style of write rate limit used for comparable MCP create surfaces (/v1/mcp/memories and /v1/mcp/action-items). Right now create_goal uses a plain get_uid_from_mcp_api_key dependency, while creating a goal writes Firestore and can retire/deactivate the oldest active goal when the user is at the active-goal cap. That makes repeated calls both a write-amplification path and a user-data churn path. The SSE transport has the general mcp:sse request limiter, but the REST create endpoint should not be easier to spam than memories/action-items.
Suggested shape: use Depends(with_rate_limit(get_uid_from_mcp_api_key, "goals:write")) (or the repo’s preferred equivalent policy name) on create_goal. I don’t think this needs to block the overall feature direction, but because this adds a new MCP user-data write/delete surface, I’d keep the PR under human maintainer/security review rather than formal automation approval.
|
Done in 40e443f. Added a I kept it at the |
Summary
The MCP server already lets ChatGPT/Claude read the user's goals (
get_goals), but not change them. This adds the write half, so an assistant connected to Omi can manage goals instead of only observing them: create a goal the user mentions, log progress against it, adjust its target, review its history, and remove a stale one.Goals are measurable, long-horizon objectives (a
target_valuethe user works toward, withcurrent_valueprogress and recorded history), which is what makes this more than a tasks clone. Memories (create/edit/delete) and action items are already writable on the MCP surface, so this rounds out goals to give the agent the full two-way memory bank from #4862.New MCP tools (with matching REST endpoints under
/v1/mcp/goals):create_goal(title, target_value, goal_type?, current_value?, min_value?, max_value?, unit?)update_goal(goal_id, title? / target_value? / current_value? / unit? / min_value? / max_value?)update_goal_progress(goal_id, current_value)(logs the value and records it to the goal's history)delete_goal(goal_id)get_goal_history(goal_id, days?)(read, complements progress logging)Refs #4862.
Design
utils/mcp_goals.pyhelper that both transports (RESTmcp.pyand SSEmcp_sse.py) call, so the two MCP paths cannot drift, the same approach used for memories and action items.utilssits belowrouters, so neither router imports the other.create_goal,update_goal,update_goal_progress,delete_goal,get_goal_history) and the app's own/v1/goalssemantics, including the small active-goal cap the database already enforces (it retires the oldest goal when full).goals.writeOAuth scope, advertised in the server metadata. Writes are annotated (delete as destructive);get_goal_historystays undergoals.read.goal_typeenum, and history days clamped to 1-365.Testing
tests/unit/test_mcp_goals.py(26 tests), registered intest.sh. Covers the shared util (create/update/progress/delete/history, validation, not-found mapping) and both transports (REST status codes, MCP error codes, tool registration and scope).black --line-length 120 --skip-string-normalizationis clean andscripts/lint_async_blockers.pyreports no violations.