Skip to content

feat(mcp): add multi-user, multi-namespace, and session support to MCP tools#227

Merged
visahak merged 9 commits into
AgentToolkit:mainfrom
visahak:feat/multi-user-mcp
Apr 28, 2026
Merged

feat(mcp): add multi-user, multi-namespace, and session support to MCP tools#227
visahak merged 9 commits into
AgentToolkit:mainfrom
visahak:feat/multi-user-mcp

Conversation

@visahak

@visahak visahak commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add optional user_id, namespace_id, and session_id parameters to all MCP tools (get_entities, get_guidelines, save_trajectory, create_entity, publish_entity, unpublish_entity,
    delete_entity)
  • Introduce per-request namespace resolution with _resolve_namespace() — lazily initializes and caches non-default namespaces via ensure_namespace()
  • Replace singleton _namespace_initialized boolean with _initialized_namespaces: set[str] to track multiple namespaces
  • Inject user_id and session_id into trajectory and guideline entity metadata on writes
  • Keep retrieval broad — no user/session filtering on reads to preserve access to shared and pre-existing guidelines

Test plan

  • Namespace fallback to configured default when namespace_id is None
  • Explicit namespace override creates and caches new namespace
  • Namespace initialization is idempotent (second call skips ensure_namespace)
  • save_trajectory injects user_id and session_id into trajectory and guideline metadata
  • save_trajectory uses custom namespace_id for all storage calls
  • Backward compatibility: calling without new params produces identical behavior

addresses issue #225

Summary by CodeRabbit

  • New Features
    • Optional namespace selection for tools with per-namespace initialization/caching and resilient namespace resolution.
    • Added user_id and session_id parameters for entity and trajectory operations; these identifiers are recorded as metadata and used to scope reads.
  • Bug Fixes
    • Delete operations now enforce owner-based permission checks and return proper errors when unauthorized.
  • Tests
    • Expanded multi-namespace and metadata tests to validate behavior and backward compatibility.

@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9762a211-dba4-4649-824e-77aa745ed728

📥 Commits

Reviewing files that changed from the base of the PR and between c222a2f and 8e5319e.

📒 Files selected for processing (2)
  • altk_evolve/frontend/mcp/mcp_server.py
  • docs/guides/backend-configuration.md
✅ Files skipped from review due to trivial changes (1)
  • docs/guides/backend-configuration.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • altk_evolve/frontend/mcp/mcp_server.py

📝 Walkthrough

Walkthrough

Refactors namespace initialization from a single global flag to per-namespace tracking with a new _resolve_namespace helper. MCP tool signatures for entity retrieval, trajectory saving, and mutation now accept optional user_id, namespace_id, and session_id. Metadata for user/session is attached to saved trajectories and generated guidelines; delete now enforces owner permission.

Changes

Cohort / File(s) Summary
MCP Server Namespace & Tool Updates
altk_evolve/frontend/mcp/mcp_server.py
Replaced _namespace_initialized with per-namespace _initialized_namespaces; added _resolve_namespace() to ensure and cache namespaces. Extended tools (get_entities, get_guidelines, save_trajectory, create_entity, publish_entity, unpublish_entity, delete_entity) to accept optional user_id, namespace_id, and session_id. save_trajectory injects user_id/session_id metadata into trajectory and generated guideline entities, retries on missing namespaces, and scopes readback by attached metadata. delete_entity performs pre-delete fetch and enforces owner-based permission checks, handling missing namespaces via eviction and error responses.
Unit Tests
tests/unit/test_mcp_server.py
Reworked namespace bootstrap tests to use per-namespace cache; added tests for _resolve_namespace (default fallback, explicit namespace, caching) and extended save_trajectory tests to assert metadata injection, namespace override, and backward compatibility when user/session are omitted.
Docs: Backend Identity Model
docs/guides/backend-configuration.md
Adds documentation of Evolve identity model (namespace, user, session), mapping of identity metadata across filesystem/Postgres/Milvus backends, query/filter behavior, and notes on cross-namespace query characteristics and indexing considerations.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant MCP as MCP Server
    participant Resolver as Namespace Resolver
    participant Store as Entity Storage Client

    Client->>MCP: Call tool (namespace_id?, user_id?, session_id?)
    MCP->>Resolver: _resolve_namespace(namespace_id)
    alt namespace_id is None
        Resolver->>Resolver: Select configured default namespace
    else namespace_id provided
        Resolver->>Resolver: Use provided namespace
    end
    Resolver->>Resolver: Check `_initialized_namespaces` cache
    alt not initialized
        Resolver->>Store: ensure_namespace(effective_namespace)
        Store-->>Resolver: namespace ensured
        Resolver->>Resolver: Add to `_initialized_namespaces`
    end
    Resolver-->>MCP: Return resolved namespace
    MCP->>Store: Perform operation (resolved_namespace, entity data, metadata:user/session)
    Store-->>MCP: Result
    MCP-->>Client: Return response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • il leatmyhat
  • gaodan-fang
  • vinodmut

Poem

🐰
I hopped through namespaces, one by one,
No single flag—each now gets done.
User, session, safely penned,
Trajectories and guidelines blend.
A tidy hop, a job well-run.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: adding multi-user, multi-namespace, and session support to MCP tools, which is the primary focus across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 94.44% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…P tools

  Add optional user_id, namespace_id, and session_id parameters to all MCP
  tools. Namespace is resolved per-request with lazy initialization and
  caching. Trajectory and guideline writes inject user/session metadata.
  Retrieval stays broad (no user/session filtering) for backward
  compatibility.
@visahak visahak force-pushed the feat/multi-user-mcp branch from fe357ee to 9454b92 Compare April 28, 2026 16:29
coderabbitai[bot]

This comment was marked as resolved.

@visahak

visahak commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author

@illeatmyhat @gaodan-fang can you check the issue #225. I am working towards creating that feature in this PR. Let me know if there are issues we need to address.

visahak and others added 2 commits April 28, 2026 15:23
- Avoid double ensure_namespace in _resolve_namespace
- Redact raw user_id/session_id from INFO logs (moved to DEBUG)
- Add owner check to delete_entity matching publish/unpublish pattern
- Fix test mock: return_value must be iterable for save_trajectory loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@altk_evolve/frontend/mcp/mcp_server.py`:
- Around line 107-118: The cache _initialized_namespaces can become stale if a
namespace is deleted; update the code around where ensure_namespace() is called
(the block that checks default_ns in _initialized_namespaces and the analogous
block at lines 121-134) to handle missing namespaces: when a NamespaceNotFound
(or equivalent) error occurs on subsequent operations, remove/evict that
namespace from _initialized_namespaces and retry ensure_namespace() (or call
ensure_namespace() again on catching NamespaceNotFound) so the namespace is
recreated; ensure you reference and modify the logic that adds to
_initialized_namespaces so eviction and retry are applied symmetrically.
- Around line 329-333: The search_entities call that returns trajectories is
only filtering by metadata.task_id and can leak other users' data; update the
code that calls get_client().search_entities (the block returning
search_entities with namespace_id=resolved_ns, filters={"type": "trajectory",
"metadata.task_id": task_id, ...}) to include metadata.user_id and
metadata.session_id in the filters when those values are present (e.g., from the
current caller/context), constructing the filters dict to add
"metadata.user_id": user_id and "metadata.session_id": session_id conditionally
so the readback is scoped to the caller/session.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: edf4d024-d1fa-4815-aa6d-f9182f68b4a2

📥 Commits

Reviewing files that changed from the base of the PR and between 9454b92 and c222a2f.

📒 Files selected for processing (2)
  • altk_evolve/frontend/mcp/mcp_server.py
  • tests/unit/test_mcp_server.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/test_mcp_server.py

Comment thread altk_evolve/frontend/mcp/mcp_server.py
Comment thread altk_evolve/frontend/mcp/mcp_server.py
Filter search_entities return by user_id and session_id when present
so save_trajectory only returns the caller's own trajectories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
illeatmyhat
illeatmyhat previously approved these changes Apr 28, 2026

@illeatmyhat illeatmyhat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully clients can figure out which namespaces they're using

When a namespace is deleted externally, downstream operations now
catch NamespaceNotFoundException, evict the namespace from the
initialization cache, and either retry (read/write tools) or return
an error (entity mutation tools). The next call re-runs
ensure_namespace to recreate the namespace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@visahak

visahak commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author

hopefully clients can figure out which namespaces they're using

added the isolation details in the issue #225 will also add a readme section on it.

visahak and others added 4 commits April 28, 2026 16:09
Document how namespace, user_id, and session_id map to physical storage
across filesystem, PostgreSQL, and Milvus backends. Includes comparison
tables and key implications for multi-tenant deployments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "How Each Backend Stores These Layers" table already covers the
same information more concisely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@visahak visahak requested a review from illeatmyhat April 28, 2026 20:35
@visahak visahak merged commit 6cb2b45 into AgentToolkit:main Apr 28, 2026
16 checks passed
@visahak visahak deleted the feat/multi-user-mcp branch April 28, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants