Skip to content

Add tool annotations to server-memory (9 tools, 0 annotated) #3400

@agentward-ai

Description

@agentward-ai

Request: Add tool annotations — @modelcontextprotocol/server-memory v0.6.3

Context

We ran an automated scan of this server via live JSON-RPC handshake. This server currently provides zero annotations on all 9 tools. Three tools perform permanent, cascading deletions with no undo — and none of them signal this to clients.

For reference, @modelcontextprotocol/server-filesystem annotates all 14 of its tools with readOnlyHint, destructiveHint, and idempotentHint. We're requesting the same treatment here.

Current state — 0/9 tools annotated

# Tool readOnlyHint destructiveHint idempotentHint openWorldHint
1 create_entities
2 create_relations
3 add_observations
4 delete_entities
5 delete_observations
6 delete_relations
7 read_graph
8 search_nodes
9 open_nodes

Suggested annotations — per tool

# Tool readOnlyHint destructiveHint idempotentHint openWorldHint
1 create_entities false false false false
2 create_relations false false false false
3 add_observations false false false false
4 delete_entities false true false false
5 delete_observations false true false false
6 delete_relations false true true false
7 read_graph true false true false
8 search_nodes true false true false
9 open_nodes true false true false

Suggested code change — top 3 priority tools

delete_entities (highest priority)

server.registerTool(
  "delete_entities",
  {
    description: "Delete multiple entities and their associated relations from the knowledge graph",
    inputSchema: { entityNames: z.array(z.string()) },
    annotations: {
      readOnlyHint: false,
      destructiveHint: true,
      idempotentHint: false,
      openWorldHint: false,
    },
  },
  handler
);

delete_observations

server.registerTool(
  "delete_observations",
  {
    description: "Delete specific observations from entities in the knowledge graph",
    inputSchema: { deletions: z.array(z.object({ entityName: z.string(), observations: z.array(z.string()) })) },
    annotations: {
      readOnlyHint: false,
      destructiveHint: true,
      idempotentHint: false,
      openWorldHint: false,
    },
  },
  handler
);

read_graph

server.registerTool(
  "read_graph",
  {
    description: "Read the entire knowledge graph",
    inputSchema: {},
    annotations: {
      readOnlyHint: true,
      idempotentHint: true,
      openWorldHint: false,
    },
  },
  handler
);

Rationale for each

delete_entitiesdestructiveHint: true, idempotentHint: false
Permanently deletes entities AND cascades to all associated relations. Calling it twice on overlapping entity sets could fail on the second call (entities already gone). This is the highest-risk tool on this server.

delete_observationsdestructiveHint: true, idempotentHint: false
Permanently removes specific observations. No undo, no trash.

delete_relationsdestructiveHint: true, idempotentHint: true
Permanently removes graph edges. Idempotent — deleting an already-deleted relation is a no-op.

create_entities / create_relations / add_observationsdestructiveHint: false, idempotentHint: false
Additive-only writes. Not destructive (they don't remove or overwrite data). Not idempotent (calling create twice produces duplicate entities).

read_graph / search_nodes / open_nodesreadOnlyHint: true, idempotentHint: true
Pure reads. No state mutation.

All tools → openWorldHint: false
The knowledge graph is local. No external network calls, no side effects outside the graph file.

Why this matters — chaining risks in multi-server setups

This server is commonly installed alongside filesystem, GitHub, and network-capable MCP servers. Without annotations, clients and downstream tools have to guess which operations are safe. As the MCP ecosystem grows and more tooling consumes annotations, having accurate metadata becomes increasingly important.

Concrete examples of composition risks that annotations help surface:

  • delete_entities triggered by prompt injection → An agent processing untrusted input (email, chat, web content) could be instructed to "clean up the knowledge graph." destructiveHint: true enables any MCP client that respects the spec to add a confirmation step before permanent deletion. Without it, the delete is indistinguishable from a read to annotation-aware clients.

  • read_graph + network server → The knowledge graph may accumulate sensitive data across sessions (user preferences, conversation history, project details). If an agent chains read_graph into an outbound network call, the graph could be exfiltrated. readOnlyHint: true on read_graph clarifies the read is safe in isolation — the risk is in the composition, not the individual tool. This distinction is what enables "allow reads, gate sends" as a policy pattern.

Impact

A client or tool that relies on server-provided annotations (as the MCP spec encourages) currently sees all 9 tools as identical — no risk differentiation at all. Proper annotations make the risk classification reliable without depending on heuristics like tool-name parsing.

The change is roughly 45 lines of metadata additions across 9 tool registrations. No behavior changes. The server-filesystem already sets the precedent.


Found via automated scan with AgentWard. Enumerated via live JSON-RPC handshake, protocol 2025-11-25.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions