Issue
The recent_activity and build_context MCP tools are leaking data across project boundaries, potentially exposing sensitive information from other projects.
What's happening
When calling recent_activity() while in project A, the tool correctly returns primary entities from project A, but the related results include relations and entities from projects B, C, etc. This breaks the fundamental isolation that users expect between projects.
Root cause
Looking at the code:
- Primary search ✅ -
SearchRepository.search() correctly filters by project_id
- Related search ❌ -
ContextService.find_related() uses raw SQL that completely ignores project boundaries
The recursive CTE in find_related() queries the entity and relation tables directly without any project_id filtering, so it pulls connected content from all projects.
Security implications
- Users creating "work" vs "personal" projects expect strict isolation
- Sensitive data from private projects can leak into queries from other projects
- No indication to users that cross-project data is being returned
- Violates the principle of least privilege
Suggested fix
Add project filtering to all three parts of the recursive CTE in ContextService.find_related():
-- Base case
WHERE e.id IN ({entity_id_values}) AND e.project_id = :project_id
-- Relations
JOIN entity e_from ON (r.from_id = e_from.id AND e_from.project_id = :project_id)
-- Connected entities
JOIN entity e ON (...AND e.project_id = :project_id)
The ContextService would need access to project_id similar to how the repositories work.
Impact
This affects any tool that uses context building - recent_activity, build_context, probably others. Should be treated as a security issue since it breaks data isolation guarantees.
Thanks for building such a cool project! Let me know if you need more details on the specific code paths.
Issue
The
recent_activityandbuild_contextMCP tools are leaking data across project boundaries, potentially exposing sensitive information from other projects.What's happening
When calling
recent_activity()while in project A, the tool correctly returns primary entities from project A, but the related results include relations and entities from projects B, C, etc. This breaks the fundamental isolation that users expect between projects.Root cause
Looking at the code:
SearchRepository.search()correctly filters byproject_idContextService.find_related()uses raw SQL that completely ignores project boundariesThe recursive CTE in
find_related()queries theentityandrelationtables directly without anyproject_idfiltering, so it pulls connected content from all projects.Security implications
Suggested fix
Add project filtering to all three parts of the recursive CTE in
ContextService.find_related():The
ContextServicewould need access toproject_idsimilar to how the repositories work.Impact
This affects any tool that uses context building -
recent_activity,build_context, probably others. Should be treated as a security issue since it breaks data isolation guarantees.Thanks for building such a cool project! Let me know if you need more details on the specific code paths.