Jama MCP Server

Jama MCP Server

Enables LLM clients to semantically search and query metadata within Jama requirements management via RAG and native API filters.

Category
访问服务器

README

Jama MCP Server

A production-grade Model Context Protocol (MCP) server for the Jama requirements management system, combining high-precision RAG retrieval with native REST API filtering. An LLM client (Claude Desktop, etc.) can autonomously choose between semantic search and structured metadata queries.

Architecture

            ┌──────────────────────── MCP (stdio) ────────────────────────┐
            │                                                              │
  LLM ──────┤  init_jama_project      get_sync_progress                   │
  Client    │  search_jama_semantics  query_jama_native_metadata           │
            │                                                              │
            │   server.py  (FastMCP + APScheduler + thread pool)          │
            │      │                                                       │
            │      ├── rag_pipeline.py  (Multi-Query + Hybrid + RRF +     │
            │      │                       Qwen3-Reranker)                 │
            │      ├── jama_client.py   (OAuth2 + pagination + HTML clean)│
            │      └── db_setup.py      (SQLite + FTS5 + sqlite-vec)      │
            │                                                              │
            └──────────────────────────────────────────────────────────────┘
                         │                        │
                  Jama REST API            Azure OpenAI embeddings
                  (read-only GET)          (text-embedding-3-small)

Retrieval pipeline (search_jama_semantics)

  1. Multi-Query — the query is expanded into 3-5 sub-queries. The MCP LLM client performs the expansion and passes the variants via the sub_queries parameter; when none are supplied, the server falls back to deterministic lexical variants (stopword-stripped + truncated) so RRF fusion still benefits from multiple recall angles. No server-side chat LLM is configured or called.
  2. Hybrid recall — for each sub-query: vector recall (sqlite-vec, cosine)
    • keyword recall (FTS5, BM25), each capped at candidate_k.
  3. RRF fusion — Reciprocal Rank Fusion merges all ranked lists into one candidate pool of ≤ candidate_k unique chunks.
  4. Rerank — local Qwen3-Reranker-0.6B (CPU, via transformers) scores (query, chunk) pairs via the P("yes") token probability; top top_k returned. If the model is unavailable, the pipeline gracefully falls back to RRF scores. Model weights are fetched from the HuggingFace China mirror (HF_ENDPOINT=https://hf-mirror.com) on first use, then served from cache.

Reliability & crash recovery

The server is designed to survive crashes without losing data and to come back up consistent on restart:

  • Atomic per-item indexing — each item's chunks (text + FTS5 + sqlite-vec) are replaced in a single write_txn (BEGIN IMMEDIATE), so a crash mid-sync never leaves a half-written item. done/progress only advance after the commit, so the DB is consistent up to the last flushed batch.
  • Idempotent re-sync — upserts overwrite (never duplicate), so re-processing already-indexed items on resume is harmless.
  • Startup recovery_resume_interrupted_syncs re-queues any project left INITIALIZING by a prior crash, so the server self-heals without manual action.
  • Concurrency guardinit_jama_project refuses a duplicate concurrent sync for a project that already has a job in flight, returning the existing job_id instead of spawning a racing second worker.
  • Bounded HTTP retries — 429 rate-limit handling is a bounded loop (not recursion), so a persistent rate-limit fails cleanly instead of overflowing the stack; Retry-After parsing tolerates non-numeric values; a 401 mid-sync refreshes the token and retries the page; malformed JSON bodies are retried.
  • WAL mode + write lock — SQLite runs in WAL with a process-wide write lock, so the scheduler's writer and MCP reader threads coexist without SQLITE_BUSY failures.

Chunking (LlamaIndex)

Jama rich-text (Description / Test Case Steps) is cleaned to plain text with BeautifulSoup before being wrapped in LlamaIndex Document objects. The documents are split into TextNode chunks by LlamaIndex's SentenceSplitter (recursive, sentence-aware; chunk_size=512, chunk_overlap=80 to preserve context for the ~30% long-form items). The item name is prepended to each chunk so the title is always retrievable.

Native API (query_jama_native_metadata)

Bypasses the vector store for exact-match questions (specific document key, status, item type). Uses /abstractitems which honours itemType, contains and documentKey server-side; status is refined client-side. Handles pagination internally, returns up to 20 core metadata records.

Incremental sync

On startup, APScheduler registers a job (every 2h by default) that reads the projects table for initialized project_id + last_sync_time, then walks Jama items whose modifiedDate > last_sync_time, re-cleans/re-chunks them and updates the FTS5 + sqlite-vec indexes. New items are added; modified items have their old chunks replaced atomically.

Setup

# 1. Install (uses Aliyun mirror; GitHub-only deps fall back to PyPI)
pip install -r requirements.txt

# 2. Configure (interactive wizard writes .env, then validates deps + config,
#    and optionally probes Jama/embedding connectivity with --self-test)
python setup_wizard.py --self-test

# 3. Run (stdio transport for an MCP client)
python server.py

First-run configuration guard

Every MCP tool runs an offline pre-flight check before doing any work: Python dependencies, required env vars (JAMA_URL / JAMA_CLIENT_ID / JAMA_CLIENT_SECRET / EMBEDDING_BASE_URL / EMBEDDING_API_KEY) and the SQLite store. If anything is missing the tool returns a clear error dict with a hint instead of failing midway through a Jama API call. Configure via the wizard, or call the configure_jama / validate_setup tools at runtime.

MCP client config (Claude Desktop example)

{
  "mcpServers": {
    "jama-mcp": {
      "command": "python",
      "args": ["/absolute/path/to/jama-mcp-server/server.py"],
      "env": { "JAMA_MCP_DB_PATH": "/absolute/path/to/jama-mcp-server/jama_mcp.db" }
    }
  }
}

Usage flow (for the LLM)

  1. init_jama_project("20571") → returns job_id immediately (non-blocking).
  2. get_sync_progress(job_id) → poll until status == "DONE".
  3. search_jama_semantics("20571", "how does volume sync work", top_k=5) → RAG.
  4. query_jama_native_metadata("20314", document_key="SA-TC-7") → exact match.

Resilience

  • Jama API: OAuth token auto-refresh on expiry + 401 retry; urllib3 Retry with exponential backoff on 429/5xx; explicit Retry-After handling; SSL connection-reset tolerated (transient on this network).
  • Embeddings: same retry/backoff session on the embedding endpoint.
  • SQLite concurrency: WAL mode + busy timeout + a process-level write lock so the APScheduler writer and MCP reader threads coexist without SQLITE_BUSY errors; chunk replacement is atomic per item.
  • Reranker: lazy-loaded singleton; failure degrades to RRF-only scoring instead of crashing the search.
  • Read-only: JamaClient only issues GET requests — it cannot create, modify or delete data on the Jama instance.

Files

File Purpose
requirements.txt deps + Aliyun mirror config
config.py env-driven settings (dataclasses) + validation/persistence/reload
db_setup.py SQLite schema, FTS5 + sqlite-vec loading, CRUD
jama_client.py OAuth, paginated fetch, HTML cleaning, native query, browse API
rag_pipeline.py chunking, embeddings, Multi-Query, hybrid recall, RRF, rerank
server.py MCP tools, async jobs, APScheduler incremental sync, pre-flight guards
preflight.py offline dependency + config + storage validation
setup_wizard.py interactive configuration wizard (python setup_wizard.py)
selftest.py end-to-end self-test suite (python selftest.py)
.env.example template for environment configuration

Tools

Configuration & validation

  • validate_setup(live=False) — offline pre-flight (+ optional live Jama/embedding probe).
  • configure_jama(values) — apply config at runtime, persist to .env, reload.

Jama browse (read-only, gated by pre-flight)

  • list_jama_projects() — all visible projects.
  • find_jama_project_by_name(name, exact?) — find projects by name → get id + info.
  • get_jama_item(item_id) — full single item (cleaned text).
  • get_jama_item_children(item_id) — decomposition children.
  • get_jama_item_relationships(item_id) / list_jama_project_relationships(project_id, item_id?) — relationships (cursor-paginated /relationships).
  • get_jama_item_comments(item_id) — item comments (cleaned body).
  • get_jama_item_attachments(item_id) — attachment metadata (no binary).
  • list_jama_releases(project_id) — project releases/versions.
  • list_jama_test_runs(project_id?, test_cycle_id?) — test runs.
  • list_jama_item_types() — tenant item types (id → name).
  • query_jama_endpoint(path, params?, all_pages?) — generic read-only GET escape hatch.

RAG / retrieval

  • init_jama_project(project_id) — async background init (returns job_id).
  • get_sync_progress(job_id) — poll init/sync progress.
  • search_jama_semantics(project_id, query, ...) — Multi-Query + hybrid + RRF + Qwen3 rerank.
  • query_jama_native_metadata(project_id, ...) — exact-match metadata via /abstractitems.

Verified

All components self-tested against the live Jama instance and embedding API: OAuth + paginated fetch, HTML→text cleaning, Test Case step rendering, item-type mapping, DB schema (FTS5 + vec0), full RAG search, async init with progress polling, incremental sync (0 new items), native metadata filters (item_type / status / keyword / document_key), APScheduler startup, MCP stdio handshake, and error paths (bad project id, unknown job, nonexistent project).

The Qwen3-Reranker-0.6B was downloaded from the HuggingFace China mirror (hf-mirror.com) and loaded on CPU; verified it produces non-zero relevance scores with correct ordering (related=0.55 > unrelated=0.0002) and that the end-to-end RAG search returns strategy=rerank results. LlamaIndex is the primary RAG framework: SentenceSplitter + Document/TextNode for chunking. Multi-Query expansion is performed by the MCP LLM client and passed to the pipeline via search(sub_queries=...); when omitted, deterministic lexical variants are used.

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选