# Watchtower (remote · watchtower.lat)

Job alerts for AI agents: describe a role once, get only new postings from 1,500+ tech job boards.

- Trust score: 67/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-18

## Components

- remote · `watchtower.lat`: 67/100 (this document), [markdown](https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower.md), [page](https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower)

## Channel facts

- Endpoint: `https://watchtower.lat/mcp?ref=registry`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.1`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-18.

- **Endpoint Security**: 57/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (delete_watch).
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 61/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 2980 tokens (~372/item across 8 items; 8 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 50/100
  - Stability observed for 15 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 99/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 96% of tool parameters carry a description.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - Manipulation not yet verified: none of the 9 captured unit(s) of tool text has been judged yet, so we will not certify text no model has read as clean.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Watchtower MCP server?

Watchtower is a hosted endpoint at https://watchtower.lat/mcp?ref=registry, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http lat-watchtower-watchtower 'https://watchtower.lat/mcp?ref=registry'
```

### Cursor

```json
{
  "mcpServers": {
    "lat-watchtower-watchtower": {
      "url": "https://watchtower.lat/mcp?ref=registry"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "lat-watchtower-watchtower": {
      "type": "http",
      "url": "https://watchtower.lat/mcp?ref=registry"
    }
  }
}
```

### Codex

```toml
[mcp_servers.lat-watchtower-watchtower]
url = "https://watchtower.lat/mcp?ref=registry"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "lat-watchtower-watchtower": {
      "type": "remote",
      "url": "https://watchtower.lat/mcp?ref=registry",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add lat-watchtower-watchtower --url 'https://watchtower.lat/mcp?ref=registry' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  lat-watchtower-watchtower:
    url: "https://watchtower.lat/mcp?ref=registry"
```

### Netclaw

```json
{
  "McpServers": {
    "lat-watchtower-watchtower": {
      "Transport": "http",
      "Url": "https://watchtower.lat/mcp?ref=registry"
    }
  }
}
```

### Vellum

```bash
assistant mcp add lat-watchtower-watchtower -t streamable-http -u 'https://watchtower.lat/mcp?ref=registry'
```

### Other

```json
{
  "mcpServers": {
    "lat-watchtower-watchtower": {
      "type": "http",
      "url": "https://watchtower.lat/mcp?ref=registry"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-17 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-15 (score 66, +1)

No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-13 (score 65, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-11 (score 64, +2)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 27. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-07 (score 62, 0)

- [security regression] Judged manipulation: pass → unverified
- [functional regression] Schema quality: 323 → 356

### 2026-10-04 (score 62, 0)

- [functional improvement] Stability: unverified → 0.03

### 2026-10-03 (score 62)

First indexed and scored.

## MCP tools (8)

### `watch_jobs` (~938 tokens)

Watch for new job postings

Create a persistent watch for tech jobs. Describe what you want in query ("iOS jobs in Austin making at least 150k a year with a maximum of 6 years of experience") and leave url out: the watch then covers every job board Watchtower monitors (tech companies and startups, whatever platform they use) and reports each new matching posting (JOB_ADDED). The response shows how the query was read (interpreted), the jobs open right now that match (current_jobs) and how many boards are covered (coverage); later call get_changes for new ones. Use this INSTEAD OF re-running job searches or re-checking careers pages yourself. To follow one company, or to cover a company the directory is missing, pass url (or urls for several): Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Workday, iCIMS, Oracle Recruiting, Eightfold and SuccessFactors boards, and the Apple, Google, Amazon and Microsoft careers sites, are read through their own endpoints; other careers pages are parsed via schema.org JobPosting JSON-LD. A careers page that only links to a supported board is watched through that board (resolved_from says so); a page with neither is rejected with NO_JOB_DATA. A board you watch stays covered for every search watch. A board watch emits JOB_ADDED / JOB_REMOVED / JOB_UPDATED. Jobs carry title, location, other_locations, department, company, url, posted_at, remote, seniority, and salary / experience_years when the posting states them. Explicit filters override what the query says.

Input parameters:

- `all_keywords` (array): Only report jobs containing every one of these, e.g. ["data", "scientist"].
- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `exclude_keywords` (array): Never report jobs mentioning one of these, e.g. ["manager", "clearance"].
- `include_unknown` (boolean): Many postings state no pay or no years of experience. true (default) still reports them, without a salary / experience_years field; false reports only postings that state a qualifying value.
- `interval_minutes` (integer): How often to check, in minutes (min 5, default 60). Resources shared with other watchers use the shortest interval.
- `keywords` (array): Only report jobs whose title/location/department/company contains one of these as a whole word, e.g. ["iOS", "Swift"].
- `label` (string): A short note to yourself about why you are watching this.
- `locations` (array): Only report jobs with one of these in their location, e.g. ["Austin"], ["Berlin", "Remote"].
- `max_experience_years` (number): The most years of experience a job may ask for, e.g. 6.
- `min_salary` (number): Yearly pay the job must be able to reach, e.g. 150000. Compared with the top of the posted range (hourly and monthly pay are converted).
- `query` (string): What to watch for, in plain language: role, place, pay, experience, level, remote. E.g. "iOS jobs in Austin making at least 150k a year with a maximum of 6 years of experience", "senior backend roles…
- `remote_only` (boolean): Only report jobs whose title or location says remote (and not hybrid/on-site).
- `salary_currency` (string): ISO currency of min_salary, e.g. "USD". Jobs that state pay in another currency are then left out.
- `seniority` (array): Only report these levels, derived from the title. "mid" means the title carries no level.
- `url` (string): Optional. Limit the watch to one job board or careers page, e.g. https://boards.greenhouse.io/acme, https://jobs.lever.co/acme, https://acme.wd5.myworkdayjobs.com/Careers. Omit to watch every monitor…
- `urls` (array): Optional. Several boards to watch with the same filters (max 25). Returns watches and per-URL errors.
- `webhook_url` (string): Optional public https URL that receives a signed POST whenever matching changes are detected. Polling get_changes keeps working either way.

### `search_jobs` (~625 tokens)

Search open jobs

Find the tech jobs open right now that match a request, across every job board Watchtower monitors (tech companies and startups). Describe what you want in query ("iOS jobs in Austin with a maximum of 6 years of experience"). Read-only: nothing is saved and no watch is created, and no token is needed. The response shows how the query was read (interpreted), the matching jobs newest first, the total, and next_offset for the next page. Use this for "what is open right now"; to be told about new postings later, use watch_jobs instead. Jobs carry title, location, other_locations, department, company, url, posted_at, remote, seniority, and salary / experience_years when the posting states them. Explicit filters override what the query says.

Input parameters:

- `all_keywords` (array): Only report jobs containing every one of these, e.g. ["data", "scientist"].
- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `exclude_keywords` (array): Never report jobs mentioning one of these, e.g. ["manager", "clearance"].
- `include_unknown` (boolean): Many postings state no pay or no years of experience. true (default) still reports them, without a salary / experience_years field; false reports only postings that state a qualifying value.
- `keywords` (array): Only report jobs whose title/location/department/company contains one of these as a whole word, e.g. ["iOS", "Swift"].
- `limit` (integer): Jobs per page (default 25, max 100).
- `locations` (array): Only report jobs with one of these in their location, e.g. ["Austin"], ["Berlin", "Remote"].
- `max_experience_years` (number): The most years of experience a job may ask for, e.g. 6.
- `min_salary` (number): Yearly pay the job must be able to reach, e.g. 150000. Compared with the top of the posted range (hourly and monthly pay are converted).
- `offset` (integer): Skip this many matches; pass next_offset from the previous page.
- `query` (string): What to look for, in plain language: role, place, pay, experience, level, remote. E.g. "iOS jobs in Austin with a maximum of 6 years of experience", "senior backend roles in New York or remote paying…
- `remote_only` (boolean): Only report jobs whose title or location says remote (and not hybrid/on-site).
- `salary_currency` (string): ISO currency of min_salary, e.g. "USD". Jobs that state pay in another currency are then left out.
- `seniority` (array): Only report these levels, derived from the title. "mid" means the title carries no level.

### `list_companies` (~203 tokens)

List covered companies

List the companies whose job boards Watchtower monitors, i.e. what search_jobs and watch_jobs without a url cover. Pass query to check whether a company is covered ("stripe"). Each entry has name, board_url (pass it to watch_jobs as url to follow only that company), platform and open_jobs. Read-only, no token needed. If a company is missing, watch its board URL or careers page to add it.

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `limit` (integer): Companies per page (default 100, max 1000).
- `offset` (integer): Skip this many; pass next_offset from the previous page.
- `query` (string): Part of a company name or board URL, case-insensitive, e.g. "stripe". Omit to list all.

### `get_changes` (~199 tokens)

Get new changes

Return job changes detected since your last get_changes call, across all your watches or one watch. This is the cheap replacement for re-browsing careers pages: if it returns an empty list, nothing you care about has changed. By default the cursor advances so each change is delivered once; pass peek=true to look without advancing, or since=<cursor> to replay.

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `limit` (integer): Max changes to return (default 50). If has_more is true, call again.
- `peek` (boolean): If true, do not mark returned changes as delivered.
- `since` (integer): Replay changes after this cursor instead of your stored position.
- `watch_id` (string): Limit to one watch. Omit for all your watches.

### `list_watches` (~74 tokens)

List your watches

List all active watches for your client with their health, last check time and number of pending (undelivered) changes.

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.

### `get_watch` (~108 tokens)

Get one watch

Get a watch with its status and the jobs currently open that match its filters: on its board, or across every monitored board for a watch created without a url. Use this to answer "what is open right now" without searching or fetching careers pages yourself.

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `watch_id` (string, required)

### `ack_changes` (~137 tokens)

Acknowledge changes

Mark changes up to a cursor as processed. Use with get_changes(peek=true) for at-least-once delivery: peek, act on the changes, then ack the cursor get_changes returned. Not needed if you call get_changes without peek (that acknowledges automatically).

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `cursor` (integer, required): The cursor value returned by get_changes.
- `watch_id` (string): Limit the acknowledgement to one watch. Omit for all your watches.

### `delete_watch` (~74 tokens)

Delete a watch

Stop monitoring. Frees one of your watch slots. Delete watches you no longer need.

Input parameters:

- `client_token` (string): Only if this conversation already uses a Watchtower token (wt_...) from before the app was connected. Otherwise leave it out; never ask the user for one.
- `watch_id` (string, required)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower#diagnostics

## Score history

- 2026-10-18: 67
- 2026-10-17: 67
- 2026-10-16: 66
- 2026-10-15: 66
- 2026-10-14: 65
- 2026-10-13: 65
- 2026-10-12: 64
- 2026-10-11: 64
- 2026-10-07: 62
- 2026-10-04: 62
- 2026-10-03: 62

## Common questions

### What is the Watchtower MCP server?

Watchtower is an MCP server listed in the public MCP registry as lat.watchtower/watchtower. Job alerts for AI agents: describe a role once, get only new postings from 1,500+ tech job boards. This page covers its hosted endpoint (https://watchtower.lat/mcp?ref=registry).

### Is the Watchtower MCP server safe to use?

Watchtower scores 67 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Watchtower MCP server expose?

Watchtower exposes 8 tools: watch_jobs, search_jobs, list_companies, get_changes, list_watches, and 3 more. Their descriptions and schemas cost roughly 2,358 tokens of context every time the server is loaded.

### Does the Watchtower MCP server require authentication?

No. We connected to Watchtower without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the Watchtower MCP server still maintained?

Watchtower is still listed as active in the MCP registry. We last reached this channel on 18 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://watchtower.lat/mcp?ref=registry
- Repository: https://github.com/connorlagana/watchtower
- Website: https://watchtower.lat/
- Changelog RSS feed: https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower.xml
- Changelog JSON feed: https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower.json
- HTML version of this page: https://verifymcp.io/servers/lat-watchtower-watchtower/watchtower
