Skip to main content
Glama

jcs-mcp

An MCP server that exposes the Joaquim Chaves Saúde (JCS) patient portal (webapp.jcs.pt) as tools for Claude and other MCP clients.

It lets you ask Claude things like:

  • "Show me my upcoming appointments"

  • "What prescriptions do I have active?"

  • "Download my latest exam result and summarise it"

  • "List my invoices from the past 6 months"

Features

11 MCP tools covering the full JCS portal:

Tool

Description

jcs_login(password)

Authenticate; session saved to ~/.jcs_session.json (auto-renewed)

get_patient_info()

Name, email, patient ID

list_timeline(rows_to_skip?, archived?)

Main health feed — exam results, appointment confirmations, documents

list_notifications(rows_to_skip?, archived?)

Notifications and messages

get_message(id)

Full message detail; body contains signed document URIs

list_appointments()

Upcoming and recent appointments from the calendar

list_prescriptions(include_expired?)

Active (and optionally expired) prescriptions

list_invoices()

Invoices (Faturas/Recibos) from the patient profile

get_document_content(uri)

Fetch HTML exam result content from a signed URI

download_document(uri, filename?)

Download a PDF document, saved to ./downloads/jcs/documentos/

parse_prescription(file_path, model?)

Parse a prescription PDF with a local Ollama model

Session management

Authentication uses OAuth2 Resource Owner Password Grant against the GatewayBox platform. After the first jcs_login() call the session is persisted to ~/.jcs_session.json and reloaded automatically on subsequent calls. If JCS_PASSWORD is set in .env, the server will auto-login when the session expires — no manual intervention needed.

Prescription parsing

parse_prescription extracts structured data from a downloaded prescription PDF using a local Ollama model:

{
  "patient": "...",
  "date": "YYYY-MM-DD",
  "doctor": "...",
  "specialty": "...",
  "medications": [
    {
      "name": "...", "dci": "...", "strength": "...",
      "form": "...", "quantity": "...", "posology": "...", "duration": "..."
    }
  ],
  "prescription_number": "...",
  "notes": "..."
}

For image-based PDFs it falls back to vision mode automatically (use a vision-capable model like llava).

Related MCP server: CUF Health Portal MCP Server

Requirements

  • Python 3.10+

  • uv

  • A JCS account at webapp.jcs.pt

  • Your device UUID and device token key (see Auth setup below)

  • Ollama (optional, only needed for parse_prescription)

Installation

git clone https://github.com/nathanfolkman/jcs-mcp.git
cd jcs-mcp
uv sync

Configuration

Copy .env.example to .env and fill in your credentials:

cp .env.example .env
# Required
JCS_PHONE_NUMBER=+351912345678

# Optional — if set, the server will auto-login when the session expires
JCS_PASSWORD=your_password

# Required for first login (see Auth setup below)
JCS_DEVICE_UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
JCS_DEVICE_DTK=your_device_token_key

# Optional — where to save downloaded documents (default: ./downloads)
OUTPUT_DIR=./downloads

Auth setup

The JCS API uses a GatewayBox device registration system. Your script must present a device UUID and device token key (dtk) that are already registered with the server — unrecognised devices are rejected.

The easiest way to obtain these is from your browser session on webapp.jcs.pt:

  1. Open Chrome DevTools → Application → Local Storage → https://webapp.jcs.pt

  2. Find the key that contains your appUuid — this is your JCS_DEVICE_UUID

  3. Open DevTools → Network, log in normally, and look for the POST /api/device/token response — the deviceToken field is your JCS_DEVICE_DTK

Set both values in .env. After the first successful jcs_login() call they are also persisted to ~/.jcs_session.json.

Usage

With Claude Code

Add to your MCP settings (e.g. ~/.claude.json):

{
  "mcpServers": {
    "jcs-health": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/jcs-mcp", "python", "mcp_server.py"]
    }
  }
}

MCP Inspector (development)

uv run mcp dev mcp_server.py

Standalone

uv run python mcp_server.py

First-time login

If JCS_PASSWORD is not set in .env, call the login tool explicitly once:

jcs_login(password="your_password")

The session is saved and reused automatically until it expires (~24 hours).

Project structure

jcs-mcp/
├── jcs_client.py     # Async HTTP client (GatewayBox OAuth2 + all API methods)
├── mcp_server.py     # FastMCP server — 11 tools
├── pyproject.toml    # Dependencies
└── .env              # Credentials (not committed)

API notes

The JCS webapp is a single-page application built on the GatewayBox platform by Seamlink. All API endpoints were reverse-engineered from network traffic. Key facts:

  • Base URL: https://webapp.jcs.pt

  • Auth: OAuth2 password grant via POST /Token with uid, AppUuid, and dtk custom headers

  • All data endpoints use POST with a JSON body containing device (the appUuid)

  • Document URIs are signed, time-limited tokens embedded in message body HTML as data-attach-html attributes

  • HTML exam results: GET /api/attachdata/getcontent?uri=...

  • PDF documents: GET /api/attachdata/getfile?uri=...

License

MIT

Available Tools

11 tools
download_documentA

Download a clinical document PDF by signed URI. Saves to downloads/jcs/documentos/.

The uri comes from get_message() response.

Args: uri: Signed document URI from a message detail response. filename: Optional filename (e.g. "resultado_patologia.pdf").

Returns: Absolute path to the saved PDF file.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYes
filenameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are present, so the description carries the burden. It discloses the side effect of saving to downloads/jcs/documentos/ and the return value (absolute path), but it omits behavior around overwrites, filename defaults, or error handling. This is adequate but has clear 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 concise and front-loaded with the main purpose. It uses a clear Args/Returns structure with no filler or redundant information.

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 two-parameter download tool with an output schema, the description covers the source URI, destination folder, optional filename, and return value. It could reference alternatives like get_document_content, but the description is largely self-contained and sufficient for the tool's complexity.

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?

Schema description coverage is 0%, so the description must compensate. It explains that uri is a signed document URI from a message detail response and gives an example for the optional filename. It does not clarify the default filename behavior when omitted, which is a minor gap.

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 opens with 'Download a clinical document PDF by signed URI', which is a specific verb-object pair with clear scope. It distinguishes itself from sibling tools like get_document_content by specifying that it saves a PDF to a local directory.

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 states the prerequisite clearly: 'The uri comes from get_message() response.' This gives the agent the needed workflow context. It doesn't explicitly name alternatives or exclusions, but the usage intent is evident.

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

get_document_contentA

Fetch the HTML content of a clinical document or exam result.

The uri comes from get_message() response (in events[] or external_ref). Returns: {FileName, contentType, html}

Args: uri: Signed document URI from a message detail response.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYes

TDQS

A4.3/5.0
Behavior3/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 describes the operation as 'Fetch' and lists the return structure, but does not disclose potential errors, authentication requirements, or limits. Basic behavioral transparency is present but not rich.

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 compact and well-structured, with a clear main sentence, a returns line, and an args section. Every sentence adds useful information, and there is no redundancy.

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 tool with one parameter and no output schema, the description sufficiently covers purpose, parameter source, and return format. It lacks explicit error behavior or alternative tool guidance, but these are not critical for successful invocation.

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

Parameters5/5

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

With 0% schema coverage, the description fully compensates by explaining that 'uri' is a signed document URI and specifying exactly where it comes from (get_message() events[] or external_ref). This adds significant meaning beyond the schema's simple 'Uri' label.

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 it fetches HTML content of a clinical document or exam result, specifying a specific verb and resource. It also implicitly distinguishes itself from sibling tool download_document by focusing on HTML content rather than document download.

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?

It provides clear context by stating the uri comes from get_message() response, which guides the agent on the prerequisite step. However, it does not explicitly mention when to use this tool instead of alternatives like download_document.

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

get_messageA

Get full detail for a message/notification by ID.

The response includes the subject, body, linked events (appointments), and attachment URIs. Use get_document_content(uri) or download_document(uri) with any uri values found in the response to access the actual documents.

Args: message_id: Numeric message ID (from list_timeline or list_notifications).

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYes

TDQS

A4.6/5.0
Behavior4/5

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

While no annotations are provided, the description discloses what the response includes (subject, body, linked events, attachment URIs) and explicitly states that document URIs require separate retrieval via sibling tools. This clarifies the tool's scope and prevents user confusion, though it does not mention authorization or error behavior.

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 compact: a one-line purpose, a brief response summary, and a clear parameter note. Every sentence adds value, with no redundant content. It is front-loaded with the core purpose.

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 single-parameter read tool with no output schema or annotations, the description covers the essential information: what it does, what the response contains, how to get the ID, and how to handle attachment URIs. It could touch on error behavior or authentication but is otherwise complete for its scope.

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 input schema has only a bare integer type for message_id, but the description adds critical context: it is numeric and comes from list_timeline or list_notifications. This gives the parameter meaning beyond the schema, though it doesn't elaborate further on possible formats or edge cases.

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 retrieves full detail for a message/notification by ID, listing specific response elements (subject, body, linked events, attachment URIs). This distinguishes it from sibling listing tools and document access tools, 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 Guidelines5/5

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

The description explicitly tells the user to use list_timeline or list_notifications to obtain the message_id, and directs to get_document_content or download_document for actual document access using URIs from the response. This provides clear guidance on when to use this tool versus alternatives.

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

get_patient_infoB

Return patient profile: Name, Email, patientId, accounts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior2/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It only lists return fields and omits any mention of authentication requirements, session context, error behavior, or side effects. For a zero-parameter tool, it is especially important to explain how the patient is determined.

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 sentence with no filler, listing the return fields directly. It is front-loaded and every word earns its place.

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, but the description lacks context about how the patient is selected (e.g., relies on an active session from jcs_login) and what happens if no patient is found. Given no annotations or output schema, the description is minimally adequate but leaves important gaps.

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 input schema has zero parameters, so the baseline is 4. The description adds no parameter information, but none is needed since there are no parameters. However, it does not clarify how the tool identifies the patient, which is a semantic gap, though minor given the schema.

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

Purpose4/5

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

The description clearly states the tool's purpose with a specific verb ('Return') and resource ('patient profile'), listing the fields returned (Name, Email, patientId, accounts). It is specific enough to distinguish from sibling tools like list_appointments or list_prescriptions, though it does not explicitly name alternatives.

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, nor are any prerequisites or exclusions mentioned. The description is purely a statement of function without context on when it should be invoked.

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

jcs_loginA

Log in to JCS with phone number (from env) + password.

Only needs to be called once — the session is saved to ~/.jcs_session.json and reused automatically until it expires (~24h).

Returns: {"success": True, "patient_name": "...", "patient_id": "..."}

ParametersJSON Schema
NameRequiredDescriptionDefault
passwordYes

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries full weight. It discloses the session file (~/.jcs_session.json), automatic reuse, expiry duration, and return structure including success, patient_name, and patient_id. This gives the agent a clear model of the tool's side effects and persistence behavior.

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 concise at four sentences, front-loading the core action and then providing necessary session and return details. Every sentence adds value with no redundancy or fluff.

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

Completeness5/5

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

Despite having no output schema, the description explicitly states the return format, making the tool's outcome clear. With only a single parameter and no nested objects, the description covers session persistence and expiry, which is sufficient for a login tool. Missing error-handling details are minor and don't detract from overall completeness.

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

Parameters3/5

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

Schema coverage is 0% (the password field lacks a description), so the description must compensate. It clarifies that phone number comes from the environment and password is the sole user input, adding context beyond the schema. However, it doesn't add format, constraints, or requirements for the password, so it doesn't fully compensate.

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's purpose: 'Log in to JCS with phone number (from env) + password.' This is a specific verb (log in) with a clear resource (JCS) and distinguishes itself from sibling data-retrieval tools by being the only authentication tool.

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 provides explicit usage guidance: 'Only needs to be called once' and explains the session is saved and reused until expiry (~24h). This clarifies when to invoke the tool and when it's unnecessary, though it doesn't explicitly mention alternatives (none exist among siblings).

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

list_appointmentsA

Return upcoming and recent appointments from the calendar.

Each event has: date, time, description, location (clinic), patient name.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full transparency burden. It discloses that each event includes date, time, description, location, and patient name, which is useful. However, it does not mention authorizations, sorting, limits, or whether it returns only a summary, leaving room for ambiguity.

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 two short sentences that immediately state the purpose and then list the returned fields. Every sentence earns its place, and there is no wasted text or repetition of the tool name.

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 zero-parameter read-only list tool, the description is adequately complete: it states the scope (upcoming and recent), source (calendar), and the fields returned. It could mention whether login is required or how many items are returned, but these are minor gaps given the simplicity.

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 tool has zero parameters and the schema properties are empty, so the baseline is 4. The description adds value by explaining what is returned, though it does not need to explain parameter behavior since none exist.

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 ('Return') and names the resource ('appointments from the calendar') with a clear scope ('upcoming and recent'). This clearly differentiates it from siblings like list_timeline or list_notifications, which cover different calendars or notification types.

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 when to use the tool: when you need upcoming and recent appointments with their details. However, it does not explicitly state when not to use it or mention alternatives like list_timeline for broader calendar events, so the guidance is reasonably clear but not explicit.

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

list_invoicesA

Return invoices (Faturas) from the patient profile.

Each item contains clinic, invoice number (Fatura/Recibo), date, amount. Use download_document(uri) with the item's attach URI to download the PDF.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior2/5

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

With no annotations, the description carries the full burden for behavioral disclosure. It mentions the return items and a download action, but it omits important traits such as authentication prerequisites (e.g., requiring jcs_login), pagination behavior, and the exact field name for the attach URI (it is not listed among the item fields). This leaves operational gaps for the agent.

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 two sentences, with the primary purpose in the first sentence and supporting details in the second. It is front-loaded, efficient, and every sentence contributes value.

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 no params and no output schema, so the description does explain the main return fields (clinic, number, date, amount). However, it fails to mention the attach URI as an item field, which creates ambiguity for the download step. Pagination is not addressed, leaving some incompleteness.

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 input schema has zero parameters, so the description has no need to explain parameter meanings. The baseline for 0 params is 4, and the description does not introduce any parameter-related confusion.

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 states a specific verb and resource: 'Return invoices (Faturas) from the patient profile.' This clearly distinguishes it from sibling list tools like list_prescriptions and list_appointments, and the parenthetical clarifies the term in the target language.

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?

It provides clear context ('from the patient profile') and a concrete follow-up action ('Use download_document(uri) with the item's attach URI to download the PDF'). However, it does not explicitly mention when not to use this tool or compare it to alternatives, so it lacks explicit exclusions.

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

list_notificationsA

Return notifications/messages list. Returns {items, channels}.

Args: rows_to_skip: Pagination offset (default 0). archived: Include archived notifications (default False).

ParametersJSON Schema
NameRequiredDescriptionDefault
archivedNo
rows_to_skipNo

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description adds some transparency by disclosing the return shape ('{items, channels}') and parameter defaults. However, it does not state whether the operation is read-only, whether it has side effects, or any other behavioral constraints, leaving much to inference.

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 extremely concise—two short sentences plus argument documentation—with the purpose stated first. Every word earns its place, and there is no wasted text.

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 tool with two optional parameters and no output schema, the description provides sufficient context including the return structure and parameter behavior. It lacks details like authentication requirements or result limits, but is generally adequate.

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 description compensates for the 0% schema coverage by explaining 'rows_to_skip' as pagination offset and 'archived' as controlling inclusion of archived notifications. This adds meaningful semantics beyond the schema's bare property names and defaults.

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

Purpose4/5

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

The description clearly states 'Return notifications/messages list' with a specific verb and resource, distinguishing it from sibling list tools like list_appointments and list_prescriptions. However, the phrase 'notifications/messages' is slightly ambiguous and no scope or filtering is described.

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 given on when to use this tool versus alternatives such as get_message or list_timeline. The description simply states what the tool does without any context about when it is appropriate.

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

list_prescriptionsB

Return prescriptions list.

Args: include_expired: Include expired prescriptions (default False).

ParametersJSON Schema
NameRequiredDescriptionDefault
include_expiredNo

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It reveals that expired prescriptions are excluded by default via the 'include_expired' argument, which is useful behavioral context. However, it doesn't disclose other behaviors like ordering, scope, or potential 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 extremely concise, front-loaded with the main purpose, and includes a structured Args section for the parameter. Every sentence earns its place with no unnecessary content.

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?

For a simple list tool with one parameter and no output schema, the description is minimally adequate. It lacks context on scope (e.g., patient vs. all prescriptions), return format, or prerequisites, and no annotations exist to fill the gap. The sibling tools suggest a clinical context, but this isn't stated.

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

Parameters3/5

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

The schema provides only the parameter name and default, with 0% description coverage. The description compensates by explaining 'include_expired' as 'Include expired prescriptions', which adds meaning beyond the schema. It's clear but not rich.

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

Purpose4/5

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

The description 'Return prescriptions list' clearly identifies the action (return) and the resource (prescriptions list), making the purpose clear. It distinguishes from siblings like parse_prescription, which implies a different operation, though it doesn't explicitly differentiate.

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. There is no mention of context (e.g., patient scope, auth requirements) or exclusions. The parameter description implies default behavior but doesn't state usage scenarios.

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

list_timelineA

Return the main health feed — exam results, appointment confirmations, docs, etc.

Items have: id, subject, body_preview, msgtype, publish_date, un_read, events[]. Use get_message(id) to fetch full detail + attachment URIs for a specific item.

Args: rows_to_skip: Pagination offset (default 0). archived: Include archived items (default False).

ParametersJSON Schema
NameRequiredDescriptionDefault
archivedNo
rows_to_skipNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description discloses the item shape (id, subject, body_preview, msgtype, publish_date, un_read, events[]) and the semantics of pagination and the archived flag. It stops short of stating sorting order, error behavior, or authentication requirements, but the read-only nature is clearly implied by 'Return'.

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 front-loads the main purpose in the first sentence, then uses compact lines for fields and arguments. There is no redundant text or restating of the tool name.

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 two-parameter list endpoint with no output schema, the description covers purpose, return field names, pagination offset, archived behavior, and the path to full details. Minor gaps remain around sort order and the meaning of msgtype/events[], but these are not critical for invocation.

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

Parameters5/5

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

The schema provides only titles and defaults, so the description's Args section is the sole source of meaning. It defines rows_to_skip as 'Pagination offset' and archived as 'Include archived items', which is clear and sufficient for both optional parameters.

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 opens with a specific verb and resource ('Return the main health feed') and gives concrete content examples like exam results and appointment confirmations. It also distinguishes itself from get_message by directing users there for full details, making clear this tool returns feed summaries.

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?

It explicitly tells users to use get_message(id) when they need full detail or attachment URIs, establishing a clear division of labor. It also documents pagination usage through rows_to_skip, though it does not explicitly contrast list_timeline with list_notifications.

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

parse_prescriptionA

Parse a downloaded prescription PDF with a local Ollama model.

Extracts text from the PDF and sends it to a local Ollama model for structured extraction. Falls back to vision-mode (image rendering) for image-based PDFs.

Args: file_path: Path to the prescription PDF (from download_document). model: Ollama model ID to use (default: "llama3.2"; use a vision model like "llava" if the PDF is image-based).

Returns structured dict with: patient, date, doctor, specialty, medications (list with name/dci/strength/form/quantity/posology/duration), prescription_number, notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNollama3.2
file_pathYes

TDQS

A4.3/5.0
Behavior3/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 describes the two-step process (PDF text extraction and Ollama model extraction) and the fallback to vision mode. It also lists the return structure, but does not disclose potential side effects, prerequisites like Ollama being installed, or error handling behavior.

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 well-structured with a clear one-line summary, a brief process explanation, and an Args list. No redundant information; every sentence adds value.

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?

Given there is no output schema, the description accurately lists the full return dict fields. It also explains the input source and model options. It is complete for an agent to understand invocation, though it could mention failure scenarios.

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

Parameters5/5

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

The description includes an Args section that explains both parameters beyond the schema, noting file_path is the path from download_document and recommending vision models for image-based PDFs. Since schema coverage is 0%, this fully compensates.

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 parses a downloaded prescription PDF, with a specific verb ('Parse') and resource, and distinguishes it from sibling tools like download_document and get_document_content by focusing on structured extraction via a local Ollama model.

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?

It provides context on when to use the tool (after downloading a prescription PDF) and gives guidance on model selection for image-based PDFs. However, it does not explicitly mention alternatives or when not to use it, making it clear but not fully 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.

  1. 11 tool updatesv0.1.0
    • First observeddownload_document
    • First observedget_document_content
    • First observedget_message
    • First observedget_patient_info
    • First observedjcs_login
    • First observedlist_appointments
    • First observedlist_invoices
    • First observedlist_notifications
    • First observedlist_prescriptions
    • First observedlist_timeline
    • First observedparse_prescription

TDQS

A3.8/5.0

Scored across 11 tools

Disambiguation3/5

Most tools are clearly distinct, but list_timeline and list_notifications overlap significantly—both return lists of messages with similar arguments and point to get_message for details. Additionally, get_document_content and download_document both handle attachment URIs, which could cause misselection without careful reading.

Naming Consistency4/5

The naming pattern is predominantly verb_noun (get_patient_info, list_appointments, download_document, parse_prescription), which is consistent and predictable. The outlier is jcs_login, which breaks the pattern by using a product prefix and lacking a clear object, introducing minor inconsistency.

Tool Count5/5

With 11 tools, the server is well-scoped for a healthcare portal client. It covers authentication, data retrieval, document access, and a niche parsing feature without being bloated or too thin. Each tool serves a distinct purpose in the overall workflow.

Completeness4/5

The tool surface provides a complete read-only lifecycle for the domain: listing and getting messages, appointments, prescriptions, invoices, and documents. Minor gaps exist, such as no ability to search, mark-as-read, or perform actions like scheduling appointments, but these are not core to the apparent purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers