# ai.masnavi/masnavi (remote · masnavi.ai)

Rumi's complete Masnavi (25,635 beyts) — search, quote, verify and explain. Free, no auth.

- Trust score: 64/100 (medium)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `masnavi.ai`: 64/100 (this document), [markdown](https://verifymcp.io/servers/ai-masnavi-masnavi/masnavi.md), [page](https://verifymcp.io/servers/ai-masnavi-masnavi/masnavi)

## Channel facts

- Endpoint: `https://masnavi.ai/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.0`

## Trust breakdown

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

Scored 2026-08-03.

- **Endpoint Security**: 57/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 13 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 68/100
  - 60% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 1930 tokens (~128/item across 15 items; 13 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 84/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 44% of tool parameters carry a description.
  - Structured output schemas are declared (92% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http ai-masnavi-masnavi https://masnavi.ai/mcp
```

### Codex

```toml
[mcp_servers.ai-masnavi-masnavi]
url = "https://masnavi.ai/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ai-masnavi-masnavi": {
      "type": "remote",
      "url": "https://masnavi.ai/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ai-masnavi-masnavi --url https://masnavi.ai/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  ai-masnavi-masnavi:
    url: "https://masnavi.ai/mcp"
```

### Other

```json
{
  "mcpServers": {
    "ai-masnavi-masnavi": {
      "type": "http",
      "url": "https://masnavi.ai/mcp"
    }
  }
}
```

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

## Changelog

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

### 2026-08-03 (score 64, +1)

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

### 2026-08-01 (score 63, +1)

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

### 2026-07-31 (score 62, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 61, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 61, +1)

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

### 2026-07-28 (score 60, +1)

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

### 2026-07-27 (score 59, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 59)

First indexed and scored.

## MCP tools (13)

### `search` (~83 tokens)

Full-text search across the Masnavi. Returns beyts that contain the query terms, ranked by relevance. Useful for finding where a theme, word, or phrase appears.

Input parameters:

- `daftar`: Restrict to a single daftar (1-6)
- `limit` (integer)
- `offset` (integer)
- `query` (string, required): Persian text to search for

Output parameters:

- `match` (string)
- `query` (string)
- `results` (array)
- `total` (integer)

### `search_meaning` (~145 tokens)

Semantic search: find the beyts closest in MEANING to the query, in ANY language — English, Persian, Spanish, Turkish, Arabic, … . Use this when you have a theme, feeling, or idea rather than exact Persian words (e.g. 'feeling separated from your origin' → M1:1). Each hit carries a cosine-similarity score. status='unavailable' means the vector index is not built yet — fall back to `search`.

Input parameters:

- `daftar`: Restrict to a single daftar (1-6)
- `limit` (integer)
- `query` (string, required): What the verse should MEAN, in any language

Output parameters:

- `note` (string)
- `query` (string)
- `results` (array)
- `status` (string): 'ok' | 'unavailable' (index not built / no key) | 'error'
- `total_indexed` (integer)

### `lookup` (~104 tokens)

Fetch a specific beyt by its citation (e.g. 'M3:1278'), by daftar+beyt number, or by global beyt index. Optionally include surrounding beyts for context.

Input parameters:

- `after` (integer)
- `before` (integer)
- `beyt_global`
- `beyt_in_daftar`
- `citation`: Citation like 'M3:1278' or 'g:7421'
- `daftar`

Output parameters:

- `context_after` (array)
- `context_before` (array)
- `primary`

### `verify` (~84 tokens)

Given a candidate quote attributed to Rumi's Masnavi, check whether it actually appears. Returns status='exact' (with citation), 'fuzzy' (with similar candidates), or 'not_found'. USE THIS BEFORE QUOTING RUMI to avoid hallucination.

Input parameters:

- `fuzzy_threshold` (number)
- `text` (string, required): Candidate Rumi quote in Persian

Output parameters:

- `matches` (array)
- `notes` (string)
- `query_normalized` (string)
- `status` (string): 'exact', 'fuzzy', or 'not_found'

### `get_section` (~37 tokens)

Retrieve a full section (story / بخش) with all its beyts.

Input parameters:

- `section_id`
- `slug`: Stable URL slug

Output parameters:

- `beyt_count` (integer)
- `beyts` (array)
- `daftar` (integer)
- `first_beyt_global`
- `id` (integer)
- `last_beyt_global`
- `slug` (string)
- `title_fa` (string)

### `table_of_contents` (~35 tokens)

Browse the Masnavi's section list. Returns titled sections per daftar with beyt counts and ranges.

Input parameters:

- `daftar`

Output parameters:

- `daftar`
- `nodes` (array)

### `random_beyt` (~28 tokens)

Return a randomly-selected beyt, optionally restricted to a daftar.

Input parameters:

- `daftar`

Output parameters:

- `beyt_global` (integer)
- `beyt_in_daftar` (integer)
- `citation` (string): Canonical citation, e.g. 'M3:1278'
- `daftar` (integer)
- `mesra1` (string): First hemistich (with diacritics)
- `mesra2` (string): Second hemistich
- `section_id` (integer)
- `section_slug` (string)
- `section_title` (string)

### `get_range` (~142 tokens)

Fetch ALL beyts between two endpoints, inclusive, grouped by section. Use this — NOT many calls to get_section or lookup — when a user asks for a full story, a long passage, or a sequence of beyts spanning multiple sections. Endpoints are canonical citations like 'M2:2608' and 'M2:2775', or global indices via start_global / end_global. Max range: 500 beyts.

Input parameters:

- `end`: End citation, e.g. 'M2:2775'
- `end_global`
- `start`: Start citation, e.g. 'M2:2608'
- `start_global`

Output parameters:

- `end_citation` (string)
- `sections` (array)
- `start_citation` (string)
- `total_beyts` (integer)
- `total_sections` (integer)

### `find_sections` (~216 tokens)

Find sections (stories) by TITLE. Exact words first (phrase, then AND-of-tokens); when NO title contains the words, falls back to MEANING matches in any language (hits carry match='meaning' + a cosine score — verify with get_section before relying on one). Each match includes `first_citation` and `last_citation` — ready-to-use canonical citations (e.g. 'M2:2608'). To read a whole multi-section story, call get_range with the FIRST match's `first_citation` as start and the LAST match's `last_citation` as end. Do NOT construct a citation from `first_beyt_global` — that is a GLOBAL index (1..25635), not a daftar-local beyt number. Example: find_sections('ابلیس معاویه', daftar=2).

Input parameters:

- `daftar`
- `limit` (integer)
- `query` (string, required): story title words (Persian) or a description of the story in any language

Output parameters:

- `note`
- `query` (string)
- `sections` (array)
- `total` (integer)

### `explain` (~143 tokens)

Get commentary (Persian + English) for a specific beyt of the Masnavi, attributed to a primary source (e.g. Abdolkarim Soroush's lectures). Returns the beyt text along with structured commentary entries. Each entry has source, author, language, body markdown, and confidence ('ai-draft' / 'reviewed' / 'verbatim'). Use this when a user asks 'what does this beyt mean' or 'what does <scholar> say about M1:1'.

Input parameters:

- `citation` (string, required): Citation like 'M1:1' or 'M3:1278' or 'g:7421'.

### `search_divan` (~128 tokens)

Full-text search across the 34,603 beyts of the ghazals of the Divan-e Shams (Divan-e Kabir) — Rumi's lyric work, distinct from the Masnavi. Returns beyts with divan citations (G{ghazal}:{beyt}, e.g. G1393:1). Use when you know the exact Persian words; use search_divan_meaning for a theme in any language.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `query` (string, required): Persian text to search for

Output parameters:

- `match` (string)
- `query` (string)
- `results` (array)
- `total` (integer)

### `search_divan_meaning` (~152 tokens)

Semantic search over the Divan-e Shams ghazals: given a theme, feeling, or idea in ANY language, returns the GHAZALS closest in meaning — each with its best-matching couplet as a preview and a cosine score. Both couplet-level and whole-ghazal vectors are searched, so a ghazal whose overall theme matches is found even when no single couplet does. Fetch a full ghazal with get_ghazal. status='unavailable' means the index is not built — fall back to search_divan.

Input parameters:

- `limit` (integer)
- `query` (string, required): What the ghazal should be ABOUT, in any language

Output parameters:

- `note` (string)
- `query` (string)
- `results` (array)
- `status` (string)
- `total_indexed_beyts` (integer)
- `total_indexed_ghazals` (integer)

### `get_ghazal` (~123 tokens)

Fetch ONE complete ghazal of the Divan-e Shams by its canonical number (1..3230) or citation ('G1393' / 'G1393:2'). Returns every beyt plus prev/next ghazal numbers. Famous example: get_ghazal(1393) = «مرده بدم زنده شدم…».

Input parameters:

- `citation`: Divan citation like 'G1393' or 'G1393:2'
- `number`: Ghazal number, e.g. 1393

Output parameters:

- `beyt_count` (integer)
- `beyts` (array)
- `citation` (string): 'G{n}' — cites the whole ghazal
- `excerpt` (string): First hemistich of the ghazal
- `ghazal` (integer): Canonical ghazal number, 1..3230
- `next_ghazal`
- `prev_ghazal`
- `slug` (string)
- `title_fa` (string)

## Diagnostics

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

## Score history

- 2026-08-03: 64
- 2026-08-02: 63
- 2026-08-01: 63
- 2026-07-31: 62
- 2026-07-30: 61
- 2026-07-29: 61
- 2026-07-28: 60
- 2026-07-27: 59
- 2026-07-26: 59

## Links

- Remote endpoint: https://masnavi.ai/mcp
- Repository: https://github.com/shahhoseini/masnavi-mcp
- Website: https://masnavi.ai/
- Changelog RSS feed: https://verifymcp.io/servers/ai-masnavi-masnavi/masnavi/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/ai-masnavi-masnavi/masnavi/changelog.json
- HTML version of this page: https://verifymcp.io/servers/ai-masnavi-masnavi/masnavi
