nextlevelbuilder / nextlevelbuilder/goclaw

feat(mcp): wire per-agent MCP server loading in managed mode

Open
#3 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

agent:github-maintain enhancement maintain:triaged
Dominant language
Go
Stars
3.6k
Forks
1.1k
Avg merge
3d 5h
Merged PRs (30d)
24

Description

Summary

mcp.Manager.LoadForAgent() exists but is never called. In managed mode, MCP servers are still loaded globally from config.json (gateway.go:200-209), not per-agent from DB.

Current state (infrastructure is ready)

  • DB schema ready: mcp_servers, mcp_agent_grants (with config_overrides JSONB), mcp_user_grants
  • Store methods ready: ListAccessible(), GrantToAgent(), etc.
  • Manager method ready: LoadForAgent(ctx, agentID, userID)
  • HTTP API ready: /v1/mcp/servers/{id}/grants/agent

What's missing

  1. ListAccessible() doesn't SELECT config_overrides from mcp_agent_grants — the column exists but isn't included in the query result
  2. LoadForAgent() doesn't merge config_overrides.env into server env before spawning
  3. wireManagedExtras() / resolver doesn't call LoadForAgent() per agent — MCP is only initialized once globally
  4. MCP tools register into global registry — need per-agent clone (similar to DynamicToolLoader.LoadForAgent() pattern)

Use case

Running 2+ agents in managed mode with different MCP server configs. Example: separate NeuralMemory brains per agent via env var overrides in config_overrides:

// mcp_agent_grants.config_overrides for agent "tho-ngoc"
{"env": {"NEURALMEMORY_DIR": "/home/user/.neuralmemory-tho-ngoc"}}

// mcp_agent_grants.config_overrides for agent "rua"
{"env": {"NEURALMEMORY_DIR": "/home/user/.neuralmemory-rua"}}

Both agents share the same mcp_servers record (command: nmem mcp) but get different env vars per grant → brain isolation without duplicate server definitions.

Proposed approach

  1. Add ConfigOverrides []byte to MCPAccessInfo and include mag.config_overrides in ListAccessible() SQL
  2. In LoadForAgent(), parse config_overrides.env and merge into server env map before connectServer()
  3. In resolver's resolveAgent(), create per-agent MCP Manager with cloned registry (after DynamicToolLoader clone), call LoadForAgent()
  4. Handle MCP process lifecycle cleanup when agent loop stops

Happy to submit a PR if this aligns with your design intent.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with gateway.go:200-209, then trace wireManagedExtras() and resolver.resolveAgent(), comparing their flow with DynamicToolLoader.LoadForAgent(). Review MCPAccessInfo, ListAccessible(), and LoadForAgent() for config_overrides merging and per-agent registry cloning. Done means managed agents load their granted MCP servers with isolated environment overrides and MCP processes are cleaned up when agent loops stop.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, postgresql
Domain
ai, backend, databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.