Architectural Differences Between AgentMemory REST Endpoints and MCP Tools
AgentMemory exposes two distinct interfaces—fine-grained REST endpoints for human-oriented HTTP clients and a unified MCP tool dispatcher for LLM agents—with both ultimately delegating to the same internal memory functions but differing fundamentally in registration patterns, routing strategies, and payload handling.
The rohitg00/agentmemory repository implements a dual-interface architecture that separates human-facing HTTP APIs from machine-facing LLM tool protocols. Understanding the architectural difference between these two pathways is essential for developers integrating with memory operations programmatically versus those building AI agent workflows.
Registration and Routing Architecture
REST Endpoint Registration Pattern
REST endpoints in AgentMemory follow a traditional one-function-per-route model. Each capability is registered individually using sdk.registerFunction() with a trigger type of "http".
In src/triggers/api.ts, individual functions like api::observe or api::remember are registered alongside dedicated URL patterns such as /agentmemory/observe or /agentmemory/remember. This creates a discrete endpoint for every memory operation, allowing direct HTTP methods (GET, POST) to map to specific business logic.
MCP Tool Registration Pattern
MCP tools consolidate functionality under a unified dispatcher. Instead of registering separate endpoints per tool, src/mcp/server.ts registers only two handlers: mcp::tools::list and mcp::tools::call.
The mcp::tools::call handler contains a switch statement that routes incoming requests to the appropriate underlying function based on the tool name provided in the payload. This architecture minimizes the endpoint surface area while maximizing the action space available to LLM agents.
Request Handling and Payload Structure
Direct HTTP Parsing in REST
REST endpoints parse the HTTP request body directly through req.body. Each endpoint in src/triggers/api.ts (lines 60-88) handles its own validation, authentication checks, and parameter conversion before triggering the internal mem::… functions.
This approach provides fine-grained control over input processing, allowing endpoints to enforce specific schemas and return custom HTTP status codes (400, 401, 503) based on validation failures.
Generic Tool Dispatch in MCP
MCP tools receive a standardized {name, arguments} object. When POST /agentmemory/mcp/call receives a request, the handler extracts the tool name and argument payload, validates them against the tool schema, and maps them to the same internal mem::… functions used by the REST layer.
As implemented in src/mcp/server.ts (lines 58-88), this generic dispatch pattern abstracts HTTP plumbing away from the LLM, presenting a minimal token-efficient interface where the caller only needs to specify the tool name and parameters.
Authentication and Middleware
Per-Endpoint Middleware Chains
REST endpoints support granular authentication through middleware_function_ids. Each trigger can attach specific auth middleware like checkAuth or middleware::api-auth, allowing different endpoints to enforce varying security requirements.
This per-endpoint approach provides flexibility for public health checks (GET /agentmemory/health) while securing sensitive write operations with bearer token validation.
Centralized Authentication in MCP
The MCP interface performs authentication once at the entry point in registerMcpEndpoints. Since all tool calls route through the single /agentmemory/mcp/call endpoint, the auth check occurs at the top of the handler chain in src/mcp/server.ts.
No per-tool middleware chain exists because the dispatcher handles routing after authentication, simplifying the security model for machine-to-machine communication.
Response Formats and Error Handling
REST endpoints return rich JSON responses with explicit HTTP status codes and detailed error messages in the body. Each endpoint controls its own response semantics, enabling fine-grained client feedback for debugging and retry logic.
MCP tools return a uniform response payload wrapped in a content array: content: [{type:"text", text:…}]. While internal errors still communicate status_code information, the outer HTTP layer always returns 200 for successful tool invocations, adhering to the Model-Chat-Protocol specification for LLM consumption.
Implementation Examples
Calling the REST API
To store a memory via REST, clients target the specific endpoint with direct HTTP semantics:
curl -X POST https://localhost:3111/agentmemory/remember \
-H "Authorization: Bearer $AGENTMEMORY_SECRET" \
-d '{"content":"Remember this fact","type":"fact"}'
Implementation path: The request hits api::remember in src/triggers/api.ts (lines 1207-1226), which triggers mem::remember after validation.
Invoking MCP Tools
LLM agents interact through the unified call endpoint, passing the tool name and arguments explicitly:
POST /agentmemory/mcp/call
{
"name": "memory_save",
"arguments": {
"content": "Remember this fact",
"type": "fact"
}
}
Implementation path: mcp::tools::call receives the payload, matches "memory_save" in its switch statement, and triggers mem::remember as defined in src/mcp/server.ts (lines 58-88).
Listing Available Tools
To discover capabilities, LLM clients query the catalog endpoint:
curl https://localhost:3111/agentmemory/mcp/tools
This returns getVisibleTools() from src/mcp/tools-registry.ts, exposing the available tool definitions without the underlying implementation details.
Design Rationale and Key Source Files
The dual-interface architecture exists to serve distinct consumption models. REST endpoints cater to developers and automation scripts requiring conventional HTTP semantics, while MCP tools optimize for LLM agents operating under token budget constraints, presenting a concise action catalog without URL management overhead.
Both pathways ultimately delegate to the same core logic through sdk.trigger, ensuring consistent behavior while isolating transport concerns.
Critical implementation files include:
src/triggers/api.ts– Defines everyapi::…function and HTTP trigger registrationsrc/mcp/server.ts– Implements the MCP dispatcher withmcp::tools::listandmcp::tools::callsrc/mcp/tools-registry.ts– Builds the tool visibility catalog consumed by LLMssrc/index.ts– Wires both interfaces viaregisterApiTriggersandregisterMcpEndpointssrc/cli.ts– Provides the standalone MCP server entry point vianpx @agentmemory/mcp
Summary
- Registration model: REST uses individual function/trigger pairs per endpoint; MCP uses a unified dispatcher with a switch statement
- URL structure: REST exposes fine-grained routes (
/remember,/observe); MCP uses two endpoints (/tools,/call) - Payload handling: REST parses HTTP bodies directly per endpoint; MCP receives generic
{name, arguments}objects - Authentication: REST supports per-endpoint middleware chains; MCP uses centralized validation at the dispatcher level
- Response format: REST returns varied HTTP status codes; MCP wraps results in uniform content arrays with outer HTTP 200
- Target consumers: REST serves human developers and scripts; MCP serves LLM agents via the Model-Chat-Protocol
Frequently Asked Questions
Can I use both REST and MCP interfaces simultaneously?
Yes. The src/index.ts entry point initializes both registerApiTriggers and registerMcpEndpoints, allowing the same running instance to serve human-facing HTTP requests and LLM tool calls concurrently without冲突.
Why does MCP consolidate tools into a single endpoint while REST uses multiple?
MCP optimizes for LLM token efficiency and protocol standardization. A single call endpoint reduces the context window required to explain the API structure, while the tool list provides discoverability. REST prioritizes HTTP semantics and direct resource addressing for human developers.
Which interface should I use for Claude or other LLM integrations?
Use the MCP interface. The Model-Chat-Protocol is specifically designed for LLM tool use, providing structured discovery via mcp::tools::list and standardized invocation via mcp::tools::call, which Claude and similar agents can consume natively.
How do I add a new tool to the AgentMemory MCP interface?
Add a new case to the switch statement in mcp::tools::call within src/mcp/server.ts, then update the tool definition in src/mcp/tools-registry.ts so getVisibleTools() includes it in the catalog. The REST interface would require a new function registration and HTTP trigger in src/triggers/api.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →