rti-mcp

rti-mcp

An MCP server that lets you query your own RTI applications on India's RTI Online portal, including status, overdue requests, and reply PDFs, without re-entering OTP and captcha for every lookup.

Category
访问服务器

README

rti-mcp

CI Python 3.10+ License: MIT

An MCP server for querying your own applications on India's RTI Online portal — status, filed text, replies and reply PDFs — without re-entering an OTP and two captchas for every lookup.

Ask your assistant "which of my RTIs are overdue?" instead of clicking through View History one application at a time.

> Which of my RTI requests are more than 30 days overdue?

  14 of your 146 pending requests are past the Act's 30-day deadline.
  The oldest is DGDOR/R/E/21/00133, filed 1,844 days ago…

> What happened to the NIMHANS one?

  NIMNS/R/E/26/00220 — REQUEST DISPOSED OF as on 30/07/2026. A reply PDF
  is available; want me to download it?

Contents

Why this works

Logging in to RTI Online and clicking View History lands you on a citizen_view_history.php URL whose emailchk, cellchk and urletoken parameters are server-side encrypted blobs. That URL authenticates itself — it keeps working from a plain HTTP client with no cookies carried over from the browser, and it stays valid for a long time.

This server takes that one URL and walks the rest of the portal from it. You pay the OTP + captcha cost once, whenever the URL eventually stops working.

It is read-only. It only ever reads your own account, and only what the portal already shows you when you are logged in. It cannot file, appeal, edit or pay. Anyone holding your URL can read the same data, so treat it like a password — see Security.

Install

Requires Python 3.10+.

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install rti-mcp

Install into a virtual environment rather than system Python: the next section asks for an absolute interpreter path, and a venv is what makes that path stable.

<details> <summary>From source, to hack on it</summary>

git clone https://github.com/gouthamganeshm/rti-mcp.git
cd rti-mcp
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

Or the unreleased main, without a working copy:

pip install "git+https://github.com/gouthamganeshm/rti-mcp.git"

</details>

Point your MCP config at an absolute interpreter path, never a bare python. A bare python resolves to whatever environment happens to be active when the client spawns the server, and the server vanishes from the list with a ModuleNotFoundError the moment that differs from the environment holding the dependencies. Get the right path with:

python -c "import sys; print(sys.executable)"

Get your session URL

  1. Open https://rtionline.gov.in and log in with your OTP and captcha.

  2. Click View History.

  3. Copy the entire URL from the address bar. It looks like:

    https://rtionline.gov.in/request/citizen_view_history.php?emailchk=…&cellchk=…&urletoken=…
    

Then hand it to the server, either by asking your assistant —

"Set my RTI session URL to https://rtionline.gov.in/request/citizen_view_history.php?emailchk=…"

— which calls rti_set_session_url and stores it in ~/.rti-mcp/config.json, or by exporting it before the client starts:

export RTI_HISTORY_URL="https://rtionline.gov.in/request/citizen_view_history.php?emailchk=…"

The stored config file wins over the environment variable, so rti_set_session_url can refresh an expired URL at runtime without touching your MCP client config or restarting anything.

Register with your MCP client

Each client keeps its own registry — registering with one does not populate another's list.

<details open> <summary><b>Claude Code</b></summary>

claude mcp add rti-online -s user -- /absolute/path/to/.venv/bin/python -m rti_mcp

On Windows the interpreter sits elsewhere in the venv, so pass that path instead:

claude mcp add rti-online -s user -- C:\path\to\.venv\Scripts\python.exe -m rti_mcp

Re-pointing an existing entry means removing it first — claude mcp add will not overwrite one that is already registered:

claude mcp remove rti-online -s user

Or a project .mcp.json (key: mcpServers):

{
  "mcpServers": {
    "rti-online": {
      "type": "stdio",
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "rti_mcp"]
    }
  }
}

Verify with claude mcp list, or /mcp inside a session. </details>

<details> <summary><b>Claude Desktop</b></summary>

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

{
  "mcpServers": {
    "rti-online": {
      "command": "C:\\path\\to\\.venv\\Scripts\\python.exe",
      "args": ["-m", "rti_mcp"]
    }
  }
}

Restart Claude Desktop afterwards. </details>

<details> <summary><b>VS Code</b></summary>

.vscode/mcp.json — note the key is servers, not mcpServers:

{
  "servers": {
    "rti-online": {
      "type": "stdio",
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "rti_mcp"]
    }
  }
}

The server will not appear in the Extensions sidebar; that is expected. </details>

<details> <summary><b>Anything else (stdio)</b></summary>

The server speaks stdio and is also installed as a console script:

rti-mcp

Equivalent to python -m rti_mcp. Point any MCP-capable client at either. </details>

Tools

Tool What it does
rti_session_status Is the stored URL still good, and whose account is it
rti_set_session_url Store a fresh URL after re-login; clears the cache
rti_dashboard Registered / disposed / pending totals, requests and appeals
rti_list List one bucket, with optional filter and paging
rti_search Find applications by number fragment, authority code or status
rti_overdue Pending requests past the Act's 30-day reply deadline
rti_status Current status, remarks and reply availability for one application
rti_details Full filed application: authority, information sought, CPIO
rti_download Save the reply PDF or the attached request document
rti_export_csv Export every request and appeal to CSV
rti_clear_cache Force the next query to re-read the portal

Things to ask for once it is wired up:

  • "What's the status of NIMNS/R/E/26/00220?"
  • "Which of my RTIs are more than 30 days overdue?"
  • "Anything change on my applications today?"
  • "Download the reply for the NIMHANS one."
  • "Export everything to a spreadsheet."

Configuration

Variable Default Meaning
RTI_HISTORY_URL Seed View History URL (fallback if no config file)
RTI_MCP_HOME ~/.rti-mcp Config + cache location
RTI_MCP_DOWNLOAD_DIR ~/.rti-mcp/documents Where PDFs and CSVs land
RTI_MCP_CACHE_TTL 900 Seconds a fetched list stays fresh

Every list-returning tool also takes refresh=true to bypass the cache for one call.

How the portal behaves

Worth knowing, because the constraints shaped the code:

  • No pagination. A bucket's list page carries every row — several hundred registered requests in one ~300 KB response. One fetch gets everything.
  • registered is the superset. Its count equals disposed + pending, so rti_search and rti_export_csv fetch one list per category, not three.
  • Detail links are single-use-ish. Every list fetch mints fresh regId/token params, valid only while that fetch is the most recent successful navigation. Fetching a different list invalidates the previous page's links.
  • A 403 poisons the session. Once one request 403s, the next one fails too, whatever it is. Re-walking seed → list clears it.

client.py encodes these rules: detail links are never cached to disk, several details can be read off one live list, and a 403 triggers an automatic re-walk from the seed URL. Requests are paced ~0.6 s apart to stay polite to a government server.

One known quirk, surfaced rather than hidden: the dashboard's counts sometimes run a row or two ahead of its own list pages (e.g. it says 146 pending while the pending page lists 144). That is the portal's inconsistency, not a parsing gap — the row parser matches the served table exactly, and any row it fails to recognise is reported by rti_session_status instead of being dropped.

Troubleshooting

The server does not appear in the client's tool list. Almost always the interpreter path. Run /absolute/path/to/python -m rti_mcp in a terminal: if it fails with ModuleNotFoundError: No module named 'rti_mcp', the package is installed into a different environment than the one your config names.

"The RTI Online session URL is no longer valid." It expired. Log in again, open View History, copy the URL, and pass it to rti_set_session_url. Nothing else needs changing.

Results look stale. Lists are cached for 15 minutes. Pass refresh=true, or call rti_clear_cache.

A tool reports unparsed_rows. The portal changed its registration-number format and some applications are missing from results. Please open an issue with the shape of the number that failed — not your real one.

Everything 403s. The session got poisoned mid-walk. The client recovers automatically; if it persists, rti_clear_cache then retry.

Security

~/.rti-mcp/config.json holds a URL that grants read access to your entire RTI account. Don't commit it, don't paste it into an issue, and don't put it in a screenshot. There is no logout — revoking it means waiting for the portal to expire it.

Full details, and how to report a vulnerability, in SECURITY.md.

Disclaimer

Not affiliated with, endorsed by, or connected to the Government of India, the Department of Personnel and Training, or the RTI Online portal.

This is an unofficial client that parses HTML the portal was not designed to serve to programs, so it can break whenever the portal changes. It reads only the account whose session URL you supply. Use it for your own applications; don't point it at the portal at large, and don't remove the request pacing.

The 30-day figure rti_overdue uses is the ordinary deadline under §7(1) of the RTI Act, 2005 — shorter and longer periods apply in some cases (48 hours where life or liberty is concerned, 35 or 40 days when routed through an APIO or a third party is involved). Check the Act before relying on a date.

Use this at your own risk.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md. The test suite runs entirely offline against synthetic fixtures, so you can work on the parsers without an RTI account.

License

MIT © Goutham Ganesh M H

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选