| init_jama_projectA | Initialize a Jama project: download, clean, vectorize and index its items. Runs as an async background task and returns a job_id immediately so the
caller (LLM) is never blocked. Poll progress with get_sync_progress roughly
every 2 minutes until status is DONE or ERROR, reporting each sample to the
user. To re-index a project that is already initialized, prefer
reinit_jama_project.
Args:
project_id: Jama project id (numeric string, e.g. "20571").
Returns:
{"job_id": "...", "project_id": ..., "status": "RUNNING"}
|
| reinit_jama_projectA | Re-initialize an already-initialized Jama project (full re-sync). Behaves like init_jama_project but is the explicit verb for re-fetching and
re-indexing a project that has already reached READY/ERROR — e.g. after a
config change, corrupted index, or to pull a fresh full copy. Runs as an
async background task and returns a job_id immediately. Poll progress with
get_sync_progress roughly every 2 minutes until status is DONE or ERROR,
reporting each sample to the user.
Args:
project_id: Jama project id (numeric string, e.g. "20571").
Returns:
{"job_id": "...", "project_id": ..., "status": "RUNNING"}
|
| bootstrap_modelsA | Pre-download the embedding model (and optionally the reranker) so syncs never wait on them. Downloads the local embedding model (bge-small-en-v1.5, ~130MB ONNX) into
the project-local cache, ASYNCHRONOUSLY, via onnxruntime/fastembed (no
torch/transformers dependency). Returns a job_id immediately. This is the
recommended first step after installing/configuring the server — call it
BEFORE init_jama_project so the first sync isn't slowed by a model
download. Models already cached are skipped. Poll progress with
get_bootstrap_progress roughly every 2 minutes, reporting each sample to
the user, until status is DONE or ERROR.
The cross-encoder reranker (ms-marco-MiniLM-L-6-v2, ~80MB ONNX) is only
downloaded when explicitly enabled via RERANKER_ENABLED=1. The default
search path is pure RRF ordering (benchmarking showed it outperforms
rerank), so a default install needs NO reranker weights and bootstrap
completes after the embedding model alone.
Returns:
{"job_id": "...", "status": "RUNNING"} or, if a bootstrap is already
running, {"job_id": "...", "status": "RUNNING", "note": "..."}.
|
| get_bootstrap_progressA | Poll the progress of a bootstrap_models job. After calling bootstrap_models, poll this roughly every 2 minutes, reporting
each sample (status, progress %, message) to the user, until status is DONE
or ERROR. Progress is phase-based, not live bytes: the embedding
(~130MB ONNX, via fastembed) lacks per-chunk byte callbacks, so `message`
reports phase transitions rather than byte counts. When the reranker is
enabled (RERANKER_ENABLED=1) a second phase downloads the ~80MB reranker;
otherwise bootstrap completes after the embedding model alone.
Returns:
{"job_id","project_id","kind","status","progress","total","done",
"message","started_at","finished_at"} (project_id is 0 for a
bootstrap job — it has no project). status is one of
PENDING | RUNNING | DONE | ERROR.
|
| get_sync_progressA | Poll the progress of an init, reinit or sync job. After calling init_jama_project or reinit_jama_project, poll this roughly
every 2 minutes until status is DONE or ERROR, reporting each sample to the
user. For a project-wide view of all operations and their last runs, use
get_sync_status instead.
Returns:
{"job_id","project_id","kind","status","progress","total","done",
"message","started_at","finished_at"}
status is one of PENDING | RUNNING | DONE | ERROR.
|
| get_sync_statusA | Monitor a project's sync operations: current run + last run of each kind. Use this to check on init_jama_project / reinit_jama_project / scheduled
sync for one project. It returns the in-flight job (if any), the most recent
init / reinit / sync job (terminal or running), the project's current state,
and lightweight process metrics. After starting an init or reinit, you may
poll this roughly every 2 minutes (reporting each sample to the user) until
active_job is null and the relevant recent.* entry is DONE/ERROR.
Args:
project_id: Jama project id (numeric string, e.g. "20571").
Returns:
{"project_id","project_status","last_sync_time","item_count",
"chunk_count","active_job": {...}|null,
"recent": {"init": {...}|null, "reinit": {...}|null,
"sync": {...}|null},
"process": {"rss_mb","threads","db_mb","chunks"}|null}
Returns {"error": ...} if the project_id is not numeric or the server
is not ready.
|
| search_jama_semanticsA | Semantic search over an initialized Jama project using high-precision RAG. This is the DEFAULT tool for any non-precise question. It fuses keyword
(FTS5/BM25), vector (sqlite-vec cosine) and RRF in one call — so "like",
"keyword" and "semantic" queries are all best answered here. Prefer it over
native metadata unless the user gives an exact document key / status / item id.
Pipeline: client Multi-Query expansion -> hybrid recall (sqlite-vec +
FTS5) -> RRF fusion (with item-level dedup) -> top_k results. Ranking is
pure RRF by default: the cross-encoder reranker is DISABLED
(``RERANKER_ENABLED=0``) because benchmarking on the Lyra corpus showed it
HURT precision (Recall@50 73.3% RRF-only vs Recall@5 33.3% with rerank).
The reranker code path remains available for re-enablement.
Args:
project_id: numeric string Jama project id (must be initialized first).
query: the ORIGINAL natural-language search query, verbatim. It is
always kept as the primary recall/rerank reference, so even
when `sub_queries` is supplied you MUST pass the original user
query here too.
sub_queries: RECOMMENDED. Rewrite `query` into 3-5 diverse search
sub-queries capturing different semantic angles
(synonyms, broader/narrower scope, related concepts) to
maximize recall for RRF fusion. Pass as a JSON array of
strings. The server normalizes them (forces `query` to the
front, de-duplicates, caps at 5). If omitted, the server
falls back to deterministic lexical variants.
Example for query "how does login timeout work":
["login session expiration",
"authentication timeout policy",
"user inactivity logout"]
item_type: optional Jama item-type id to filter (e.g. "89011" for Test
Cases, "89009" for Requirements). Pass None for all.
top_k: final results to return (default 50). The BEIR sweep showed
top_k=50 + candidate_k=100 is the optimal combination (highest
Recall@50 = 73.3%). Range 1-50; must be <= candidate_k.
candidate_k: candidate pool size after RRF fusion + item dedup
(default 100). A larger pool improves recall (vector+FTS
recall is capped by this): measured vecR@25=7%, @50=13%,
@100=21%, @200=34%. Note: candidate_k=200 DILUTES RRF
rankings and actually lowers Recall@50 to 64.4%, so 100
is the measured sweet spot. Range 1-500; must be >= top_k.
modified_after: optional ISO-8601 lower bound on item modified date
(inclusive). Naive timestamps are assumed UTC.
e.g. "2024-01-01" or "2024-06-01T00:00:00Z".
modified_before: optional ISO-8601 upper bound on item modified date
(inclusive). Naive timestamps are assumed UTC.
Returns:
{"project_id","query","sub_queries_used","results":
[{document_key,name,item_type_name,section,modified_date,text,
score,strategy}, ...]}
|
| query_jama_native_metadataA | Query Jama's native REST API directly for exact metadata filtering. Use ONLY for precise lookups (exact document key, exact status, exact
item_type) — it returns empty on any misspelling. For topical, fuzzy or
natural-language questions, prefer `search_jama_semantics` instead.
Bypasses the vector store to answer precise questions (exact document key,
specific status, specific item type). Handles pagination internally and
returns up to 20 core metadata records.
Args:
project_id: numeric string Jama project id.
document_key: exact Jama document key (e.g. "SA-TC-7").
item_type: Jama item-type id as a numeric string (e.g. "89011" for Test
Case). Pass None for all types. Kept as a string (not int)
to match `search_jama_semantics` and the other MCP tools,
which all take ids as numeric strings.
status: exact status string (e.g. "BLOCKED", "APPROVED").
keyword: full-text 'contains' filter delegated to Jama.
Returns:
{"project_id","count","results":[{document_key,name,item_type_name,
status,modified_date,description}, ...]}
|
| list_jama_projectsA | List all Jama projects visible to the OAuth client. Returns:
{"count","results":[{id,project_key,name,status,description}, ...]}
|
| get_jama_itemA | Fetch a single Jama item by id (full metadata + cleaned text). Args:
item_id: numeric string Jama item id.
Returns:
{"item":{item_id,document_key,item_type_name,name,status,
description,test_steps,modified_date,...}}
|
| get_jama_item_relationshipsA | List relationships (source/target) for an item. Args:
item_id: numeric string Jama item id.
limit: max relationships to return (default 50).
Returns:
{"item_id","count","results":[{id,relationship_type,source_item,
target_item,name,modified_date}, ...]}
|
| get_jama_item_childrenA | List decomposition children of an item. Args:
item_id: numeric string Jama item id.
limit: max children to return (default 50).
Returns:
{"item_id","count","results":[{item_id,document_key,item_type_name,
name,status,modified_date}, ...]}
|
| list_jama_project_relationshipsA | List relationships for a project (cursor-paginated Jama endpoint). Jama's ``/relationships`` endpoint requires a ``project`` filter and uses
``lastId`` cursor pagination. Optionally filter to relationships involving
a specific item (client-side on fromItem/toItem).
Args:
project_id: numeric string Jama project id.
item_id: optional numeric string item id to filter on.
limit: max relationships to return (default 50).
Returns:
{"project_id","count","results":[{id,relationship_type,source_item,
target_item,suspect,name,modified_date}, ...]}
|
| get_jama_item_commentsA | List comments threaded on an item. Args:
item_id: numeric string Jama item id.
limit: max comments to return (default 50).
Returns:
{"item_id","count","results":[{id,body,created_by,created_date,
modified_date}, ...]}
|
| get_jama_item_attachmentsA | List attachment metadata for an item (no binary download). Args:
item_id: numeric string Jama item id.
limit: max attachments to return (default 50).
Returns:
{"item_id","count","results":[{id,name,file_type,file_size,
mime_type,created_date,modified_date}, ...]}
|
| list_jama_releasesA | List releases / versions for a project. Args:
project_id: numeric string Jama project id.
limit: max releases to return (default 50).
Returns:
{"project_id","count","results":[{id,name,release_date,status,
description,modified_date}, ...]}
|
| list_jama_test_runsA | List test runs for a project and/or test cycle. At least one of ``project_id`` / ``test_cycle_id`` must be provided.
Args:
project_id: optional numeric string Jama project id.
test_cycle_id: optional numeric string Jama test cycle id.
limit: max test runs to return (default 50).
Returns:
{"count","results":[{id,name,status,test_cycle,item,assigned_to,
modified_date}, ...]}
|
| list_jama_item_typesA | List all Jama item types (id -> display name) for the tenant. Returns:
{"count","results":[{id,name}, ...]}
|
| find_jama_project_by_nameA | Find Jama projects by name (case-insensitive) and return their info. Useful when you only know a project's name (or a fragment of it) and need
its numeric id to feed into other tools (init_jama_project,
list_jama_releases, list_jama_test_runs, …). Matching is substring by
default; pass exact=True for full case-insensitive equality.
Args:
name: project name or fragment (e.g. "acre" matches "Acrelec").
exact: if True, require full case-insensitive name equality.
limit: max matches to return (default 20).
Returns:
{"count","results":[{id,project_key,name,status,description}, ...]}
|
| find_jama_item_type_by_nameA | Find Jama item types by display name (case-insensitive) and return info. Returns the type id (needed by search_jama_semantics / query_jama_native_metadata
item_type filters) plus category, display plural and description. Matching is
substring by default; pass exact=True for full case-insensitive equality.
Args:
name: type name or fragment (e.g. "test" matches "Test Case", "Test Plan").
exact: if True, require full case-insensitive name equality.
limit: max matches to return (default 20).
Returns:
{"count","results":[{id,display,display_plural,category,category_name,
description}, ...]}
|
| query_jama_endpointA | Power-user escape hatch: GET any Jama REST endpoint (read-only). ``path`` is appended to ``{JAMA_URL}{API_PREFIX}`` (e.g. ``"/projects"``).
Only GET is ever issued; the client is read-only by design.
Args:
path: REST path beginning with '/', e.g. "/items/12345".
params: optional 'k1=v1&k2=v2' query string.
all_pages: if True, walk all pages and return a flat list of ``data``;
if False (default), return only the first page.
Returns:
{"path","data": <first-page data or flat list>}
|
| validate_setupA | Validate all dependencies, configuration and storage. Runs the offline pre-flight (packages + env vars + SQLite). When
``live=True`` it also probes the Jama OAuth token and the embedding
endpoint with a real request, so credentials can be verified without
running a full project init.
Args:
live: if True, perform live connectivity probes against Jama and the
embedding endpoint (slower; uses one Jama + one embedding call).
Returns:
{"blocking","issues":[...],"dependencies","config_issues","storage",
"live": {"jama","embedding"} | null, "hint"}
|
| configure_jamaA | Apply configuration values at runtime and persist them to .env. Accepts a mapping of env-var names to values (e.g.
``{"JAMA_URL":"...","JAMA_CLIENT_SECRET":"..."}`). Writes a complete
``.env`` (merging with existing values), reloads settings in-process, and
resets the Jama/RAG/DB singletons so subsequent calls use the new config.
Secrets are written to ``.env`` on disk only; they are never echoed back.
Args:
values: dict of {ENV_VAR: value}. Recognized keys: JAMA_URL,
JAMA_CLIENT_ID, JAMA_CLIENT_SECRET, EMBEDDING_BASE_URL,
EMBEDDING_API_KEY, JAMA_MCP_DB_PATH,
and any other key in the .env template.
Returns:
{"ok": true, "written": <abs .env path>, "applied_keys": [...]}
or {"error": ...}
|