Skip to main content
Glama
Chanoir999

StudyPilot MCP Server

by Chanoir999

StudyPilot

StudyPilot is a course-material learning agent project. It uses an MCP server to expose course documents as resources and provide search/read tools.

Project references: architecture, evaluation protocol, demo script, and release checklist.

Current capabilities

  • Import local Markdown, text, and text-based PDF documents.

  • Preserve one-based PDF page numbers in search results and citation details.

  • Store material chunks and their Qwen3-Embedding-0.6B vectors in a persistent FAISS IndexFlatIP index (exact cosine similarity after L2 normalization).

  • Retrieve with hybrid search: dense vector candidates plus an in-process lexical rank, fused with reciprocal-rank fusion (RRF).

  • Keep study tasks and quiz results in PostgreSQL; material retrieval no longer depends on PostgreSQL full-text search.

  • Read a complete document by its stable document ID.

  • Expose the same operations as MCP tools and resources.

  • Create, list, and update persistent study tasks through MCP tools.

  • Provide a source-grounded quiz prompt through MCP.

  • Let DeepSeek discover and call MCP tools in a bounded Agent loop.

  • Route requests between a Tutor Agent and Planner Agent with isolated MCP tool permissions.

  • Select DeepSeek or a release-gated local Ollama model for Tutor requests while Planner remains on DeepSeek.

  • Persist the assistant display name per browser conversation in PostgreSQL.

Related MCP server: University Content MCP

Multi-Agent routing

StudyPilot uses deterministic routing instead of spending another model call on a Supervisor Agent. Ordinary course questions go directly to the Tutor Agent. Task-only commands go directly to the Planner Agent. Composite requests such as "analyze my weak points from the materials and schedule revision" run Tutor first, then pass its cited diagnosis to Planner as a structured handoff.

  • Tutor tools: search_materials, get_document

  • Planner tools: create_study_task, list_study_tasks, update_study_task_status

  • Single-purpose requests invoke one Agent; only composite requests invoke both.

Each Agent run is bounded by both model steps and total tool calls. Composite requests pass a JSON Tutor handoff containing the original request, grounded diagnosis, and extracted citation IDs to the Planner.

Within one Agent run, an identical mutating tool call is executed at most once. This protects task creation and status updates from repeated model tool calls; read-only tools may still be called again when needed. Web Agent task creation also receives a persistent idempotency key derived from the conversation, turn, and normalized business arguments. Concurrent or retried creation with that key returns the original task. Direct MCP/CLI creation without a key keeps normal create-each-time behavior.

The Web client stores a random conversation_id in localStorage. Explicit renames such as "以后你叫不亮" are stored in PostgreSQL and injected into both Agent prompts on later turns. Clearing the chat creates a new conversation and resets the display name.

Persistent conversation context

Every user and assistant message is stored in PostgreSQL with its conversation_id, turn_id, role, timestamp, and executing Agent. The browser restores the complete saved history through GET /api/conversations/{conversation_id} after a refresh. Full history remains in the database; only the latest 20 messages within a 12,000-character budget are sent to the model on each turn.

If a completed conversation_id and turn_id is submitted again with the same user message, both chat endpoints replay the persisted assistant response without running the Agent again. Reusing a turn ID for different content returns HTTP 409. This covers completed-request retries; it is not a lock for two concurrent requests that arrive before the first response is persisted. Persistent task idempotency still prevents identical task creation within that concurrent turn.

StudyPilot records user preferences only from explicit statements, including preferred name, language, response detail, and step-by-step teaching style. Its learning profile separates explicit goals and weak points from observed activity such as retrieval queries, source documents, and study tasks. Observed activity is derived from real MCP traces, not model guesses. Clearing the chat starts a new conversation but does not delete the old history from PostgreSQL.

Setup

python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"

Run the MCP server

Start PostgreSQL for study-task persistence, migrate the schema, and index sample materials into FAISS. The first indexing run downloads Qwen/Qwen3-Embedding-0.6B from Hugging Face.

docker compose up -d postgres
.venv\Scripts\alembic.exe upgrade head
.venv\Scripts\studypilot-index.exe

FAISS persists the index and chunk metadata under data/faiss/. Existing Chroma cache files are not read after this migration, so run studypilot-index once after upgrading to rebuild the index from data/materials/. Set FAISS_DIR only when the index must live elsewhere, such as an isolated test or deployment data volume; the default remains data/faiss/.

Document IDs are derived from normalized file stems and must be unique. Files such as Course Notes.md and course-notes.txt conflict; indexing rejects the set and reports both names instead of silently merging their chunks or producing ambiguous citations.

Blank-line paragraph boundaries remain stable for ordinary material. A single paragraph longer than 1,200 characters is split into bounded chunks, preferring sentence endings in the final 40 percent of each window. This rule does not add overlap because complete documents are reconstructed from stored chunks. Re-run studypilot-index after upgrading from an index built before this rule.

The default transport is stdio, which is convenient for a local Agent host:

studypilot-mcp

To inspect it interactively:

mcp dev app/studypilot/mcp_server.py

Test

.venv\Scripts\python.exe -m pytest

The default suite uses local fakes for model calls and an isolated repository temporary directory. PostgreSQL integration tests are skipped when the test database is unavailable; a green local run therefore does not by itself prove that PostgreSQL or a real model endpoint is reachable.

Fixed retrieval evaluation

The fixed set is data/eval/retrieval_cases.json. It uses source chunk IDs as relevance judgments and writes a reproducible JSON report with Recall@1, Recall@3, Recall@5, MRR, and per-case bad cases.

.venv\Scripts\studypilot-eval.exe --k 1 3 5

To score answers and citation faithfulness as well, provide real Agent output in this format (one record per fixed case):

[
  {
    "id": "round-robin",
    "answer": "时间片过小会造成频繁进程切换,增加系统开销。",
    "citations": ["operating-systems:2"],
    "refused": false,
    "latency_ms": 840.5,
    "total_tokens": 320,
    "error": null
  }
]
.venv\Scripts\studypilot-eval.exe --answers .\agent_answers.json

data/eval/latest_report.json records every retrieval list and identifies failures in bad_cases. Cases marked should_refuse evaluate refusal separately from retrieval. When answer records include runtime fields, the report also calculates P50/P95 latency, mean token count, and failure rate. It never fabricates metrics when real Agent data is not supplied.

T2Ranking fixed rerank set

The project uses the official THUIR/T2Ranking dev split as its external Chinese rerank benchmark. The checked-in fixed subset contains 200 query IDs selected from dev using a documented SHA-256 seed, retrieval qrels, graded rerank qrels, and hashes of all three official source files.

Build or verify the subset after downloading the official small metadata files into data/eval/t2ranking/source/:

.venv\Scripts\python.exe .\tools\build_t2ranking_subset.py

The fixed query/qrels set alone is not enough to report rerank quality. A valid Recall@3 comparison also needs a persisted Top-K candidate pool and the corresponding passages from the same collection.tsv revision. The baseline and reranker must reorder the same candidates. Until those artifacts and both run outputs exist, this project does not claim any Recall@3 improvement.

The official dev.bm25.tsv candidate list produces a persisted 100-candidate pool per fixed query. Its measured baseline is Recall@3 0.5250, MRR@10 0.4268, and nDCG@10 0.3050. A completed local BAAI/bge-reranker-v2-m3 run reranked the first 20 of the same 100 candidates for all 200 queries in one 4,000-pair batched call. The measured rerank result is Recall@3 0.6000, MRR@10 0.4812, and nDCG@10 0.3495, for deltas of +0.0750, +0.0544, and +0.0445 respectively. The checked-in report and manifest identify the exact artifacts. To reproduce it, run:

.venv\Scripts\python.exe .\tools\extract_t2ranking_passages.py
.venv\Scripts\python.exe .\tools\rerank_t2ranking.py --model .\data\models\bge-reranker-v2-m3 --top-n 20 --batch-size 16 --progress
.venv\Scripts\python.exe .\tools\evaluate_t2ranking.py --rerank .\data\eval\t2ranking\fixed-200\rerank.cross_encoder.tsv --report .\data\eval\t2ranking\fixed-200\rerank.report.json

The evaluator rejects a rerank file if it changes any query's candidate set. It therefore reports a genuine reranking comparison, not a candidate-generation comparison.

Ask the Agent

Configure DEEPSEEK_API_KEY and DEEPSEEK_MODEL in .env, then run:

.venv\Scripts\studypilot-chat.exe "时间片为什么不能设置得太小?"

Model reliability and observability

DeepSeekChatModel enforces a per-attempt timeout, retries transient timeout, connection, rate-limit, and server errors with exponential backoff, then tries the explicitly configured fallback models. It does not silently switch to an invented provider or model.

For streaming responses, retry and fallback are allowed only before the first chunk is emitted. Every wait for the next chunk uses the same per-attempt timeout. If a stream fails after partial content has reached the client, the request ends with an error instead of replaying duplicated text.

Configure the primary and fallback sequence in .env:

DEEPSEEK_MODEL=deepseek-v4-flash
DEEPSEEK_FALLBACK_MODELS=your-confirmed-fallback-model
DEEPSEEK_TIMEOUT_SECONDS=30
DEEPSEEK_MAX_RETRIES=2
DEEPSEEK_RETRY_BASE_SECONDS=0.5

The system prompt carries the code-defined version studypilot-2026-07-30.2. Every model attempt is appended to data/logs/model_calls.jsonl with its provider, model, model artifact hash (when configured), prompt version, retry/fallback position, latency, token usage, outcome, and error type. Web calls also include request_id, conversation_id, and turn_id so an HTTP response can be correlated with its model attempts. These identifiers are propagated through both JSON and NDJSON responses. Prompt text, user questions, API keys, and material content are not written to this log. To calculate cost, provide verified per-million-token rates for the exact model names; without them estimated_cost_usd remains null.

MODEL_PRICING_USD_PER_MILLION_JSON={"deepseek-v4-flash":{"input":0.0,"output":0.0}}

Run the web workspace

.venv\Scripts\studypilot-web.exe

Open http://127.0.0.1:8787 to chat, import materials, inspect sources, and manage study tasks.

For a containerized application process, keep Ollama on the host and run:

docker compose build app
docker compose run --rm app alembic upgrade head
docker compose run --rm app studypilot-index
docker compose up -d app

The app container reaches Ollama through host.docker.internal. PostgreSQL, FAISS data, Hugging Face cache, and application health have separate Compose volumes/checks. The native and containerized Web processes both use port 8787, so run only one of them at a time.

GET /api/health reports the application, PostgreSQL connection, and FAISS material-index state separately. An index can be ready, empty, inconsistent, or unavailable; empty remains usable because documents can still be imported, while inconsistent or unavailable indexes make the top-level health status false. The health payload also reports the current index-format version. Metadata from an older or malformed format is rejected with an explicit studypilot-index rebuild instruction.

Hybrid retrieval and streaming chat

search_materials keeps its existing MCP tool name and result shape. Internally it fetches vector candidates from FAISS, ranks all chunks for lexical term matches, then uses RRF to combine the two lists. This improves exact terminology matches without removing semantic retrieval.

The workspace now uses POST /api/chat/stream. It returns application/x-ndjson with status, delta, done, and error events. The UI renders each delta as it arrives and reports when the bounded Agent is calling an MCP tool. POST /api/chat remains available for existing non-streaming clients.

Optional Qwen3.5-4B tutor fine-tuning (deferred)

This release intentionally stops before adapter training, GGUF conversion, and four-model quality comparison. The checked-in corpus, isolated indexes, trajectory compiler, dataset validator, and CPU preflight are preparation artifacts only; no local-model quality improvement is claimed. DeepSeek remains the default Tutor and the local Ollama option stays release-gated.

The current app-scope release audit is:

.venv\Scripts\python.exe .\tools\audit_release.py --scope app

The local tutor fine-tuning path is pinned to the official Qwen/Qwen3.5-4B revision 851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a, which matches the qwen35 4.7B architecture used by the local Ollama qwen3.5:4b model. Ollama's quantized GGUF file is for inference; training uses the original Safetensors checkpoint.

Install the optional training dependencies:

.venv\Scripts\python.exe -m pip install -e ".[train,dev]"

Formal data uses complete system/user/assistant.tool_calls/tool/assistant trajectories and the frozen data/finetune/tutor_tools.v1.json schema. Only assistant spans contribute to loss. System prompts, user questions, and tool responses are masked. The checked-in eight-row file remains a response-only smoke sample and cannot pass the formal 300-train/60-evaluation gate.

.venv\Scripts\python.exe .\tools\fetch_public_corpus.py --inspect-rights
.venv\Scripts\python.exe .\tools\fetch_public_corpus.py --accepted-policy .\data\corpus\accepted-rights.v1.json
.venv\Scripts\python.exe .\tools\build_corpus_indexes.py
.venv\Scripts\python.exe .\tools\create_tutor_review_worklist.py --split train --output .\data\finetune\tutor_review.train.jsonl
.venv\Scripts\python.exe .\tools\create_tutor_review_worklist.py --split eval --output .\data\finetune\tutor_review.eval.jsonl
.venv\Scripts\python.exe .\tools\compile_tutor_trajectories.py --worklist .\data\finetune\tutor_review.train.jsonl --index-dir .\data\indexes\wikimedia_cs_v1\train --output .\data\finetune\tutor_sft.train.jsonl
.venv\Scripts\python.exe .\tools\compile_tutor_trajectories.py --worklist .\data\finetune\tutor_review.eval.jsonl --index-dir .\data\indexes\wikimedia_cs_v1\eval --output .\data\finetune\tutor_sft.eval.jsonl
.venv\Scripts\python.exe .\tools\validate_tutor_dataset.py --train .\data\finetune\tutor_sft.train.jsonl --eval .\data\finetune\tutor_sft.eval.jsonl --report .\data\finetune\tutor_dataset.validation.json
# Formal QLoRA training is deferred in this release.

The 8 GB profile uses a 768-token maximum, NF4 double quantization, rank-8 LoRA, batch size 1, gradient accumulation, BF16 compute, and gradient checkpointing. LoRA targets are discovered only under model.language_model.layers; the visual tower stays frozen. The current validation report records exactly 300/60 rows, semantic cross-split validation, and review_mode=ai_assisted_authorized. Formal training remains deferred; no adapter or loss result is part of this release.

After a future training run, merge on CPU, convert to GGUF Q4_K_M, and run the same holdout through base, adapter, DeepSeek, and deployed Ollama candidates only when the recorded release gates pass:

.venv\Scripts\python.exe .\tools\merge_tutor_lora.py
.venv\Scripts\python.exe .\tools\convert_tutor_to_gguf.py
.venv\Scripts\python.exe .\tools\run_tutor_evaluation.py --cases .\data\finetune\tutor_sft.eval.jsonl --output .\data\eval\tutor\runs.jsonl --candidate qwen3.5-4b-base=transformers --candidate studypilot-tutor-4b-adapter=peft:data/models/studypilot-tutor-4b-lora --candidate deepseek=deepseek --candidate studypilot-tutor-4b-q4_k_m=ollama:studypilot-tutor:4b
.venv\Scripts\python.exe .\tools\score_tutor_evaluation.py --cases .\data\finetune\tutor_sft.eval.jsonl --runs .\data\eval\tutor\runs.jsonl --output .\data\eval\tutor\report.json
.venv\Scripts\python.exe .\tools\create_ollama_tutor.py --gguf .\data\models\studypilot-tutor-4b-q4_k_m.gguf --evaluation-report .\data\eval\tutor\report.json --name studypilot-tutor:4b
.venv\Scripts\python.exe .\tools\audit_release.py --artifact .\data\models\studypilot-tutor-4b-q4_k_m.gguf

The Web API accepts tutor_provider=deepseek|ollama, and the page stores the selection per browser conversation. Planner always uses DeepSeek. The local choice is disabled until the verified artifact hash, matching deployment manifest, and OLLAMA_RELEASE_GATES_PASSED=1 are configured; ENABLE_EXPERIMENTAL_LOCAL_TUTOR=1 is an explicit non-release bypass. See fine-tuning and deployment for data contracts, scoring, failure evidence, and exact promotion rules.

Available Tools

5 tools
create_study_taskC

Create a study task. Use an ISO 8601 date-time when a deadline is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
due_atNo
descriptionNo
idempotency_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits. It does not mention the idempotency_key parameter's behavior, duplicate handling, return value, or side effects. The only non-essential detail is the date format requirement, which is not behavioral.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, direct, and front-loaded with the core action. It has no redundant words, but it is under-specified. It earns a 4 for efficiency, though not a 5 because it omits essential context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 4 parameters, 0% schema coverage, and no annotations, the description is insufficiently complete. It only covers due_at and ignores idempotency_key and other behavioral aspects. An output schema exists, which may cover return values, but the input semantics remain incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds value for due_at by specifying ISO 8601 format, but leaves title, description, and especially idempotency_key unexplained. The idempotency_key parameter is non-obvious and requires semantic clarification.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Create a study task' uses a specific verb and resource, clearly distinguishing it from sibling tools that search, get, list, or update. The purpose is unequivocal.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description simply states the action without any contextual cues, exclusions, or references to siblings like update_study_task_status. The ISO 8601 hint is parameter-specific, not usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_documentA

Read a complete course document using its document ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
document_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It conveys that this is a read operation (non-destructive), which is important context, but it does not disclose what happens if the document is not found, whether special permissions are required, or any other side effects. The description adds some behavioral context but leaves gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no wasted words. It immediately states the action and the key parameter, making it highly efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the availability of an output schema, the description does not need to explain return values. For a simple get-by-ID tool, the description is adequate but lacks guidance on how to obtain the document_id or what distinguishes 'complete' documents. It does not reference sibling tools, reducing its completeness in a broader context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the single parameter document_id. It adds minimal meaning by indicating the parameter is the document's identifier, but it does not explain where to obtain this ID, the expected format, or any constraints. This is insufficient for a parameter with zero schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Read') with a clear resource ('complete course document') and method ('using its document ID'). This clearly distinguishes it from sibling tools like search_materials (search) and create_study_task (create), making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you have a document ID and need the full content, but it does not explicitly state when not to use it or mention alternative tools like search_materials for locating documents. There is a clear context but no exclusions or explicit alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_study_tasksA

List study tasks, optionally filtered by their current status.

ParametersJSON Schema
NameRequiredDescriptionDefault
statusNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden but only reveals the optional status filter. It does not detail behavior such as default listing all tasks, sorting, or side effects, though the verb 'List' implies a read-only operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the core action and filter option without unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list operation with one optional parameter and an output schema, the description is sufficiently complete, though it could have mentioned default behavior like returning all tasks when status is not provided.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% coverage, so the description adds meaning by explaining that the 'status' parameter filters by the task's current status and is optional, which goes beyond the schema's bare parameter definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'List' with the resource 'study tasks' and states the optional filter by status, clearly distinguishing it from sibling tools like create_study_task and update_study_task_status, which are mutations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the verb 'List' and context, but does not explicitly state when to use this tool over alternatives or mention exclusions. However, sibling names make the distinction obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_materialsB

Search course materials with dense plus lexical reciprocal-rank fusion.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It only mentions the ranking algorithm and does not disclose whether the operation is read-only, what kind of materials are searched, or any side effects. Minimal behavioral context is given.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the core purpose. Every word adds value, and the algorithmic detail is relevant to distinguishing the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return value structure is covered elsewhere. However, the description lacks guidance on when to use search versus get_document and does not clarify parameter semantics, leaving notable gaps for such a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not explain 'query' or 'limit'. The agent must infer their meanings from the tool name and context, which is insufficient for correct parameter usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches course materials, and the mention of 'dense plus lexical reciprocal-rank fusion' distinguishes it from sibling tools like get_document. It is specific about both the action and the resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the search verb, but there is no explicit guidance on when to use this tool versus alternatives like get_document. No exclusions or alternative references are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_study_task_statusB

Set a study task status to pending, in_progress, or completed.

ParametersJSON Schema
NameRequiredDescriptionDefault
statusYes
task_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It only states what statuses can be set, which is already in the schema enum. It does not mention what the tool returns, whether it is idempotent, what happens on invalid task_id, or any 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with zero wasted words. It conveys the action, target, and allowed values efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with only 2 parameters and an output schema, so return values do not need explanation. However, for an update operation with no annotations, the description is minimal and lacks context about expected behavior on success/failure or prerequisites, leaving it adequate but with gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It repeats the status enum values but does not explain task_id beyond its name. The parameter names are self-explanatory, but the description adds no further semantic meaning, so it fails to compensate for missing schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Set' clearly indicates the action, and 'study task status' identifies the resource. It further specifies the allowed values (pending, in_progress, completed), which distinguishes it from sibling tools like create_study_task or list_study_tasks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the description: you would use this when you need to change the status of a study task. However, there is no explicit guidance about when not to use it or how it compares to alternatives like create_study_task, so it stops at implied rather than explicit.

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.

  1. 5 tool updatesv0.1.0
    • First observedcreate_study_task
    • First observedget_document
    • First observedlist_study_tasks
    • First observedsearch_materials
    • First observedupdate_study_task_status

TDQS

A3.7/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: searching materials, fetching a document by ID, and creating/list/updating task status. No overlapping responsibilities or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (search_materials, get_document, create_study_task, list_study_tasks, update_study_task_status). The slight plural/singular variation is semantically appropriate and does not break the pattern.

Tool Count5/5

With 5 tools, the server is well-scoped: two for material retrieval and three for task management. Each tool earns its place without redundancy or bloat.

Completeness4/5

The core workflows are covered: searching and reading materials, plus creating, listing, and updating task status. Minor gaps exist, such as lack of delete or full task edit (e.g., changing deadline), but these can be worked around.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

Latest Blog Posts

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/Chanoir999/StudyPilot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server