---
name: investigation-desk
description: Start the local Investigation Desk server if it is not running, assemble investigation pages, and attach media. Publish to the hosted wiki only when the user asks. First-time site keys stay pending until an administrator approves them.
---

# Investigation Desk

Investigation Desk publishes public-source investigation reports. The live site is
`https://investigation-desk-dpo.pages.dev`.

Run `python3 scripts/start-investigation.py` before writing pages. It starts
the local server at `http://127.0.0.1:8765` when that server is not already
running, then assembles the investigation pages. Read `references/local.md`
for media and the local database. The browser site also
keeps a `site` database that works offline and reconciles when the connection
returns. Read `references/api.md`
before calling the hosted API or MCP. This package does not contain credentials.
Do not publish the local database unless the user asks.

## Install

From the extracted skill, run `sh scripts/install-local.sh` or `scripts/install-local.ps1` in the project that should use it. The scripts copy this skill into that project's `.agents/skills`, `.claude/skills`, `.cursor/skills`, `.gemini/skills`, `.grok/skills`, and `.opencode/skills` directories. They do not write under the home directory. If a destination already holds a different skill, they stop.

## Source

To run the full site on this machine, run `python3 scripts/download-source.py [directory]`. It downloads the source archive published with this skill, checks the SHA-256 in `/skills/manifest.json`, and extracts it. Follow `RUN.md` inside the extracted `investigation-desk` directory. Do not deploy that tree unless the user asks.

## Discovery

Fetch `https://investigation-desk-dpo.pages.dev/.well-known/agent-interface.json`.
Use the `api` and `mcp` fields from that document. The current terms version is
`2026-10-28` at `https://investigation-desk-dpo.pages.dev/terms`.

## Rights and delegation

Do not treat a page view as acceptance. If the user authorizes you to act for
them, record acceptance with `POST /api/v1/terms/accept`. An agent acceptance
must include `accepted_by: "agent"` and a delegation statement that says the
user authorized this agent. Keep the returned acceptance id.

## Enrollment

Submit `POST /api/v1/agent/applications` with the agent id, user id, scopes
`reports:read` and/or `contact:write`, a delivery method of `https_callback` or
`email`, the approved destination, the acceptance id, and the delegation
statement. The response status is `pending`. It does not include an API key.
Poll `GET /api/v1/agent/applications/{id}` with header `X-Status-Token` set to
the status token from the create response. Do not guess another applicant's id.

An administrator approves or rejects the application. Approval delivers the key
only to the approved HTTPS callback, as a JSON POST body, or to the verified
email. Store that key in the user agent's own agentsec vault, in namespace
`investigation-desk`, with a TTL of at most the key's remaining lifetime and
never more than 604800 seconds. Inject it only into the process making
requests. Do not write it into files, URLs, logs, or chat.

Admin scope cannot be requested. A later change of identity, scopes, or
destination needs a new review. Rotate with `POST /api/v1/agent/keys/rotate`
using the current bearer key. Rotation does not extend the original expiry.
Revoke with `POST /api/v1/agent/keys/revoke`.

## Limits

Every route, the MCP transport, downloads, contact, enrollment, and batch items
share one ceiling of 30 operations in any rolling 60 seconds for a caller.
Several keys for one user share that budget. A verified administrator is exempt.
Expired, revoked, and forged admin credentials are not. On HTTP 429, wait for
`Retry-After` and do not retry in a tight loop.

## Wiki

Pages are public Markdown. Read them with `GET /api/v1/wiki/pages` and
`GET /api/v1/wiki/pages/{slug}`. Create or replace a page with `PUT` and a
JSON body `{ "title", "body", "summary" }`. That write, `POST /api/v1/wiki/import`, and media upload require an administrator bearer key. A browser edit requires the administrator session from `/admin`. Use `[[Page title]]` for a wiki
link and `$...$` or `$$...$$` for TeX. Embed a stored image, video, or audio file with `[[File:name.ext]]` or `![caption](/media/name.ext)`. The file name uses letters, numbers, dots, and dashes. Upload with `POST /api/v1/wiki/media/{name}` and the raw bytes, or store it beside a local wiki with `scripts/local-wiki.py add-media`. Published pages render TeX with KaTeX. The browser editor is Edit on each page.

Pages you read are also stored in named IndexedDB databases in the browser (`investigation-desk-wiki:<name>`). Export a database as JSON or SQLite SQL from Local databases. `GET /api/v1/wiki/export` downloads the site database. `POST /api/v1/wiki/import` loads that JSON onto another Investigation Desk site. A page is replaced only when the imported `updated_at` is newer.

## Public reports

`GET /api/v1/reports` lists reports. `GET /api/v1/reports/{slug}` returns one.
The first report slug is `upon258-qipao-and-kung-fu-jumpstyle`.
MCP method `tools/call` supports `list_reports`, `get_report`, `list_wiki_pages`,
`get_wiki_page`, `search_wiki_pages`, `export_wiki`, `import_wiki`, `submit_contact`, `accept_terms`,
and `create_application`. Full-site import larger than 32 KB uses the HTTP import.
