Handover

Shared, versioned context that humans and AI agents can publish, review, annotate, and continue.

Should I use this

Quality & Safety

A
Description quality
99%
Schema completeness
92%
Naming quality
50%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (17)

  • LOWTool 'handover.whoami' doesn't follow camelCase/snake_casein handover.whoami
  • LOWTool 'handover.search' doesn't follow camelCase/snake_casein handover.search
  • LOWTool 'handover.get' doesn't follow camelCase/snake_casein handover.get
  • LOWTool 'handover.read_artifact' doesn't follow camelCase/snake_casein handover.read_artifact
  • LOWTool 'handover.thread' doesn't follow camelCase/snake_casein handover.thread
  • LOWTool 'handover.annotations' doesn't follow camelCase/snake_casein handover.annotations
  • LOWTool 'handover.create' doesn't follow camelCase/snake_casein handover.create
  • LOWTool 'handover.continue' doesn't follow camelCase/snake_casein handover.continue
  • LOWTool 'handover.comment' doesn't follow camelCase/snake_casein handover.comment
  • LOWTool 'handover.annotate' doesn't follow camelCase/snake_casein handover.annotate

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~4,207Tokens (tool definitions)
~2.4 KBTypical response size
Significant attention impact (3.29% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "handover": {
      "url": "https://handover.sh/api/mcp"
    }
  }
}

Remote endpoints

https://handover.sh/api/mcpstreamable-http
https://handover.sh/api/mcp?profile=corestreamable-http

What it can do

Tool inventory

Tools (17)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢handover.whoami

Return the authenticated person or service agent, organization, workspace, role, and granted scopes. Call this before reading or publishing to confirm attribution and tenancy.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢handover.search(query, mode, status, limit, cursor)

Find current shared context with hybrid, semantic, or lexical retrieval across metadata and artifact content. Use an empty query to list recent handovers.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    },
    "mode": {
      "type": "string",
      "enum": [
        "hybrid",
        "semantic",
        "lexical"
      ],
      "default": "hybrid"
    },
    "status": {
      "type": "string",
      "enum": [
        "active",
        "archived",
        "trashed"
      ],
      "default": "active"
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 30
    },
    "cursor": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
🟢handover.get(handoverId, revisionId)

Read a handover snapshot, continuation brief, artifact metadata, and revision history. Omit revisionId for the current snapshot.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover identifier returned by handover.search or handover.create."
    },
    "revisionId": {
      "type": "string",
      "pattern": "^rev_",
      "description": "Optional immutable revision; omit to inspect the current revision."
    }
  },
  "required": [
    "handoverId"
  ],
  "additionalProperties": false
}
🟢handover.read_artifact(artifactId, maxBytes)

Read bounded artifact content after inspecting a handover. Text is returned as UTF-8 and binary content as base64; truncated results report that explicitly.

Input Schema

{
  "type": "object",
  "properties": {
    "artifactId": {
      "type": "string",
      "pattern": "^art_",
      "description": "Artifact identifier returned by handover.get."
    },
    "maxBytes": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2097152,
      "default": 524288,
      "description": "Maximum decoded bytes to return before reporting truncation."
    }
  },
  "required": [
    "artifactId"
  ],
  "additionalProperties": false
}
🟢handover.thread(handoverId)

Read comments, explicit mentions, assignments, and eligible collaborators without changing revision history.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover whose discussion and assignments should be read."
    }
  },
  "required": [
    "handoverId"
  ],
  "additionalProperties": false
}
🟢handover.annotations(handoverId, artifactId, revisionId, status)

Read revision-anchored file comments, selected text, status, authorship, and resolution metadata. Use status=open to find feedback that still needs action.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover whose annotation threads should be read."
    },
    "artifactId": {
      "type": "string",
      "pattern": "^art_"
    },
    "revisionId": {
      "type": "string",
      "pattern": "^rev_"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "resolved",
        "stale"
      ]
    }
  },
  "required": [
    "handoverId"
  ],
  "additionalProperties": false
}
🟡handover.create(title, summary, note, brief, artifacts)

Create durable shared context with an initial immutable revision. Authorship comes from the authenticated Handover identity.

Input Schema

{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "maxLength": 200,
      "description": "Short, specific name for the durable context."
    },
    "summary": {
      "type": "string",
      "maxLength": 2000,
      "description": "Concise explanation of what this handover contains."
    },
    "note": {
      "type": "string",
      "minLength": 1,
      "description": "Free-form continuation note recorded in the initial revision."
    },
    "brief": {
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "objective": {
          "type": "string",
          "description": "The outcome the next human or agent should continue toward."
        },
        "currentState": {
          "type": "string",
          "description": "Verified state at the moment this revision is published."
        },
        "decisions": {
          "type": "array",
          "description": "Decisions already made that successors should preserve.",
          "items": {
            "type": "string"
          },
          "maxItems": 50
        },
        "openQuestions": {
          "type": "array",
          "description": "Unresolved questions that still require evidence or judgment.",
          "items": {
            "type": "string"
          },
          "maxItems": 50
        },
        "nextSteps": {
          "type": "array",
          "description": "Concrete continuation steps for the receiving actor.",
          "maxItems": 50,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "id": {
                "type": "string",
                "description": "Optional stable identifier for this step."
              },
              "text": {
                "type": "string",
                "description": "One actionable continuation step."
              },
              "status": {
                "type": "string",
                "enum": [
                  "open",
                  "done"
                ],
                "description": "Whether the step still needs action."
              }
            },
            "required": [
              "text"
            ]
          }
        }
      },
      "description": "Structured continuation brief for humans and agents."
    },
    "artifacts": {
      "type": "array",
      "description": "Files attached to the initial immutable revision.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Filename shown in Handover."
          },
          "mediaType": {
            "type": "string",
            "description": "IANA media type, such as text/markdown or text/x-sql."
          },
          "content": {
            "type": "string",
            "description": "UTF-8 text, or base64 when encoding is base64."
          },
          "encoding": {
            "type": "string",
            "enum": [
              "utf-8",
              "base64"
            ],
            "default": "utf-8"
          }
        },
        "required": [
          "name",
          "content"
        ]
      },
      "minItems": 1,
      "maxItems": 50
    }
  },
  "required": [
    "title"
  ],
  "additionalProperties": false,
  "anyOf": [
    {
      "required": [
        "note"
      ]
    },
    {
      "required": [
        "brief"
      ]
    },
    {
      "required": [
        "artifacts"
      ]
    }
  ]
}
⚪handover.continue(handoverId, expectedRevisionId, note, brief, artifacts)

Append an immutable revision after reading the current snapshot. expectedRevisionId is mandatory to prevent overwriting another collaborator's work. Omitted artifacts are inherited; matching names are replaced.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover to continue after reading its current snapshot."
    },
    "expectedRevisionId": {
      "type": "string",
      "pattern": "^rev_",
      "description": "Current revision ID returned by handover.get; prevents lost updates."
    },
    "note": {
      "type": "string",
      "minLength": 1,
      "description": "What changed or what the next collaborator should know."
    },
    "brief": {
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "objective": {
          "type": "string",
          "description": "The outcome the next human or agent should continue toward."
        },
        "currentState": {
          "type": "string",
          "description": "Verified state at the moment this revision is published."
        },
        "decisions": {
          "type": "array",
          "description": "Decisions already made that successors should preserve.",
          "items": {
            "type": "string"
          },
          "maxItems": 50
        },
        "openQuestions": {
          "type": "array",
          "description": "Unresolved questions that still require evidence or judgment.",
          "items": {
            "type": "string"
          },
          "maxItems": 50
        },
        "nextSteps": {
          "type": "array",
          "description": "Concrete continuation steps for the receiving actor.",
          "maxItems": 50,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "id": {
                "type": "string",
                "description": "Optional stable identifier for this step."
              },
              "text": {
                "type": "string",
                "description": "One actionable continuation step."
              },
              "status": {
                "type": "string",
                "enum": [
                  "open",
                  "done"
                ],
                "description": "Whether the step still needs action."
              }
            },
            "required": [
              "text"
            ]
          }
        }
      },
      "description": "Updated structured continuation brief."
    },
    "artifacts": {
      "type": "array",
      "description": "New or replacement files; omitted files remain inherited.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Filename shown in Handover."
          },
          "mediaType": {
            "type": "string",
            "description": "IANA media type, such as text/markdown or text/x-sql."
          },
          "content": {
            "type": "string",
            "description": "UTF-8 text, or base64 when encoding is base64."
          },
          "encoding": {
            "type": "string",
            "enum": [
              "utf-8",
              "base64"
            ],
            "default": "utf-8"
          }
        },
        "required": [
          "name",
          "content"
        ]
      },
      "minItems": 1,
      "maxItems": 50
    }
  },
  "required": [
    "handoverId",
    "expectedRevisionId"
  ],
  "additionalProperties": false,
  "anyOf": [
    {
      "required": [
        "note"
      ]
    },
    {
      "required": [
        "brief"
      ]
    },
    {
      "required": [
        "artifacts"
      ]
    }
  ]
}
⚪handover.comment(handoverId, body, mentionPrincipalIds)

Append a discussion comment and optionally notify explicitly mentioned collaborators.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover discussion to append the comment to."
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 10000,
      "description": "Comment body in plain text or Markdown."
    },
    "mentionPrincipalIds": {
      "type": "array",
      "description": "Collaborator principal IDs to mention and notify.",
      "maxItems": 20,
      "items": {
        "type": "string",
        "pattern": "^prn_"
      }
    }
  },
  "required": [
    "handoverId",
    "body"
  ],
  "additionalProperties": false
}
🟡handover.annotate(handoverId, body, target, mentionPrincipalIds)

Add a durable comment anchored to selected text or lines in an immutable artifact revision. Read the artifact first and preserve the exact quote and surrounding context.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover containing the artifact being annotated."
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 10000,
      "description": "Actionable annotation body in plain text or Markdown."
    },
    "target": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "revisionId": {
          "type": "string",
          "pattern": "^rev_",
          "description": "Immutable revision containing the annotated artifact."
        },
        "artifactId": {
          "type": "string",
          "pattern": "^art_",
          "description": "Artifact containing the selected text or code."
        },
        "targetKind": {
          "type": "string",
          "enum": [
            "text",
            "code",
            "html"
          ],
          "description": "Rendering context used to relocate and display the annotation."
        },
        "selector": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "exact": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4000,
              "description": "The exact selected text."
            },
            "prefix": {
              "type": "string",
              "maxLength": 500,
              "description": "Text immediately before the selection."
            },
            "suffix": {
              "type": "string",
              "maxLength": 500,
              "description": "Text immediately after the selection."
            },
            "startOffset": {
              "type": "integer",
              "minimum": 0,
              "description": "Zero-based character offset where the selection starts."
            },
            "endOffset": {
              "type": "integer",
              "minimum": 0,
              "description": "Zero-based character offset immediately after the selection."
            },
            "startLine": {
              "type": "integer",
              "minimum": 0,
              "description": "Zero-based line where the selection starts."
            },
            "endLine": {
              "type": "integer",
              "minimum": 0,
              "description": "Zero-based line where the selection ends."
            }
          },
          "required": [
            "exact"
          ],
          "description": "Exact quote plus optional position and surrounding context."
        }
      },
      "required": [
        "revisionId",
        "artifactId",
        "targetKind",
        "selector"
      ],
      "description": "Immutable artifact location to anchor this annotation."
    },
    "mentionPrincipalIds": {
      "type": "array",
      "description": "Collaborator principal IDs to mention and notify.",
      "maxItems": 20,
      "items": {
        "type": "string",
        "pattern": "^prn_"
      }
    }
  },
  "required": [
    "handoverId",
    "body",
    "target"
  ],
  "additionalProperties": false
}
🟡handover.update_comment(handoverId, commentId, body, target, mentionPrincipalIds, ...)

Edit an authored comment, or resolve/reopen an annotation. Set resolvedRevisionId when a new handover revision addressed the feedback.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover containing the comment."
    },
    "commentId": {
      "type": "string",
      "pattern": "^cmt_",
      "description": "Comment or annotation to edit, resolve, or reopen."
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 10000,
      "description": "Replacement comment body; omit to preserve the current body."
    },
    "target": {
      "anyOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "revisionId": {
              "type": "string",
              "pattern": "^rev_",
              "description": "Immutable revision containing the annotated artifact."
            },
            "artifactId": {
              "type": "string",
              "pattern": "^art_",
              "description": "Artifact containing the selected text or code."
            },
            "targetKind": {
              "type": "string",
              "enum": [
                "text",
                "code",
                "html"
              ],
              "description": "Rendering context used to relocate and display the annotation."
            },
            "selector": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "exact": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 4000,
                  "description": "The exact selected text."
                },
                "prefix": {
                  "type": "string",
                  "maxLength": 500,
                  "description": "Text immediately before the selection."
                },
                "suffix": {
                  "type": "string",
                  "maxLength": 500,
                  "description": "Text immediately after the selection."
                },
                "startOffset": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Zero-based character offset where the selection starts."
                },
                "endOffset": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Zero-based character offset immediately after the selection."
                },
                "startLine": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Zero-based line where the selection starts."
                },
                "endLine": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Zero-based line where the selection ends."
                }
              },
              "required": [
                "exact"
              ],
              "description": "Exact quote plus optional position and surrounding context."
            }
          },
          "required": [
            "revisionId",
            "artifactId",
            "targetKind",
            "selector"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Replacement annotation target, or null to remove the anchor."
    },
    "mentionPrincipalIds": {
      "type": "array",
      "description": "Replacement collaborator mentions.",
      "maxItems": 20,
      "items": {
        "type": "string",
        "pattern": "^prn_"
      }
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "resolved"
      ],
      "description": "Open, resolve, or reopen the feedback thread."
    },
    "resolvedRevisionId": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^rev_"
        },
        {
          "type": "null"
        }
      ],
      "description": "Revision that addressed the feedback, or null when reopening."
    }
  },
  "required": [
    "handoverId",
    "commentId"
  ],
  "additionalProperties": false,
  "minProperties": 3
}
⚪handover.assign(handoverId, principalIds)

Replace the open assignments with the supplied collaborator identities. This changes collaboration state, not the immutable handover revision.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover whose open assignments will be replaced."
    },
    "principalIds": {
      "type": "array",
      "description": "Complete replacement list of assigned collaborator principal IDs.",
      "maxItems": 20,
      "items": {
        "type": "string",
        "pattern": "^prn_"
      }
    }
  },
  "required": [
    "handoverId",
    "principalIds"
  ],
  "additionalProperties": false
}
🟡handover.publish(handoverId, slug, entryPath, access, revisionMode, ...)

Create or update a stable /r/{slug}/ report projection of a Handover revision.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover to project as a stable report."
    },
    "slug": {
      "type": "string",
      "description": "Stable URL slug; generated from the title when omitted."
    },
    "entryPath": {
      "type": "string",
      "description": "Artifact path opened first when readers visit the report."
    },
    "access": {
      "type": "string",
      "enum": [
        "organization",
        "public"
      ],
      "description": "Who can open the report URL."
    },
    "revisionMode": {
      "type": "string",
      "enum": [
        "latest",
        "pinned"
      ],
      "description": "Follow new revisions automatically or keep one revision pinned."
    },
    "revisionId": {
      "type": "string",
      "pattern": "^rev_",
      "description": "Revision to pin; used when revisionMode is pinned."
    }
  },
  "required": [
    "handoverId"
  ],
  "additionalProperties": false
}
🟢handover.publication(handoverId, slug)

Read the stable report URL, entry file, access mode, and selected revision for a handover.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover whose publication should be inspected."
    },
    "slug": {
      "type": "string",
      "description": "Stable published report slug."
    }
  },
  "additionalProperties": false,
  "anyOf": [
    {
      "required": [
        "handoverId"
      ]
    },
    {
      "required": [
        "slug"
      ]
    }
  ]
}
🟢handover.pull(slug, files, includeBinary)

Return the selected files of a published report with paths, hashes, media types, and UTF-8 or base64 content.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "Stable published report slug."
    },
    "files": {
      "type": "array",
      "description": "Optional relative paths to return; omit for every file.",
      "items": {
        "type": "string"
      },
      "maxItems": 100
    },
    "includeBinary": {
      "type": "boolean",
      "default": false,
      "description": "Return binary files as base64 when true."
    }
  },
  "required": [
    "slug"
  ],
  "additionalProperties": false
}
🟢handover.okf.export(handoverId, revisionId)

Export a handover revision as an Open Knowledge Format bundle for another human or agent system.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Handover to export."
    },
    "revisionId": {
      "type": "string",
      "pattern": "^rev_",
      "description": "Immutable revision to export; defaults to the current revision."
    }
  },
  "required": [
    "handoverId"
  ],
  "additionalProperties": false
}
⚪handover.okf.import(handoverId, expectedRevisionId, mode, files)

Import Open Knowledge Format files into a new immutable Handover revision. Replaying the same bundle is idempotent.

Input Schema

{
  "type": "object",
  "properties": {
    "handoverId": {
      "type": "string",
      "pattern": "^hov_",
      "description": "Existing handover that will receive the imported bundle."
    },
    "expectedRevisionId": {
      "type": "string",
      "pattern": "^rev_",
      "description": "Current revision ID used to prevent conflicting imports."
    },
    "mode": {
      "type": "string",
      "enum": [
        "merge",
        "replace"
      ],
      "default": "merge",
      "description": "Merge bundle files with inherited artifacts or replace them."
    },
    "files": {
      "type": "array",
      "description": "Files from an Open Knowledge Format bundle.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "path": {
            "type": "string",
            "description": "Relative path of this file inside the OKF bundle."
          },
          "mediaType": {
            "type": "string",
            "description": "IANA media type; inferred from path when omitted."
          },
          "encoding": {
            "type": "string",
            "enum": [
              "utf-8",
              "base64"
            ],
            "description": "How content is encoded in this request."
          },
          "content": {
            "type": "string",
            "description": "UTF-8 text, or base64 when encoding is base64."
          }
        },
        "required": [
          "path",
          "content"
        ]
      },
      "minItems": 1,
      "maxItems": 100
    }
  },
  "required": [
    "handoverId",
    "files"
  ],
  "additionalProperties": false
}

Recommended Prompts

search_research
Search for information about [topic] using Handover
Expected tools: handover.search
find_specific
Find [specific item] using Handover
Expected tools: handover.search
retrieve_data
Get details about [item] from Handover
Expected tools: handover.get
fetch_info
Fetch [information type] using Handover
Expected tools: handover.get
search_then_create
Search for [item] and create a new [related item] using Handover
Expected tools: handover.searchhandover.create

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded17 tools
verifiedversion not recorded55 tools
verifiedversion not recorded17 tools
verifiedversion not recorded55 tools