Handover
Shared, versioned context that humans and AI agents can publish, review, annotate, and continue.
Should I use this
Quality & Safety
Findings (17)
- LOWin handover.whoami
- LOWin handover.search
- LOWin handover.get
- LOWin handover.read_artifact
- LOWin handover.thread
- LOWin handover.annotations
- LOWin handover.create
- LOWin handover.continue
- LOWin handover.comment
- LOWin handover.annotate
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
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-httphttps://handover.sh/api/mcp?profile=corestreamable-httpWhat it can do
Tool inventory
Tools (17)
🟢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
handover.searchhandover.searchhandover.gethandover.gethandover.searchhandover.createCommunity
Evidence