fyi-mcp
The fyi-mcp server provides AI assistants with full CRUD access to a local Freedom of Information (FOI) request tracker database, along with authority management, sync monitoring, and health tools.
Request Management
List requests — Retrieve tracked Alaveteli FOI requests, newest first, with an optional limit
Retrieve a request — Fetch a specific request and its full correspondence history by ID
Create a request — Add a new FOI request with title, body, status, URL, tags, and user name
Update a request — Modify an existing request's fields
Delete a request — Permanently remove a request and all its correspondence
Authority Management
List authorities — View all government/public bodies stored in the database
Import authorities — Bulk import or update authority records (slug, name, URL)
Sync & Conflict Management
Sync monitor — Check global sync status, queue depth, latest sync time, and offline degradation state
List sync conflicts — View requests currently flagged as sync conflicts
Resolve a conflict — Mark a conflicted request as clean or keep it dirty
Check sync status — Read sync metadata globally or for a specific request
System Health
Check status — Verify database health and get a summary of record counts/metrics
Enables OpenAI Codex agents to interact with FYI CLI for FOI/OIA request management.
FYI CLI
A multi-jurisdiction Freedom-of-Information (FOI) client for Alaveteli-based platforms — track, submit, and archive official information requests across New Zealand, Australia, the UK, and any other Alaveteli deployment (foi-repository, WhatDoTheyKnow, FragDenStaat, and more), from a single privacy-focused CLI.
The project's core is a Rust workspace (fyi-core, fyi-cli, fyi-mcp); a legacy Python
package (fyi_system) remains available as a reference implementation but is no longer extended.
Where fyi-cli / fyi-mcp is listed
Registry / catalog | Package / server | Status | Link |
Official MCP Registry |
| Live | |
OpenAI plugin directory (Codex) |
| Assets ready — external submission pending | |
Anthropic Claude Connectors |
| Assets ready — hosted HTTPS deployment and external submission pending | |
Glama |
| Live | |
Smithery |
| Live (score pending) | |
PyPI |
| Live | |
Crates.io |
| Published / release flow | |
GitHub Releases | CLI + MCPB assets | Live | |
Awesome-MCP-Servers | Legal section entry | PR submitted | |
GitHub curated MCP ( | — | Blocked external (manual onboarding) | Tracked in #32 |
Draft / not yet submitted: Scoop, WinGet, Homebrew, Chocolatey, GHCR multi-arch workflow, PulseMCP, mcp.so, Docker MCP Catalog, mcp-get, OpenTools, AUR, nixpkgs, Snap, Flatpak, asdf/mise, Debian/PPA, Fedora/COPR.
cargo-binstall is already assets-ready and wired in-repo, but still depends on matching GitHub Release assets before it can be treated as a live distribution path. Codex and Anthropic packets are assets-ready but still require external submission.
Full status matrix (including planned channels): docs/registry-distribution-matrix.md.
🚀 Quick Start
# Install (Rust workspace, recommended)
cargo install --path crates/fyi-cli
# or: cargo install fyi-cli (once published to crates.io)
# Initialize
fyi-cli init-db
# Create your first request
fyi-cli register-request ministry-of-justice "OIA Request" "Request body..." --status draft
# Track and manage requests
fyi-cli list-requestsFull guide: QUICKSTART.md
Related MCP server: sourceright
✨ Features
🌐 Multi-Jurisdiction: Works with any Alaveteli deployment — foi-repository (NZ), WhatDoTheyKnow (UK), FragDenStaat (Germany), righttoknow.org.au (Australia), and more, with jurisdiction-aware metadata and localization on the way
🔒 Privacy-First: All data stored locally, optional encryption, Tor support
📊 Track Requests: Monitor FOI/OIA requests from creation to completion
🤖 Automated Monitoring: Watch instances for updates automatically
📈 Reports & Analytics: Generate dashboards, attention reports, handover docs
🔐 Secure Storage: Encrypted credentials, OS keyring integration
💻 CLI + MCP: Command-line tool and an MCP server for AI assistants
📦 Export Options: JSON, CSV, HTML export capabilities
🗄️ Faithful Archiving: WARC/WACZ capture of requests, correspondence, and attachments
📦 Installation
Full guide (Rust-first, all channels): INSTALL.md · version 0.1.2 · homepage github.com/edithatogo/fyi-cli
Path | Command / location | Notes |
Cargo (clone) |
| Recommended |
Cargo (crates.io) |
| When published |
cargo-binstall |
| assets-ready — needs matching release assets |
GitHub Releases | Prebuilt CLI / MCPB; check asset names per tag | |
PyPI (legacy) |
| Python |
MCP binary |
| Or MCPB from Releases |
MCP registries | Official / Glama / Smithery | live — see table above |
Containers |
| assets-ready — docs/containers.md |
Scoop, WinGet, Homebrew, Chocolatey, AUR, nix, Snap, Flatpak, Debian, Fedora, asdf, mise | Drafts under | Not claimed live — docs/installation-package-managers.md |
git clone https://github.com/edithatogo/fyi-cli.git
cd fyi-cli
cargo install --path crates/fyi-cli --locked
fyi-cli --helpLive listings and draft status: Where fyi-cli / fyi-mcp is listed · full matrix: docs/registry-distribution-matrix.md · MCP catalog checklist: packaging/mcp-catalogs/SUBMISSION_CHECKLIST.md.
📖 Documentation
Document | Description |
Full documentation (Astro + Starlight) | |
Canonical cross-reference for Python CLI, Rust CLI, and Rust MCP surfaces | |
Alaveteli/instance operator etiquette and outreach log | |
MCP catalogs, package managers, containers status | |
Smithery score + GitHub MCP onboarding playbook | |
Draft package-manager install notes (Scoop, WinGet, brew, …) | |
| |
5-minute getting started guide | |
Comprehensive user documentation | |
Installation guide (Rust-first; all channels) | |
How to get and configure API key | |
Configuration reference | |
Troubleshooting guide | |
Frequently asked questions | |
Version history | |
How to contribute | |
Citation metadata for releases | |
Zenodo release metadata source |
📚 Citation and Zenodo
Release metadata is versioned in CITATION.cff, .zenodo.json, and
artifacts/release/zenodo-mirror-manifest.json. DOI fields remain unset until the live Zenodo
record is verified for the tagged release.
🛡️ Security
Reporting a Vulnerability
Please do NOT report security vulnerabilities through public GitHub issues.
Use GitHub's private vulnerability reporting: https://github.com/edithatogo/fyi-cli/security/advisories/new
Security Policy: SECURITY.md
Security Features
✅ AES-256-GCM encryption for sensitive data
✅ PBKDF2-HMAC-SHA256 key derivation
✅ OS keyring integration for credential storage
✅ Tamper-evident audit logging
✅ Secure session management
✅ Input validation and sanitization
✅ Security headers (CSP, HSTS, X-Frame-Options)
✅ Automated security scanning (CodeQL, pip-audit, bandit)
🧪 Testing
# Rust release checks used by this repository
cargo +stable-x86_64-pc-windows-gnu fmt --all -- --check
cargo +stable-x86_64-pc-windows-gnu clippy --workspace --all-targets --all-features -- -D warnings
cargo +stable-x86_64-pc-windows-gnu test --workspace --all-features
# Python legacy/support checks
.\.venv\Scripts\python.exe -m pytest tests/test_release_readiness.py
# Opt-in live smoke test
FYI_LIVE_SMOKE=1 .\.venv\Scripts\python.exe -m pytest -m smoke tests/test_discovery_smoke.pyTest Coverage: Rust workspace checks are the release gate. Python support tests remain available for legacy docs and archive tooling.
🤝 Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Quick Start for Contributors
# Fork and clone
git clone https://github.com/YOUR_USERNAME/fyi-cli.git
cd fyi-cli
# Build & test the Rust workspace
cargo build --workspace --all-features
cargo test --workspace --all-features
# Make your changes, then submit a PR
git commit -m "feat: Add awesome feature"
git push origin feature/awesome-featureSee CONTRIBUTING.md for the full development setup, including the legacy
Python fyi_system package.
Code of Conduct
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
📊 Project Status
GitHub Projects
The project board for this repository is
fyi-cli Conductor Roadmap.
It mirrors the local .conductor/tracks.md registry and tracks completed
Conductor work, release-readiness items, and external MCP registry follow-ups.
The umbrella
Rare Insights on Open Policy from Aotearoa
project is synchronized at the item level. GitHub Projects does not support
nested projects, so synchronization is handled by
scripts/sync_github_projects.py and the
manual/scheduled project-sync workflow.
# Preview synchronization without changing either project
.\.venv\Scripts\python.exe scripts\sync_github_projects.py --dry-run
# Apply synchronization from fyi-cli project 6 into RIOPA project 4
.\.venv\Scripts\python.exe scripts\sync_github_projects.pyThe workflow requires a repository secret named PROJECT_SYNC_TOKEN with
GitHub Projects access for user-level ProjectsV2 writes. The sync is
conservative: it adds missing fyi-cli issue/PR items to RIOPA, copies shared
status values, sets the RIOPA mirror source to other unless a fyi-cli option
exists, and never deletes umbrella-board items.
Project Status
This project is actively evolving from an NZ-only tool into a multi-jurisdiction FOI/Alaveteli
platform built on the Rust workspace. Current work is tracked as
Conductor tracks under .conductor/tracks.md, mirrored to GitHub epic
issues (#37-#46) and their sub-issues. See the project board below for live status, and
CHANGELOG.md for released versions.
🔗 Compatible Platforms
FYI CLI works with any Alaveteli-based platform. The embedded jurisdiction catalog currently includes:
Platform | Region | URL |
foi-repository | New Zealand | foi-repository |
RightToKnow | Australia | |
WhatDoTheyKnow | United Kingdom | |
MyRightToKnow | Ireland | |
Ma Da Da (CADA) | France | |
Tu Derecho a Saber | Spain | |
FragDenStaat | Germany | |
Alaveteli | Any | Self-hosted instances |
See .conductor/tracks/jurisdiction-* for the rollout plan covering additional instances and
non-English localization.
📋 CLI Commands
Archive Discovery
The archive commands are read-only and do not require an API key.
# Import the official FYI authority list into the local SQLite database
fyi import-authorities
# Walk the public search feed for a date window and save discovered requests
fyi discover --date-from 2024-01-01 --date-to 2024-02-01 \
--checkpoint data/_state/discovery-2024-01.json \
--output data/_state/discovered-2024-01.jsonl
# Probe a numeric request ID range for gaps
fyi discover --backfill-ids --id-from 1 --id-to 5000 \
--output data/_state/backfill-1-5000.jsonl
# Compare feed discovery against the ID backfill
fyi discover-reconcile \
--feed data/_state/discovered-2024-01.jsonl \
--backfill data/_state/backfill-1-5000.jsonl \
--output data/_state/discovery-reconciliation.jsonRead-only authority discovery
discover-bodies keeps --base-url as the instance/capture URL. Use the
separate --catalog-url option only when the authority CSV is hosted at an
explicit alternate URL:
fyi discover-bodies --base-url https://www.righttoknow.org.au \
--catalog-url https://catalog.example/au-authorities.csv \
--rate-limit-name archive-discovery-au-rtk --format jsonl --output bodies.jsonlWith --format jsonl, each output line contains only the stable downstream
contract fields url_name, name, and tags[]. The default JSON format also
includes retrieval provenance for audit records. Both modes are read-only,
robots-aware, and use the configured shared limiter.
The JSON output includes the effective catalog URL, whether the default or an override was used, retrieval time, HTTP status, row count, and a SHA-256 of the raw CSV payload. The override is read-only and still uses the catalog host's robots policy, contactable User-Agent, retry backoff, and shared rate limiter. Treat an override URL as trusted configuration: it can redirect discovery to a different authority set and should be reviewed and recorded alongside archive provenance.
Discovery uses a contactable User-Agent, checks robots.txt, and backs off on
transient 429/5xx responses. Keep live runs polite: use small date windows,
resume with checkpoints, and coordinate archive work with the ethics guidance in
the sibling fyi-archive repo at docs/ethics-and-compliance.md.
The Rust fyi-core network path is the primary resource-aware implementation:
it parses RateLimit-*/Retry-After, adapts pacing, enforces request/bytes/time
guardrails, persists load memory, caches safe GETs, and can emit secret-redacted
JSONL traces. Python remains a deliberately compatible discovery/capture path
and follows the same identity and retry etiquette.
For concurrent workers, point discover and backfill at the same SQLite
database with --db. That enables the shared cross-worker limiter, which
reserves one aggregate request slot across processes and records both normal
reservations and transient-failure backoff events. Inspect the current state
with fyi rate-limit-status --db fyi_system.db.
CLI and MCP surfaces
The full command and server cross-reference is maintained in docs/cli-entrypoints-audit.md. It covers the Python CLI entrypoints (fyi, fyi-cli, fyi-system), the Rust CLI binary (fyi-cli), and the Rust MCP server (fyi-mcp) with its published registry pages.
Opt-in live smoke test:
FYI_LIVE_SMOKE=1 pytest -m smoke tests/test_discovery_smoke.pyThe AU RightToKnow smoke is bounded to one discovery page and at most five
request captures. It writes only to temporary test directories and remains
disabled unless FYI_LIVE_SMOKE=1 is explicitly set.
In the current live verification, RightToKnow returned HTTP 403 for the bounded JSON search request, so the smoke records an explicit external availability skip and does not attempt capture. This does not change default offline CI behavior or retry the denied request aggressively.
Faithful Archive Capture
fyi capture stores the public request JSON, rendered HTML, and attachments as
WARC records, deduplicates attachment bytes by SHA-256, and maintains a derived
request view for downstream dataset tooling.
fyi capture 12345 \
--data-dir data \
--dist-dir dist \
--max-bytes 500000000 \
--max-runtime-minutes 30Capture layout:
data/
warc/<runid>-<request>.warc.gz
attachments/<sha-prefix>/<sha256>
raw/requests/<authority>/<request_id>/
request.json
page.html
attachments.json
snapshot_meta.json
dist/
site_snapshots/<YYYYMMDD>.waczEach daily WACZ is appendable: subsequent captures add another WARC segment under
archive/ and merge the resource metadata in datapackage.json. Replay tooling
that supports WACZ/WARC can open the package from dist/site_snapshots/; for
low-level inspection, unzip it and read the WARC segments with warcio.
# Database
fyi init-db # Initialize database
fyi config show # Show configuration
# Requests
fyi register-request ... # Create new request
fyi list-requests # List all requests
fyi request-detail <id> # View request details
fyi set-status <id> <status> # Update status
# Submission
fyi build-prefilled-url <id> # Generate submission URL
# Monitoring
fyi ingest-feed <url> # Ingest RSS/Atom feed
fyi scheduler <url> # Run continuous monitoring
fyi discover # Discover public FYI requests
fyi discover-reconcile # Compare discovery JSONL outputs
# Reports
fyi dashboard --output ... # Generate dashboard
fyi attention-report # Generate attention report
fyi handover --output ... # Generate handover document
# Export
fyi export-requests # Export all requests
fyi export-bundle <id> # Export request bundle
# Security
fyi privacy-audit # Privacy compliance check
fyi health-check # System health verificationFull CLI reference: See fyi --help or USER_GUIDE.md
🏗️ Architecture
┌───────────────────────────────────────────────────────────────┐
│ fyi-cli workspace │
├───────────────────┬───────────────────────┬───────────────────┤
│ fyi-cli (bin) │ fyi-mcp (MCP server) │ legacy fyi_system │
│ CLI commands, │ JSON-RPC over stdio, │ (Python, reference │
│ TUI dashboard │ tools for AI assistants│ implementation) │
├───────────────────┴───────────────────────┴───────────────────┤
│ fyi-core (lib) │
│ Alaveteli API client · Tor client · encryption/keyring · │
│ sync engine · jurisdiction/instance registry (in progress) │
├─────────────────────────────────────────────────────────────────┤
│ SQLite database │
│ (requests, correspondence, authorities, sync_metadata) │
├─────────────────────────────────────────────────────────────────┤
│ Alaveteli instances: foi-repository · WhatDoTheyKnow · │
│ FragDenStaat · righttoknow.org.au · any self-hosted deploy │
└─────────────────────────────────────────────────────────────────┘📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
Built on the Alaveteli platform by mySociety
Inspired by the transparency work of foi-repository
Uses cryptography for encryption
📞 Support
Documentation: https://edithatogo.github.io/fyi-cli/
Discussions: https://github.com/edithatogo/fyi-cli/discussions
Made with ❤️ for transparency and privacy
Available Tools
15 toolscheck_statusCheck StatusARead-onlyIdempotent
Check FYI MCP SQLite readiness and return record-count metrics for requests, correspondence, and optional sync totals. Use as a first health probe or liveness check; prefer sync_monitor for queue/offline depth and list_requests for request content. Read-only, idempotent, and safe to call repeatedly; does not write data or contact remote services.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Overall service health, reported as healthy when database queries succeed. |
| metrics | Yes | Record-count metrics for core FYI tables. |
| database | Yes | Database connection state used by the MCP server. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. Description adds that it is safe to call repeatedly and does not write data or contact remote services, which supplements but does not contradict. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first states purpose and output, the second provides usage guidelines and behavioral traits. Every sentence adds value, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero input parameters and the existence of an output schema, the description fully informs about the return value (record-count metrics) and the tool's role. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema describes zero parameters with 100% coverage, so baseline is 4. Description does not need to add parameter details but mentions 'optional sync totals' which relates to output, not input. No missing information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks SQLite readiness and returns record-count metrics for specific entities (requests, correspondence, optional sync totals). It distinguishes from siblings by naming alternatives like sync_monitor and list_requests.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises use as a first health probe or liveness check, and provides clear alternatives: prefer sync_monitor for queue/offline depth and list_requests for request content. No usage ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_deadlineCompute DeadlineARead-onlyIdempotent
Compute a statutory FOI/OIA deadline from a start date and day count using the bleeding-edge fyi-core deadline engine. Use for local working-day or calendar-day deadline math; do not use for listing requests (list_requests) or sync health (sync_monitor). Read-only and idempotent; pure calculation with no database or network access. Returns a StatutoryDeadline JSON object (start_date, due_date, statutory_deadline_days, working_day_rule).
| Name | Required | Description | Default |
|---|---|---|---|
| days | Yes | Number of statutory days to count after start_date (working days by default). | |
| calendar | No | When true, count calendar days including weekends; when false/omitted, count weekdays only (Mon–Fri). | |
| start_date | Yes | Inclusive statutory period start date in YYYY-MM-DD (typically submission/receipt day). |
Output Schema
| Name | Required | Description |
|---|---|---|
| due_date | Yes | Computed due date (YYYY-MM-DD). |
| start_date | Yes | Start date echoed from input (YYYY-MM-DD). |
| instance_id | No | |
| working_day_rule | Yes | Rule applied: weekdays_only or calendar_days. |
| statutory_deadline_days | Yes | Day count used in the calculation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Disclosures go beyond annotations: 'Read-only and idempotent; pure calculation with no database or network access' and mentions return type. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: purpose, usage, behavior/return. No redundant information, well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a simple tool with output schema: covers purpose, usage, behavior, and return type adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so description adds little param detail beyond implicit mention of start date and day count, but adequate given high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool computes statutory FOI/OIA deadlines from start date and day count, and explicitly differentiates from siblings list_requests and sync_monitor.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (local working-day or calendar-day deadline math) and when not to use, listing sibling tools as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_requestCreate RequestA
Create a new local FYI/Alaveteli request row (draft or tracked) in SQLite. Use only when starting a new request; use update_request to change an existing ID and delete_request to remove one. Mutating and not idempotent: each call allocates a new ID. Does not submit to a remote authority, send email, or require network access; title and body are required.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Optional absolute FYI/Alaveteli URL when the request already exists online; omit for pure local drafts. | |
| body | Yes | Full request body or draft text to store locally (required, non-empty). | |
| tags | No | Optional local classification tags for filtering/reporting; replace-not-merge semantics only apply on update_request. | |
| title | Yes | Short public-facing request title (required, non-empty). | |
| status | No | Optional initial local lifecycle status. Prefer draft until the request is ready; does not trigger remote submission. | |
| user_name | No | Optional requester display name for local tracking only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| request | Yes | The newly created local request record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=false, idempotentHint=false), description adds 'Mutating and not idempotent: each call allocates a new ID. Does not submit to a remote authority, send email, or require network access.' No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-structured sentences. First sentence states purpose and scope; second gives usage constraints and behavioral notes. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers core behavior, exclusions, side effects, and sibling references. Output schema exists so return values need not be described. Complete for a tool with 6 params and 2 required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description only mentions that title and body are required, which is already in schema. No additional parameter guidance beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description explicitly states 'Create a new local FYI/Alaveteli request row (draft or tracked) in SQLite', with verb, resource, and scope. Also names siblings update_request and delete_request to distinguish.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly says 'Use only when starting a new request; use update_request to change an existing ID and delete_request to remove one.' Provides explicit when-to-use, when-not-to-use, and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_requestDelete RequestADestructive
Permanently delete a local request and all of its stored correspondence from SQLite. Use only after the agent confirms the ID should be discarded; prefer update_request for status/text edits and list_requests/retrieve_request for inspection. Destructive and irreversible in this database; does not delete anything on remote FYI/Alaveteli sites.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Stable local request ID to delete permanently. |
Output Schema
| Name | Required | Description |
|---|---|---|
| deleted | Yes | True when the local delete operation completed. |
| request_id | Yes | Request ID that was targeted for deletion. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Reinforces annotations' destructiveHint: true and adds scope limitation: 'does not delete anything on remote FYI/Alaveteli sites.' Provides context beyond annotations, though could mention error handling or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, no redundancy. Important information front-loaded. Every sentence contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, scope, usage guidelines, and alternatives. Simple one-parameter delete tool—description is thorough enough for correct tool selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Single parameter with 100% schema coverage. Description does not add extra meaning beyond schema's 'Stable local request ID to delete permanently.' Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Permanently delete a local request and all of its stored correspondence from SQLite' with specific verb and resource. Distinguishes from sibling tools by naming update_request for edits and list_requests/retrieve_request for inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to use only after confirming ID should be discarded, and provides clear alternatives (update_request for edits, list/retrieve for inspection). Notes destructive and irreversible nature.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
endorsed_route_statusEndorsed Route StatusBRead-onlyIdempotent
Evaluate an operator-published endorsed-client capability document locally. Read-only, fail-closed, and never enables a route or contacts a remote service.
| Name | Required | Description | Default |
|---|---|---|---|
| scopes | Yes | ||
| client_id | Yes | ||
| now_epoch | Yes | ||
| bulk_export | No | ||
| capabilities | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| quotas | No | |
| reason | No | |
| scopes | No | |
| status | Yes | |
| bulk_export | No | |
| instance_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds 'fail-closed' and 'never enables a route or contacts a remote service', which are valuable behavioral specifics beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action, no filler. Every word adds value. Ideal conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description covers the tool's core behavior and safety profile, it fails to explain what parameters mean despite low schema coverage. The output schema exists, reducing burden for return values, but parameter semantics are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning the schema only provides type info. The description does not explain the meaning or usage of any of the 5 parameters (scopes, client_id, now_epoch, bulk_export, capabilities). This is a critical gap for an agent to correctly invoke the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool evaluates an operator-published endorsed-client capability document locally. It specifies it's read-only and fail-closed, giving a precise action. However, it does not explicitly differentiate from siblings like check_status, which could be similar in spirit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for local evaluation and says it never enables a route or contacts remote services. This provides implicit guidance (don't use if you need to enable routes or contact remotes), but lacks explicit when-to-use or when-not-to-use statements or alternative tool suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_authoritiesImport AuthoritiesAIdempotent
Upsert local public authority reference records by slug for request routing and discovery. Use after list_authorities when seeding or refreshing the catalog; do not use for FOI request CRUD (create_request/update_request). Mutating but non-destructive and idempotent: same slug re-import updates name/url without creating duplicates; does not contact remote authority directories.
| Name | Required | Description | Default |
|---|---|---|---|
| authorities | Yes | Authority records to upsert; slug is the primary key, name is required, url is optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| imported | Yes | Number of authority records accepted for import or update. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true and destructiveHint=false. The description adds context beyond annotations: explains the upsert mechanics ('same slug re-import updates name/url without creating duplicates') and states 'does not contact remote authority directories', which is not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: first states purpose, second gives usage guideline, third explains behavioral traits. No filler; every sentence adds distinct value. The description is front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one parameter (array) fully described in schema, annotations present, and output schema exists (handles return value documentation). The description covers the upsert semantics, idempotency, and relation to sibling tools, making it fully informative for correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining that slug is the import key (primary key for upsert) and that the operation is idempotent and non-destructive, which clarifies the behavior of the 'authorities' parameter beyond its schema definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Upsert local public authority reference records by slug for request routing and discovery', specifying the verb (upsert) and resource (authority records by slug). It also distinguishes from siblings by explicitly saying 'do not use for FOI request CRUD (create_request/update_request)' and recommends usage 'after list_authorities'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when to use ('after list_authorities when seeding or refreshing the catalog') and when not to use ('do not use for FOI request CRUD'). Also names alternative tools (list_authorities, create_request, update_request), offering clear guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_authoritiesList AuthoritiesARead-onlyIdempotent
List imported public authority records (government/public bodies) used to route or classify FOI/OIA requests. Use to browse existing slugs/names before drafting; use import_authorities to add or upsert records, and list_requests for request data. Read-only and idempotent; returns the full local authority table (no pagination).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| authorities | Yes | Imported public authority records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. The description adds that the tool is read-only, idempotent, and returns the full local authority table without pagination, providing behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first states purpose and return value, the second gives usage guidelines. No superfluous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, usage, return behavior (full table, no pagination), and distinguishes from siblings. With an output schema present, no further details on return format are needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, and schema coverage is 100%. The description adds no param-specific info because none are needed; baseline for 0 params is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists imported public authority records for FOI/OIA routing, using the verb 'List' and specifying the resource. It distinguishes itself from sibling tools like import_authorities and list_requests.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('browse existing slugs/names before drafting') and when not to, naming alternative tools (import_authorities for adding/upserting, list_requests for request data).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_requestsList RequestsARead-onlyIdempotent
List locally tracked FYI/Alaveteli official information requests, ordered newest first. Use for dashboards, triage, or finding an ID before retrieve_request; do not use when you already know the ID and need correspondence (use retrieve_request) or only need health metrics (use check_status). Read-only and idempotent; does not contact remote authorities.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of request records to return (1-500). Defaults to 100 when omitted; raise only when the agent needs a broader scan. |
Output Schema
| Name | Required | Description |
|---|---|---|
| requests | Yes | Requests ordered by most recently updated. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, ensuring the agent knows it's safe and non-mutating. The description adds that it 'does not contact remote authorities', providing extra behavioral clarity beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences deliver full purpose, usage guidelines, and safety info. Front-loaded with the primary action and ordering. Every clause earns its place; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (1 parameter, no required fields, output schema exists), the description covers all necessary aspects: what it does, when to use it, parameter behavior, and safety guarantees. No gaps remain for an AI agent to handle this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the single parameter 'limit' with 100% description coverage. The description adds context: 'raise only when the agent needs a broader scan', which helps the agent decide when to increase the default. This adds value beyond the schema's own description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'List locally tracked FYI/Alaveteli official information requests, ordered newest first'. It specifies the data source and ordering, and distinguishes from siblings by mentioning not to use for known ID (retrieve_request) or health metrics (check_status).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides use cases ('dashboards, triage, or finding an ID before retrieve_request') and exclusions ('do not use when you already know the ID... or only need health metrics'), naming specific alternative tools. This leaves no ambiguity for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retrieve_requestRetrieve RequestARead-onlyIdempotent
Retrieve one locally tracked FYI/Alaveteli request and its stored correspondence by request ID. Use after list_requests when you need full text/history for a single request; do not use for bulk listing (list_requests) or database health (check_status). Read-only and idempotent; fails if the ID is missing; never contacts remote sites.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Stable local request ID to load (must already exist; typically from list_requests). |
Output Schema
| Name | Required | Description |
|---|---|---|
| request | Yes | The requested FYI/Alaveteli request record. |
| correspondence | Yes | Stored correspondence items linked to the request, in database order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHint. Description adds 'fails if the ID is missing' and 'never contacts remote sites', which are useful beyond annotations. However, the core behavioral traits (read-only, idempotent) are redundant with annotations, preventing a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, front-loaded with the core purpose, no wasted words. Every sentence adds distinct value: purpose, usage guidance, and behavioral transparency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple retrieval tool with one parameter and an existing output schema, the description covers all necessary aspects: what it does, when to use, failure behavior, and safety profile. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the parameter description in the schema is already clear ('Stable local request ID to load...'). The tool description does not add new parameter-level information beyond reinforcing the ID usage context. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb 'Retrieve' and resource 'one locally tracked FYI/Alaveteli request and its stored correspondence by request ID'. It explicitly distinguishes from sibling tools like list_requests and check_status, meeting the high standard for purpose clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('after list_requests when you need full text/history for a single request'), when not to use ('do not use for bulk listing or database health'), and names alternatives (list_requests, check_status). This is exemplary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_corpusSearch CorpusARead-onlyIdempotent
Search a built-in sample FOI document corpus with the bleeding-edge in-memory inverted index (demo). Use for experimental full-text search over sample titles/bodies; prefer list_requests/retrieve_request for real local SQLite requests. Read-only and idempotent; does not query the database or network. Returns ranked hits with id, score, and title.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of ranked hits to return (1-50). Defaults to 10. | |
| query | Yes | Free-text search query tokenized into alphanumeric terms. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hits | Yes | Ranked search hits (id, score, title). |
| query | Yes | Echo of the search query. |
| document_count | Yes | Number of documents in the demo corpus. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive. The description adds significant context beyond annotations: it specifies the tool does not query the database or network, and it describes the return format (ranked hits with id, score, title). This enhances transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, no filler. Every sentence adds value: purpose, usage guidance, and behavioral details. Highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool with an output schema, the description covers all necessary context: experimental nature, read-only, idempotent, no DB/network, return fields. With annotations providing safety guarantees, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters. The description adds minimal parameter meaning beyond the schema. It mentions the query is tokenized into alphanumeric terms, which is already in the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches a built-in sample FOI document corpus using an experimental in-memory index. It distinguishes itself from related tools like list_requests/retrieve_request by specifying it's for full-text search over sample data, not real database queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides guidance: 'Use for experimental full-text search over sample titles/bodies; prefer list_requests/retrieve_request for real local SQLite requests.' This tells the agent when to use this tool and when to use alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_conflictsSync ConflictsARead-onlyIdempotent
List locally tracked requests whose offline sync metadata is marked conflict. Use after sync_monitor shows conflict>0 to obtain IDs for review; use sync_resolve_conflict to clear a conflict, list_requests for all requests regardless of sync state. Read-only and idempotent; does not resolve conflicts or start network sync.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of conflicted request records to return (1-500). Defaults to 100 when omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| conflicts | Yes | Requests with sync_status set to conflict. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds that it does not resolve conflicts or start network sync, confirming and supplementing annotations. It also clarifies it deals with locally tracked requests, adding context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: purpose, usage context with alternatives, and behavioral notes. No redundant or unnecessary words; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple single-parameter input, full annotations, and presence of an output schema, the description sufficiently explains the tool's role in a workflow (after sync_monitor, before sync_resolve_conflict). It mentions the data source (locally tracked) and explicitly states what it does and does not do.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'limit' has full schema coverage (100%) with detailed description. The tool description does not add additional parameter information beyond what's in the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists locally tracked requests with offline sync metadata marked as conflict. It uses specific verbs and resources, and distinguishes from sibling tools like list_requests and sync_resolve_conflict.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: use after sync_monitor shows conflict>0 to obtain IDs, and offers alternatives (sync_resolve_conflict to clear, list_requests for all requests). This gives clear when-to-use and when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_monitorSync MonitorARead-onlyIdempotent
Summarize offline synchronization health: clean/dirty/conflict request counts, outgoing queue depth, latest sync time, and offline degradation indicators. Use for an operations overview; prefer sync_status for one request, sync_conflicts to list conflicted rows, and check_status for database connectivity/record totals. Read-only and idempotent; does not start a sync job.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| sync | Yes | Aggregate request sync counts and latest sync timestamp. |
| queue | Yes | Outgoing offline queue counts by pending, submitted, and failed status. |
| offline_degradation | Yes | Operational indicators showing queued local changes and dirty records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, destructiveHint=false. Description adds 'does not start a sync job' and reinforces read-only, idempotent nature, providing context beyond annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with key information (purpose, output list), followed by usage guidance. Every sentence is essential and concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, a rich output schema, and 13 siblings, the description covers purpose, usage, behavioral traits, and sibling differentiation completely. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, so the description correctly omits parameter details. The schema covers 100% with no properties. The description adds value by listing the output fields, which is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool summarizes offline synchronization health with specific metrics (clean/dirty/conflict counts, queue depth, latest sync time, degradation indicators). It distinguishes from siblings sync_status, sync_conflicts, and check_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('operations overview') and when not to, recommending alternatives for different tasks (sync_status for one request, sync_conflicts for conflicts, check_status for connectivity/totals).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_resolve_conflictResolve Sync ConflictAIdempotent
Resolve a local offline-sync conflict by updating only the request's sync metadata: mark_clean=true after the agent has reconciled local vs remote (status becomes clean); mark_clean=false keeps the row dirty for a later push. Prerequisite: the request should already appear in sync_conflicts. Side effects are local SQLite metadata only—no automatic merge of body text, no remote API calls, and no deletion of the request. Prefer sync_conflicts to list candidates and sync_status to inspect timestamps; do not use for ordinary field edits (update_request). Mutating, non-destructive, and idempotent for the same mark_clean value.
| Name | Required | Description | Default |
|---|---|---|---|
| mark_clean | No | true: mark reconciled/clean after manual review; false (default): leave dirty so a later offline push is expected. Does not rewrite title/body. | |
| request_id | Yes | Local request ID currently in conflict (from sync_conflicts). |
Output Schema
| Name | Required | Description |
|---|---|---|
| resolved | Yes | True when the conflict metadata was written successfully. |
| request_id | Yes | Request ID whose conflict state was updated. |
| sync_status | Yes | Resulting sync status string (typically clean or dirty). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint=true, destructiveHint=false), the description discloses that only local SQLite metadata is affected, no automatic merge, no remote API calls, no deletion, and idempotency for the same mark_clean value. This adds significant behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, well-structured, and front-loaded with the core action. Every sentence provides necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of sync conflict resolution, the description covers prerequisites, side effects, and differentiators. Output schema exists, so return values are handled. Complete and actionable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions, but the description adds behavioral context for mark_clean (e.g., effect on status and later push). This adds value beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool resolves a local offline-sync conflict by updating sync metadata (mark_clean). It uses specific verbs and resources, and distinguishes from sibling tools like update_request, sync_conflicts, and sync_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states prerequisites (request must appear in sync_conflicts), when to use (for conflict resolution), and when not to use (ordinary field edits). It also guides the agent to prefer sync_conflicts for listing and sync_status for timestamps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_statusSync StatusARead-onlyIdempotent
Read offline-sync metadata either as aggregate counts (omit request_id) or for one request (provide request_id). Use when you need clean/dirty/pending/conflict numbers or per-request last_synced timestamps; use sync_monitor for queue depth + offline degradation, sync_conflicts for conflicted rows only, and check_status for database health. Read-only and idempotent; does not mutate state or trigger network sync.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | No | Optional local request ID. Omit for aggregate counts; set to load that request's sync_status, last_synced_at, and conflict_version. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. Description adds 'does not mutate state or trigger network sync', providing extra behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, no wasted words. Purpose is front-loaded, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations and output schema, description fully covers the tool's behavior, usage modes, safety profile, and ties to sibling tools. Nothing missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (request_id) with 100% schema coverage. Description adds critical semantics: omit for aggregate counts, provide for per-request details including specific fields (sync_status, last_synced_at, conflict_version).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description specifies verb 'Read', resource 'offline-sync metadata', and two modes (aggregate or per-request). It clearly distinguishes from sibling tools like sync_monitor, sync_conflicts, and check_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('Use when you need clean/dirty/pending/conflict numbers or per-request last_synced timestamps') and provides specific alternatives for related tasks, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_requestUpdate RequestAIdempotent
Replace editable fields on an existing local FYI/Alaveteli request by ID and mark the record dirty for offline sync. Use when the request already exists and fields changed; use create_request for a new ID and delete_request to remove. Requires id, title, and body (full replacement for those fields, not a sparse patch). Mutating but non-destructive; safe to re-run with the same values; does not call remote APIs.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Existing local request ID to update (must already exist). | |
| url | No | Optional replacement absolute FYI/Alaveteli URL. | |
| body | Yes | Replacement request body or draft text (required; full replace). | |
| tags | No | Optional full replacement tag list (not appended to existing tags). | |
| title | Yes | Replacement request title (required; full replace, not merge). | |
| status | No | Optional replacement local lifecycle status; changing status does not submit or withdraw a remote request. | |
| user_name | No | Optional replacement requester display name; when omitted, existing local value is preserved. |
Output Schema
| Name | Required | Description |
|---|---|---|
| request | Yes | The updated local request record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=true and destructiveHint=false. The description adds context: 'mark the record dirty for offline sync', 'mutating but non-destructive', and 'does not call remote APIs', which enriches understanding beyond annotations. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph with efficient front-loading: first sentence states action, then usage guidelines, parameter semantics, and behavioral notes. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, 3 required, and an output schema, the description covers purpose, usage, parameter behaviors, and side effects (dirty marking, no remote calls). It is complete for an AI agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 100% schema coverage, the description adds crucial semantics: 'full replacement for those fields, not a sparse patch' for title/body, 'not appended to existing tags' for tags, and 'changing status does not submit or withdraw a remote request' for status. This goes well beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies 'Replace editable fields on an existing local FYI/Alaveteli request by ID and mark the record dirty for offline sync', which clearly states the verb, resource, and scope. It also distinguishes from siblings by mentioning create_request for new ID and delete_request for removal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use when the request already exists and fields changed', and provides alternatives: 'use create_request for a new ID and delete_request to remove'. Also notes it is safe to re-run with same values.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
15 tool updates
v0.1.1- Changed
check_status6 fields changed- added
Output schema / properties / database / descriptionAdded value: +"Database connection state used by the MCP server." - added
Output schema / properties / metrics / additionalPropertiesAdded value: +false - added
Output schema / properties / metrics / descriptionAdded value: +"Record-count metrics for core FYI tables." - added
Output schema / properties / metrics / propertiesAdded value: +{ + "sync": { + "additionalProperties": false, + "description": "Aggregate sync counts when sync metadata can be read.", + "properties": { + "clean": { + "description": "Number of clean synchronized requests.", + "minimum": 0, + "type": "integer" + }, + "conflict": { + "description": "Number of requests in sync conflict.", + "minimum": 0, + "type": "integer" + }, + "dirty": { + "description": "Number of requests with unsynced local changes.", + "minimum": 0, + "type": "integer" + }, + "pending": { + "description": "Number of requests pending sync.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Total number of requests represented in sync metadata.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "total", + "clean", + "dirty", + "pending", + "conflict" + ], + "type": [ + "object", + "null" + ] + }, + "total_correspondence": { + "description": "Number of correspondence records in the database.", + "minimum": 0, + "type": "integer" + }, + "total_requests": { + "description": "Number of request records in the database.", + "minimum": 0, + "type": "integer" + } +} - added
Output schema / properties / metrics / requiredAdded value: +[ + "total_requests", + "total_correspondence", + "sync" +] - added
Output schema / properties / status / descriptionAdded value: +"Overall service health, reported as healthy when database queries succeed."
- Added
compute_deadline - Changed
create_request14 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"The request body."New value: +"Full request body or draft text to store locally (required, non-empty)." - added
Input schema / properties / body / minLengthAdded value: +1 - changed
Input schema / properties / status / descriptionPrevious value: -"Status of the request."New value: +"Optional initial local lifecycle status. Prefer draft until the request is ready; does not trigger remote submission." - added
Input schema / properties / status / enumAdded value: +[ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict" +] - changed
Input schema / properties / tags / descriptionPrevious value: -"Optional list of tags."New value: +"Optional local classification tags for filtering/reporting; replace-not-merge semantics only apply on update_request." - changed
Input schema / properties / title / descriptionPrevious value: -"The request title."New value: +"Short public-facing request title (required, non-empty)." - added
Input schema / properties / title / minLengthAdded value: +1 - changed
Input schema / properties / url / descriptionPrevious value: -"The URL on Alaveteli or FYI."New value: +"Optional absolute FYI/Alaveteli URL when the request already exists online; omit for pure local drafts." - added
Input schema / properties / url / formatAdded value: +"uri" - changed
Input schema / properties / user_name / descriptionPrevious value: -"Name of the user."New value: +"Optional requester display name for local tracking only." - added
Output schema / properties / request / additionalPropertiesAdded value: +false - added
Output schema / properties / request / descriptionAdded value: +"The newly created local request record." - added
Output schema / properties / request / propertiesAdded value: +{ + "body": { + "description": "Request body or draft correspondence text.", + "minLength": 1, + "type": "string" + }, + "created_at": { + "description": "ISO-8601 creation timestamp when recorded.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Stable local request identifier.", + "minimum": 1, + "type": "integer" + }, + "status": { + "description": "Current Alaveteli/FYI request lifecycle status.", + "enum": [ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "Optional local tags attached to the request.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "description": "Public title of the official information request.", + "minLength": 1, + "type": "string" + }, + "updated_at": { + "description": "ISO-8601 update timestamp used for ordering and sync.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Canonical public request URL when available.", + "format": "uri", + "type": [ + "string", + "null" + ] + }, + "user_name": { + "description": "Requester display name when known.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / request / requiredAdded value: +[ + "id", + "title", + "body" +]
- Changed
delete_request4 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"The request ID."New value: +"Stable local request ID to delete permanently." - added
Input schema / properties / id / minimumAdded value: +1 - added
Output schema / properties / deleted / descriptionAdded value: +"True when the local delete operation completed." - added
Output schema / properties / request_id / descriptionAdded value: +"Request ID that was targeted for deletion."
- Added
endorsed_route_status - Changed
import_authorities10 fields changed- changed
Input schema / properties / authorities / descriptionPrevious value: -"Authority records to import."New value: +"Authority records to upsert; slug is the primary key, name is required, url is optional." - added
Input schema / properties / authorities / items / descriptionAdded value: +"Public authority record used to route or classify requests." - changed
Input schema / properties / authorities / items / properties / name / descriptionPrevious value: -"Authority name."New value: +"Human-readable public authority name." - added
Input schema / properties / authorities / items / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / authorities / items / properties / slug / descriptionPrevious value: -"Authority slug."New value: +"Stable authority slug used as an import key." - added
Input schema / properties / authorities / items / properties / slug / minLengthAdded value: +1 - changed
Input schema / properties / authorities / items / properties / url / descriptionPrevious value: -"Optional authority URL."New value: +"Optional public authority URL." - added
Input schema / properties / authorities / items / properties / url / formatAdded value: +"uri" - changed
Input schema / properties / authorities / items / properties / url / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / imported / descriptionAdded value: +"Number of authority records accepted for import or update."
- Changed
list_authorities5 fields changed- added
Output schema / properties / authorities / descriptionAdded value: +"Imported public authority records." - added
Output schema / properties / authorities / items / additionalPropertiesAdded value: +false - added
Output schema / properties / authorities / items / descriptionAdded value: +"Public authority record used to route or classify requests." - added
Output schema / properties / authorities / items / propertiesAdded value: +{ + "name": { + "description": "Human-readable public authority name.", + "minLength": 1, + "type": "string" + }, + "slug": { + "description": "Stable authority slug used as an import key.", + "minLength": 1, + "type": "string" + }, + "url": { + "description": "Optional public authority URL.", + "format": "uri", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / authorities / items / requiredAdded value: +[ + "slug", + "name" +]
- Changed
list_requests8 fields changed- added
Input schema / properties / limit / defaultAdded value: +100 - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of requests to return."New value: +"Maximum number of request records to return (1-500). Defaults to 100 when omitted; raise only when the agent needs a broader scan." - added
Input schema / properties / limit / maximumAdded value: +500 - added
Input schema / properties / limit / minimumAdded value: +1 - added
Output schema / properties / requests / items / additionalPropertiesAdded value: +false - added
Output schema / properties / requests / items / descriptionAdded value: +"One tracked FYI/Alaveteli request." - added
Output schema / properties / requests / items / propertiesAdded value: +{ + "body": { + "description": "Request body or draft correspondence text.", + "minLength": 1, + "type": "string" + }, + "created_at": { + "description": "ISO-8601 creation timestamp when recorded.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Stable local request identifier.", + "minimum": 1, + "type": "integer" + }, + "status": { + "description": "Current Alaveteli/FYI request lifecycle status.", + "enum": [ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "Optional local tags attached to the request.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "description": "Public title of the official information request.", + "minLength": 1, + "type": "string" + }, + "updated_at": { + "description": "ISO-8601 update timestamp used for ordering and sync.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Canonical public request URL when available.", + "format": "uri", + "type": [ + "string", + "null" + ] + }, + "user_name": { + "description": "Requester display name when known.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / requests / items / requiredAdded value: +[ + "id", + "title", + "body" +]
- Changed
retrieve_request11 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"The unique request ID."New value: +"Stable local request ID to load (must already exist; typically from list_requests)." - added
Input schema / properties / id / minimumAdded value: +1 - added
Output schema / properties / correspondence / descriptionAdded value: +"Stored correspondence items linked to the request, in database order." - added
Output schema / properties / correspondence / items / additionalPropertiesAdded value: +false - added
Output schema / properties / correspondence / items / descriptionAdded value: +"A correspondence item associated with an FYI request." - added
Output schema / properties / correspondence / items / propertiesAdded value: +{ + "attachments": { + "description": "Optional attachment URLs or identifiers linked to the correspondence.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "body": { + "description": "Message body or extracted correspondence text.", + "minLength": 1, + "type": "string" + }, + "direction": { + "description": "Whether the correspondence was sent by the requester or received as an authority response.", + "enum": [ + "request", + "response" + ], + "type": "string" + }, + "sent_at": { + "description": "ISO-8601 sent timestamp when captured.", + "format": "date-time", + "type": "string" + }, + "state": { + "description": "Optional Alaveteli correspondence state when captured.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / correspondence / items / requiredAdded value: +[ + "direction", + "body", + "sent_at" +] - added
Output schema / properties / request / additionalPropertiesAdded value: +false - added
Output schema / properties / request / descriptionAdded value: +"The requested FYI/Alaveteli request record." - added
Output schema / properties / request / propertiesAdded value: +{ + "body": { + "description": "Request body or draft correspondence text.", + "minLength": 1, + "type": "string" + }, + "created_at": { + "description": "ISO-8601 creation timestamp when recorded.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Stable local request identifier.", + "minimum": 1, + "type": "integer" + }, + "status": { + "description": "Current Alaveteli/FYI request lifecycle status.", + "enum": [ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "Optional local tags attached to the request.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "description": "Public title of the official information request.", + "minLength": 1, + "type": "string" + }, + "updated_at": { + "description": "ISO-8601 update timestamp used for ordering and sync.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Canonical public request URL when available.", + "format": "uri", + "type": [ + "string", + "null" + ] + }, + "user_name": { + "description": "Requester display name when known.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / request / requiredAdded value: +[ + "id", + "title", + "body" +]
- Added
search_corpus - Changed
sync_conflicts9 fields changed- added
Input schema / properties / limit / defaultAdded value: +100 - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of conflicts to return."New value: +"Maximum number of conflicted request records to return (1-500). Defaults to 100 when omitted." - added
Input schema / properties / limit / maximumAdded value: +500 - added
Input schema / properties / limit / minimumAdded value: +1 - added
Output schema / properties / conflicts / descriptionAdded value: +"Requests with sync_status set to conflict." - added
Output schema / properties / conflicts / items / additionalPropertiesAdded value: +false - added
Output schema / properties / conflicts / items / descriptionAdded value: +"A request currently marked as a sync conflict." - added
Output schema / properties / conflicts / items / propertiesAdded value: +{ + "body": { + "description": "Request body or draft correspondence text.", + "minLength": 1, + "type": "string" + }, + "created_at": { + "description": "ISO-8601 creation timestamp when recorded.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Stable local request identifier.", + "minimum": 1, + "type": "integer" + }, + "status": { + "description": "Current Alaveteli/FYI request lifecycle status.", + "enum": [ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "Optional local tags attached to the request.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "description": "Public title of the official information request.", + "minLength": 1, + "type": "string" + }, + "updated_at": { + "description": "ISO-8601 update timestamp used for ordering and sync.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Canonical public request URL when available.", + "format": "uri", + "type": [ + "string", + "null" + ] + }, + "user_name": { + "description": "Requester display name when known.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / conflicts / items / requiredAdded value: +[ + "id", + "title", + "body" +]
- Changed
sync_monitor12 fields changed- added
Output schema / properties / offline_degradation / additionalPropertiesAdded value: +false - added
Output schema / properties / offline_degradation / descriptionAdded value: +"Operational indicators showing queued local changes and dirty records." - added
Output schema / properties / offline_degradation / propertiesAdded value: +{ + "dirty_records": { + "description": "Requests with unsynced local changes.", + "minimum": 0, + "type": "integer" + }, + "queued_changes": { + "description": "Pending plus failed outgoing queue entries.", + "minimum": 0, + "type": "integer" + } +} - added
Output schema / properties / offline_degradation / requiredAdded value: +[ + "queued_changes", + "dirty_records" +] - added
Output schema / properties / queue / additionalPropertiesAdded value: +false - added
Output schema / properties / queue / descriptionAdded value: +"Outgoing offline queue counts by pending, submitted, and failed status." - added
Output schema / properties / queue / propertiesAdded value: +{ + "failed": { + "description": "Outgoing queue entries that failed submission.", + "minimum": 0, + "type": "integer" + }, + "pending": { + "description": "Outgoing queue entries waiting to be submitted.", + "minimum": 0, + "type": "integer" + }, + "submitted": { + "description": "Outgoing queue entries already submitted.", + "minimum": 0, + "type": "integer" + } +} - added
Output schema / properties / queue / requiredAdded value: +[ + "pending", + "submitted", + "failed" +] - added
Output schema / properties / sync / additionalPropertiesAdded value: +false - added
Output schema / properties / sync / descriptionAdded value: +"Aggregate request sync counts and latest sync timestamp." - added
Output schema / properties / sync / propertiesAdded value: +{ + "clean": { + "description": "Requests known to be cleanly synchronized.", + "minimum": 0, + "type": "integer" + }, + "conflict": { + "description": "Requests with unresolved sync conflicts.", + "minimum": 0, + "type": "integer" + }, + "dirty": { + "description": "Requests with unsynced local changes.", + "minimum": 0, + "type": "integer" + }, + "latest_sync": { + "description": "Most recent successful synchronization timestamp.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "pending": { + "description": "Requests pending synchronization.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Total number of requests tracked by sync metadata.", + "minimum": 0, + "type": "integer" + } +} - added
Output schema / properties / sync / requiredAdded value: +[ + "total", + "clean", + "dirty", + "pending", + "conflict", + "latest_sync" +]
- Changed
sync_resolve_conflict7 fields changed- added
Input schema / properties / mark_clean / defaultAdded value: +false - changed
Input schema / properties / mark_clean / descriptionPrevious value: -"Set true to mark the conflict clean; false keeps it dirty."New value: +"true: mark reconciled/clean after manual review; false (default): leave dirty so a later offline push is expected. Does not rewrite title/body." - changed
Input schema / properties / request_id / descriptionPrevious value: -"The request ID to resolve."New value: +"Local request ID currently in conflict (from sync_conflicts)." - added
Input schema / properties / request_id / minimumAdded value: +1 - added
Output schema / properties / request_id / descriptionAdded value: +"Request ID whose conflict state was updated." - added
Output schema / properties / resolved / descriptionAdded value: +"True when the conflict metadata was written successfully." - added
Output schema / properties / sync_status / descriptionAdded value: +"Resulting sync status string (typically clean or dirty)."
- Changed
sync_status7 fields changed- changed
Input schema / properties / request_id / descriptionPrevious value: -"Optional request ID for per-request sync metadata."New value: +"Optional local request ID. Omit for aggregate counts; set to load that request's sync_status, last_synced_at, and conflict_version." - added
Input schema / properties / request_id / minimumAdded value: +1 - changed
Output schema / additionalPropertiesPrevious value: -trueNew value: +false - changed
Output schema / descriptionPrevious value: -"Synchronization metadata."New value: +"Synchronization metadata. Aggregate counts are returned when request_id is omitted; per-request metadata is returned when request_id is provided." - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "description": "Aggregate offline synchronization counts.", + "properties": { + "clean": { + "description": "Number of requests with clean sync metadata.", + "minimum": 0, + "type": "integer" + }, + "conflict": { + "description": "Number of requests currently in conflict.", + "minimum": 0, + "type": "integer" + }, + "dirty": { + "description": "Number of requests with unsynced local changes.", + "minimum": 0, + "type": "integer" + }, + "pending": { + "description": "Number of requests queued or pending sync.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Total number of requests represented in aggregate sync status.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "total", + "clean", + "dirty", + "pending", + "conflict" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Per-request offline synchronization metadata.", + "properties": { + "conflict_version": { + "description": "Conflict version counter when a sync conflict has been detected.", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "last_synced_at": { + "description": "Last successful sync timestamp for this request.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "local_updated_at": { + "description": "Last local update timestamp known for this request.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "remote_updated_at": { + "description": "Last remote update timestamp known for this request.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "request_id": { + "description": "Request ID for the per-request sync lookup.", + "minimum": 1, + "type": "integer" + }, + "sync_status": { + "description": "Per-request sync status, or null when that request has no sync metadata.", + "enum": [ + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "request_id", + "sync_status" + ], + "type": "object" + } +] - removed
Output schema / propertiesRemoved value: -{ - "request_id": { - "type": "integer" - }, - "sync_status": { - "type": [ - "string", - "null" - ] - } -} - removed
Output schema / requiredRemoved value: -[ - "request_id", - "sync_status" -]
- Changed
update_request16 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"The request body."New value: +"Replacement request body or draft text (required; full replace)." - added
Input schema / properties / body / minLengthAdded value: +1 - changed
Input schema / properties / id / descriptionPrevious value: -"The request ID."New value: +"Existing local request ID to update (must already exist)." - added
Input schema / properties / id / minimumAdded value: +1 - changed
Input schema / properties / status / descriptionPrevious value: -"Status of the request."New value: +"Optional replacement local lifecycle status; changing status does not submit or withdraw a remote request." - added
Input schema / properties / status / enumAdded value: +[ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict" +] - changed
Input schema / properties / tags / descriptionPrevious value: -"Optional list of tags."New value: +"Optional full replacement tag list (not appended to existing tags)." - changed
Input schema / properties / title / descriptionPrevious value: -"The request title."New value: +"Replacement request title (required; full replace, not merge)." - added
Input schema / properties / title / minLengthAdded value: +1 - changed
Input schema / properties / url / descriptionPrevious value: -"The URL on Alaveteli or FYI."New value: +"Optional replacement absolute FYI/Alaveteli URL." - added
Input schema / properties / url / formatAdded value: +"uri" - changed
Input schema / properties / user_name / descriptionPrevious value: -"Name of the user."New value: +"Optional replacement requester display name; when omitted, existing local value is preserved." - added
Output schema / properties / request / additionalPropertiesAdded value: +false - added
Output schema / properties / request / descriptionAdded value: +"The updated local request record." - added
Output schema / properties / request / propertiesAdded value: +{ + "body": { + "description": "Request body or draft correspondence text.", + "minLength": 1, + "type": "string" + }, + "created_at": { + "description": "ISO-8601 creation timestamp when recorded.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Stable local request identifier.", + "minimum": 1, + "type": "integer" + }, + "status": { + "description": "Current Alaveteli/FYI request lifecycle status.", + "enum": [ + "draft", + "submitted", + "waiting_response", + "successful", + "partially_successful", + "refused", + "overdue", + "clean", + "dirty", + "pending", + "conflict", + null + ], + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "Optional local tags attached to the request.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "description": "Public title of the official information request.", + "minLength": 1, + "type": "string" + }, + "updated_at": { + "description": "ISO-8601 update timestamp used for ordering and sync.", + "format": "date-time", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Canonical public request URL when available.", + "format": "uri", + "type": [ + "string", + "null" + ] + }, + "user_name": { + "description": "Requester display name when known.", + "type": [ + "string", + "null" + ] + } +} - added
Output schema / properties / request / requiredAdded value: +[ + "id", + "title", + "body" +]
12 tool updates
v0.1.0- First observed
check_status - First observed
create_request - First observed
delete_request - First observed
import_authorities - First observed
list_authorities - First observed
list_requests - First observed
retrieve_request - First observed
sync_conflicts - First observed
sync_monitor - First observed
sync_resolve_conflict - First observed
sync_status - First observed
update_request
TDQS
Each tool targets a distinct action and resource. Even similar-sounding tools like list_requests and retrieve_request are clearly differentiated by purpose (listing vs. full detail). Sync-related tools (sync_monitor, sync_status, sync_conflicts, sync_resolve_conflict) have distinct roles.
Most tools follow a clear verb_noun pattern with lowercase and underscores (e.g., create_request, list_authorities). The only outlier is 'endorsed_route_status', which uses a past participle instead of a verb, but it remains readable and consistent in style.
With 15 tools, the server covers request CRUD, authority management, sync operations, and utilities without being overloaded. Each tool serves a clear purpose within the domain.
The surface covers core request lifecycle (create, read, update, delete, list) and sync management. Minor gaps exist: no tool for adding or editing correspondence individually, and no submission capability, but these are plausible scope decisions.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
SAM.gov contract opportunities and entity lookup (BYOK) plus USASpending federal award data.
OFAC, FDA, federal award and Federal Register lookups with signed machine evidence.
Manage incidents and on-call: list/create/update incidents, who is on call, on-call overrides.
Create signing requests, check status, send reminders, and manage Aoexl templates.
Related MCP Servers
- AlicenseAqualityAmaintenanceModel Context Protocol (MCP) server for Belgian Electronic Invoicing (Peppol BIS 3.0 / PINT-BE / Mercurius). Provides tools to validate, generate, and transform UBL 2.1 e-invoices, and look up BCE/KBO enterprise data and Peppol participants.50Apache 2.0
- AlicenseNot gradedqualityCmaintenancereference and citation validation, verification, enrichment, replacement and improvement1MIT
- AlicenseNot gradedqualityFmaintenanceAn MCP server that provides safe, read-only access to Boston's open data portal, enabling natural language exploration of civic datasets.2GPL 3.0

deeptempo-mcp-serversofficial
FlicenseNot gradedqualityDmaintenanceProvides tools for DeepTempo AI SOC including findings and case management, investigation workflow orchestration, action approval workflows, and MITRE ATT&CK layer generation.2-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/edithatogo/fyi-cli'
If you have feedback or need assistance with the MCP directory API, please join our Discord server