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 every api::… function and HTTP trigger registration
  • src/mcp/server.ts – Implements the MCP dispatcher with mcp::tools::list and mcp::tools::call
  • src/mcp/tools-registry.ts – Builds the tool visibility catalog consumed by LLMs
  • src/index.ts – Wires both interfaces via registerApiTriggers and registerMcpEndpoints
  • src/cli.ts – Provides the standalone MCP server entry point via npx @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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →