feat(integrations): add MCP server exposing MemU as Claude Code tools#422
Open
Meur3ault wants to merge 1 commit into
Open
feat(integrations): add MCP server exposing MemU as Claude Code tools#422Meur3ault wants to merge 1 commit into
Meur3ault wants to merge 1 commit into
Conversation
Implements issue NevaMind-AI#387: register MemU as a Model Context Protocol server so the same memory primitives reach LLM agents through the standard MCP transport rather than via library-specific bindings. Two adapters share a common async tool layer (_MemUTools): - mcp_server.py runs through FastMCP (`memu-py[mcp]` extra). Five tools are registered with the `@mcp.tool` decorator; stdio transport is used when invoked as a module. - mcp_server_lowlevel.py binds the same tool implementations to a low-level mcp.server.lowlevel.Server (`memu-py[mcp-lowlevel]` extra) with explicit JSON Schemas, for users who prefer the official SDK. Both expose memu_memorize / memu_retrieve / memu_list_items / memu_list_categories / memu_clear_memory, all scoped by user_id. memu_memorize writes content to a temp file before delegating to MemoryService.memorize (which requires a resource_url), mirroring the pattern already used by the LangGraph integration. Register the server in Claude Code: pip install "memu-py[mcp]" claude mcp add memu -- python -m memu.integrations.mcp_server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Pull Request Summary
Resolves #387. Registers MemU as a Model Context Protocol server so the existing memory primitives reach LLM agents through the standard MCP transport rather than via library-specific bindings or the private
claude-agent-sdkwrapper currently shown inexamples/proactive/.✅ What does this PR do?
Adds two stdio MCP servers that share one async tool layer (
_MemUTools) and expose the same five tools:memu_memorize(content, user_id, modality="conversation")MemoryService.memorizememu_retrieve(query, user_id, limit=5)MemoryService.retrievememu_list_items(user_id)MemoryService.list_memory_itemsmemu_list_categories(user_id)MemoryService.list_memory_categoriesmemu_clear_memory(user_id)MemoryService.clear_memorysrc/memu/integrations/mcp_server.py— FastMCP entry point. Tools registered with@mcp.tooldecorators.pip install memu-py[mcp], thenpython -m memu.integrations.mcp_server.src/memu/integrations/mcp_server_lowlevel.py— same five tools throughmcp.server.lowlevel.Serverfor users who prefer the official SDK directly.pip install memu-py[mcp-lowlevel], thenpython -m memu.integrations.mcp_server_lowlevel.memu_memorizewrites the content to a temp file before callingMemoryService.memorize(which requires aresource_url), mirroring the pattern insrc/memu/integrations/langgraph.py.The CLI entry reads
MEMU_API_KEY(falling back toOPENAI_API_KEY) and optionalMEMU_BASE_URL/MEMU_CHAT_MODEL/MEMU_EMBED_MODEL, so it works against any OpenAI-compatible provider (OpenAI, DeepSeek, Qwen DashScope, OpenRouter, Together, local Ollama, …). Users who need separate chat and embedding endpoints can build aMemoryServiceprogrammatically and pass it tobuild_server; the example file shows this.Register with Claude Code:
🤔 Why is this change needed?
Issue #387 asks how to use MemU as a Claude Code plugin. Today
examples/proactive/memory/local/tools.pyusesclaude_agent_sdk.create_sdk_mcp_server, which is Anthropic's proprietary wrapper rather than the standard MCP transport every MCP client (Claude Code, Cursor, Continue, Zed, …) speaks. That example also only exposes two tools and is not part of thesrc/memu/integrationspublic surface.This PR adds a first-class MCP integration in
src/memu/integrations/that:MemoryService, not just retrieve + todos__main__so users register a single command🔍 Type of Change
✅ PR Quality Checklist
feat(integrations):)pyproject.toml, docstrings onbuild_server/_service_from_env, full registration example inexamples/mcp_server_example.py)MemULangGraphToolsand the existingexamples/proactiveserver are untouched; both new modules are optional via separate extras📌 Optional
OPENAI_API_KEYunset → server fails with a clearRuntimeErrorrather than a downstream provider error (covered bytest_raises_when_no_key_set)fastmcp/mcppackage →build_serverraises anImportErrorpointing at the correct extra to installmemorize/retrieve→ tool returns a"Failed to ..."string so the MCP client still gets a response instead of the request hangingexamples/proactive/to point at this integration once it landsTests
14 tests in
tests/integrations/test_mcp.py, all hermetic (no API key needed):_MemUToolsagainstAsyncMock(spec=MemoryService)_service_from_env(preference order, fallback, overrides, missing-key error)build_serveron each SDKlist_tools+call_tool memu_retrievereturns the expectedTextContentAdditionally validated locally end-to-end through Claude Code:
claude mcp add memu-local -- uv run … python -m memu.integrations.mcp_server, then in a fresh chat session calledmemu_memorize+memu_list_itemsagainstgpt-4o-mini+text-embedding-3-small. Both items came back as expected with the LLM-extracted profile/event memory types.