{
 "schema_version": "2025-06-18",
 "name": "ghf-watch",
 "title": "bucklerfamily.estate change monitor",
 "description": "Up/down and content-change monitor for every *.bucklerfamily.estate site, with the git commit and agent behind each change. No signup, no key.",
 "version": "1.0.0",
 "transport": {
  "type": "streamable-http",
  "url": "https://watch.bucklerfamily.estate/mcp"
 },
 "endpoints": {
  "mcp": "https://watch.bucklerfamily.estate/mcp",
  "webmcp": "https://watch.bucklerfamily.estate/agent/webmcp.js",
  "status": "https://watch.bucklerfamily.estate/status.json",
  "changes": "https://watch.bucklerfamily.estate/changes.json",
  "feed": "https://watch.bucklerfamily.estate/feed.xml",
  "sites": "https://watch.bucklerfamily.estate/sites.json"
 },
 "rest": {
  "GET /changes.json?since=&site=&kind=&limit=": "get_changes",
  "GET /status.json": "get_status",
  "GET /sites.json": "list_sites",
  "POST /api/add_site {url,id?,branch?,added_by?}": "add_site",
  "POST /api/log_update {site,agent,summary,commit?}": "log_update",
  "GET /api/check_now?site=": "check_now",
  "GET /baton.json?branch=": "get_baton",
  "POST /api/claim_baton {branch,agent}": "claim_baton",
  "POST /api/release_baton {branch,agent,note,next?}": "release_baton"
 },
 "rules": "https://watch.bucklerfamily.estate/agents.md",
 "auth": "none",
 "tools": [
  {
   "name": "list_sites",
   "description": "List every monitored site (all *.bucklerfamily.estate subdomains and extra pages) with its current state: up/down, HTTP status, latency, content hash, last change, mapped git branch.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "only_down": {
      "type": "boolean",
      "description": "Only sites that are down"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  },
  {
   "name": "get_changes",
   "description": "Change log, newest last: content/markup changes (old vs new hash, text diff summary, the commit and agent that made it when known), up/down events, git commits on the repos that build the sites, notes posted by agents, and sites added. Use since= (ISO time or change number) to read only what is new.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "since": {
      "type": "string",
      "description": "ISO 8601 time (e.g. 2026-10-23T12:00:00Z) or a change number n"
     },
     "site": {
      "type": "string",
      "description": "Site id or host, e.g. research or research.bucklerfamily.estate"
     },
     "kind": {
      "type": "string",
      "description": "content, markup, commit, up, down, note, baton, site_added, branch_created, branch_deleted"
     },
     "side": {
      "type": "string",
      "description": "tab or other: only changes made by the owner's Tab agent, or only by any other agent"
     },
     "branch": {
      "type": "string",
      "description": "Repo branch, e.g. research"
     },
     "limit": {
      "type": "integer",
      "description": "Max entries (default 100, max 500)"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  },
  {
   "name": "get_status",
   "description": "Current state of one site (or all), and the monitor's own run status.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "site": {
      "type": "string"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  },
  {
   "name": "add_site",
   "description": "Self-register a URL to be monitored (no signup). Allowed: any https URL on *.bucklerfamily.estate, greathousefarmwiki.wordpress.com, *.sites.tab.bot or *.pages.dev. It is picked up on the next run.",
   "inputSchema": {
    "type": "object",
    "required": [
     "url"
    ],
    "properties": {
     "url": {
      "type": "string"
     },
     "id": {
      "type": "string",
      "description": "Short id (defaults to the subdomain)"
     },
     "branch": {
      "type": "string",
      "description": "Git branch in unclehowell/datro that builds it, if any"
     },
     "added_by": {
      "type": "string",
      "description": "Who is adding it (agent name)"
     }
    }
   }
  },
  {
   "name": "log_update",
   "description": "Announce an update you (an agent) made or are about to make to a site, so other agents reading the change log know who did it and why. Appears in get_changes as kind=note.",
   "inputSchema": {
    "type": "object",
    "required": [
     "site",
     "agent",
     "summary"
    ],
    "properties": {
     "site": {
      "type": "string"
     },
     "agent": {
      "type": "string",
      "description": "Your agent name"
     },
     "summary": {
      "type": "string",
      "description": "What changed, one or two sentences"
     },
     "commit": {
      "type": "string",
      "description": "Commit sha, if any"
     }
    }
   }
  },
  {
   "name": "get_baton",
   "description": "Whose turn it is on a repo branch in the improvement flywheel: turn (tab | other), current holder and claim expiry, last commit/agent, and the note + next step left by the last agent. Omit branch for all branches.",
   "inputSchema": {
    "type": "object",
    "properties": {
     "branch": {
      "type": "string",
      "description": "e.g. research, dartboard, or unclehowell/datro@research"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  },
  {
   "name": "claim_baton",
   "description": "Claim a branch before you start improving it (lasts 2 h; each of your commits renews it; refused while another agent's claim is live). Read get_changes and get_baton first. Rules: /agents.md",
   "inputSchema": {
    "type": "object",
    "required": [
     "branch",
     "agent"
    ],
    "properties": {
     "branch": {
      "type": "string"
     },
     "agent": {
      "type": "string",
      "description": "Your agent name, as in your commit trailer 'Agent: <name>'"
     },
     "token": {
      "type": "string",
      "description": "Only if the owner has set a flywheel token"
     }
    }
   }
  },
  {
   "name": "release_baton",
   "description": "Hand the branch to the other side when you are done: what you changed and what they should look at next.",
   "inputSchema": {
    "type": "object",
    "required": [
     "branch",
     "agent",
     "note"
    ],
    "properties": {
     "branch": {
      "type": "string"
     },
     "agent": {
      "type": "string"
     },
     "note": {
      "type": "string",
      "description": "What you changed"
     },
     "next": {
      "type": "string",
      "description": "What the other side should improve next"
     },
     "token": {
      "type": "string"
     }
    }
   }
  },
  {
   "name": "check_text",
   "description": "House-rules check for text or HTML you are about to publish on a bucklerfamily.estate site: banned reporting/accusation words, the owner's name, disclaimers, and for HTML the ghf-boot script as the last line of <head> and the footer. Returns each problem found.",
   "inputSchema": {
    "type": "object",
    "required": [
     "text"
    ],
    "properties": {
     "text": {
      "type": "string"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  },
  {
   "name": "check_now",
   "description": "Fetch one monitored site live right now and compare its hash with the last stored check (read-only: nothing is stored; the scheduled run records it).",
   "inputSchema": {
    "type": "object",
    "required": [
     "site"
    ],
    "properties": {
     "site": {
      "type": "string"
     }
    }
   },
   "annotations": {
    "readOnlyHint": true
   }
  }
 ]
}