Skip to main content
Glama

diagnose_institutional_access

Read-onlyIdempotent

Diagnose why institutional full-text access fails for a DOI or PMID by testing direct and EZproxy routes, then reporting each outcome and next step.

Instructions

Diagnose why institutional fulltext access succeeds or fails for an article.

Runs up to three probes and reports each path's outcome:

  1. Direct fetch (Phase 1, IP-aware) — follows https://doi.org/<doi> and classifies whether the publisher served fulltext, a paywall, or a login page. Works automatically when your network IP is on the publisher's institutional allow-list (campus / VPN).

  2. EZproxy fetch (Phase 2, BYO-cookie) — rewrites the publisher hostname to your library's EZproxy host and replays your exported browser session cookie. Configured via env vars:

    • EZPROXY_HOST (e.g. ezproxy.lib.ntu.edu.tw)

    • EZPROXY_COOKIE_FILE (path to browser-exported cookies.json)

    • EZPROXY_ENABLED=1

  3. OpenURL handoff — generated for you to open manually in a browser when the automated paths fail.

Usage: diagnose_institutional_access( source={"kind": "doi", "value": "10.1097/ALN.0000000000003599"} )

diagnose_institutional_access(
    source={"kind": "pmid", "value": "38353755"},
    try_ezproxy=False
)

Args: source: Exactly one PMID or DOI. A PMID is resolved to a DOI when possible so direct and EZproxy probes can run. try_direct: Run the Phase 1 direct probe (default True). try_ezproxy: Run the Phase 2 EZproxy probe (default True).

Returns: Markdown report listing every probe's status, classification, and advice on the next action to take.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sourceYes
try_directNo
try_ezproxyNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed26 schema fields changedv0.7.7
    • addedInput schema / $defs / DOISource / properties / kind / anyOf
      Added value: +[
      +  {
      +    "const": "doi",
      +    "title": "Kind",
      +    "type": "string"
      +  },
      +  {
      +    "pattern": "^[ \\t\\r\\n]*(?:[dD][oO][iI])[ \\t\\r\\n]*$",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / $defs / DOISource / properties / kind / const
      Removed value: -"doi"
    • removedInput schema / $defs / DOISource / properties / kind / type
      Removed value: -"string"
    • addedInput schema / $defs / DOISource / properties / value / description
      Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
    • addedInput schema / $defs / DOISource / properties / value / examples
      Added value: +[
      +  "10.1000/example",
      +  "doi:10.1000/example",
      +  "https://doi.org/10.1000/example"
      +]
    • addedInput schema / $defs / DOISource / properties / value / format
      Added value: +"pubmed-doi"
    • changedInput schema / $defs / DOISource / properties / value / minLength
      Previous value: -7New value: +1
    • removedInput schema / $defs / DOISource / properties / value / pattern
      Removed value: -"^10\\.[0-9]{4,9}/"
    • addedInput schema / $defs / DOISource / properties / value / x-pubmed-input
      Added value: +"doi"
    • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
      Added value: +[
      +  {
      +    "const": "pmid",
      +    "title": "Kind",
      +    "type": "string"
      +  },
      +  {
      +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / $defs / PMIDSource / properties / kind / const
      Removed value: -"pmid"
    • removedInput schema / $defs / PMIDSource / properties / kind / type
      Removed value: -"string"
    • addedInput schema / $defs / PMIDSource / properties / value / description
      Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
    • addedInput schema / $defs / PMIDSource / properties / value / examples
      Added value: +[
      +  "33053718",
      +  "PMID:33053718",
      +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
      +]
    • addedInput schema / $defs / PMIDSource / properties / value / format
      Added value: +"pubmed-pmid"
    • changedInput schema / $defs / PMIDSource / properties / value / maxLength
      Previous value: -20New value: +512
    • addedInput schema / $defs / PMIDSource / properties / value / minLength
      Added value: +1
    • removedInput schema / $defs / PMIDSource / properties / value / pattern
      Removed value: -"^[1-9][0-9]{0,19}$"
    • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
      Added value: +"pmid"
    • addedInput schema / properties / source / anyOf
      Added value: +[
      +  {
      +    "discriminator": {
      +      "mapping": {
      +        "doi": "#/$defs/DOISource",
      +        "pmid": "#/$defs/PMIDSource"
      +      },
      +      "propertyName": "kind"
      +    },
      +    "oneOf": [
      +      {
      +        "$ref": "#/$defs/PMIDSource"
      +      },
      +      {
      +        "$ref": "#/$defs/DOISource"
      +      }
      +    ],
      +    "title": "Source"
      +  },
      +  {
      +    "contentMediaType": "application/json",
      +    "contentSchema": {
      +      "discriminator": {
      +        "mapping": {
      +          "doi": "#/$defs/DOISource",
      +          "pmid": "#/$defs/PMIDSource"
      +        },
      +        "propertyName": "kind"
      +      },
      +      "oneOf": [
      +        {
      +          "$ref": "#/$defs/PMIDSource"
      +        },
      +        {
      +          "$ref": "#/$defs/DOISource"
      +        }
      +      ],
      +      "title": "Source"
      +    },
      +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
      +    "maxLength": 1000000,
      +    "type": "string"
      +  },
      +  {
      +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
      +    "maxLength": 1000000,
      +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
      +    "type": "string",
      +    "x-pubmed-decodedSchema": {
      +      "discriminator": {
      +        "mapping": {
      +          "doi": "#/$defs/DOISource",
      +          "pmid": "#/$defs/PMIDSource"
      +        },
      +        "propertyName": "kind"
      +      },
      +      "oneOf": [
      +        {
      +          "$ref": "#/$defs/PMIDSource"
      +        },
      +        {
      +          "$ref": "#/$defs/DOISource"
      +        }
      +      ],
      +      "title": "Source"
      +    },
      +    "x-pubmed-encoding": "fenced-json"
      +  }
      +]
    • removedInput schema / properties / source / discriminator
      Removed value: -{
      -  "mapping": {
      -    "doi": "#/$defs/DOISource",
      -    "pmid": "#/$defs/PMIDSource"
      -  },
      -  "propertyName": "kind"
      -}
    • removedInput schema / properties / source / oneOf
      Removed value: -[
      -  {
      -    "$ref": "#/$defs/PMIDSource"
      -  },
      -  {
      -    "$ref": "#/$defs/DOISource"
      -  }
      -]
    • addedInput schema / properties / try_direct / anyOf
      Added value: +[
      +  {
      +    "default": true,
      +    "title": "Try Direct",
      +    "type": "boolean"
      +  },
      +  {
      +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
      +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / properties / try_direct / type
      Removed value: -"boolean"
    • addedInput schema / properties / try_ezproxy / anyOf
      Added value: +[
      +  {
      +    "default": true,
      +    "title": "Try Ezproxy",
      +    "type": "boolean"
      +  },
      +  {
      +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
      +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / properties / try_ezproxy / type
      Removed value: -"boolean"
  2. Changed7 schema fields changedv0.7.2
    • addedInput schema / $defs
      Added value: +{
      +  "DOISource": {
      +    "additionalProperties": false,
      +    "description": "An explicit DOI.",
      +    "properties": {
      +      "kind": {
      +        "const": "doi",
      +        "title": "Kind",
      +        "type": "string"
      +      },
      +      "value": {
      +        "maxLength": 512,
      +        "minLength": 7,
      +        "pattern": "^10\\.[0-9]{4,9}/",
      +        "title": "Value",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "kind",
      +      "value"
      +    ],
      +    "title": "DOISource",
      +    "type": "object"
      +  },
      +  "PMIDSource": {
      +    "additionalProperties": false,
      +    "description": "An explicit PubMed identifier.",
      +    "properties": {
      +      "kind": {
      +        "const": "pmid",
      +        "title": "Kind",
      +        "type": "string"
      +      },
      +      "value": {
      +        "maxLength": 20,
      +        "pattern": "^[1-9][0-9]{0,19}$",
      +        "title": "Value",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "kind",
      +      "value"
      +    ],
      +    "title": "PMIDSource",
      +    "type": "object"
      +  }
      +}
    • addedInput schema / additionalProperties
      Added value: +false
    • removedInput schema / properties / doi
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "title": "Doi"
      -}
    • removedInput schema / properties / pmid
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "title": "Pmid"
      -}
    • addedInput schema / properties / source
      Added value: +{
      +  "discriminator": {
      +    "mapping": {
      +      "doi": "#/$defs/DOISource",
      +      "pmid": "#/$defs/PMIDSource"
      +    },
      +    "propertyName": "kind"
      +  },
      +  "oneOf": [
      +    {
      +      "$ref": "#/$defs/PMIDSource"
      +    },
      +    {
      +      "$ref": "#/$defs/DOISource"
      +    }
      +  ],
      +  "title": "Source"
      +}
    • addedInput schema / required
      Added value: +[
      +  "source"
      +]
    • changedOutput schema / (root)
      Previous value: -{
      -  "properties": {
      -    "result": {
      -      "title": "Result",
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "result"
      -  ],
      -  "title": "diagnose_institutional_accessOutput",
      -  "type": "object"
      -}New value: +null
  3. First observedv0.5.16

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already establish readOnly/idempotent/openWorld/non-destructive, and the description adds substantial behavior beyond them: the three probe phases, what each probe does with the DOI, that EZproxy requires exported browser cookies and specific env vars, and that it probes live external hosts. Auth and network prerequisites are disclosed, which is exactly the added value expected.

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 front-loaded with the purpose and organized into numbered phases plus a Usage block, so it is easy to scan. It is somewhat long and the docstring-style Args/Returns sections partly restate the schema, but each section contributes usable detail rather than filler.

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 3-parameter diagnostic tool with no output schema, the description covers purpose, all probe phases, configuration prerequisites, and the markdown report it returns. The only notable gap is the absence of any pointer to the overlapping institutional-access siblings, which leaves an agent unsure of routing between them.

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?

Schema description coverage is 0% for the top-level parameters, so the description must carry the burden, and it does: it defines source (exactly one PMID or DOI, with the PMID-to-DOI resolution behavior explained), try_direct (Phase 1 toggle, default True), and try_ezproxy (Phase 2 toggle, default True). This adds real meaning — the resolution side effect — beyond the schema's bare booleans.

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 states a precise verb and resource ("Diagnose why institutional fulltext access succeeds or fails for an article") and enumerates the three probes it runs, so the agent knows exactly what it does. However, it never differentiates itself from closely related siblings such as test_institutional_access, configure_institutional_access, or get_institutional_link, so it falls short of a 5.

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?

Usage is well conveyed through two concrete invocation examples and clear preconditions (campus/VPN IP for Phase 1; EZPROXY_HOST/COOKIE_FILE/ENABLED for Phase 2; manual OpenURL when automated paths fail). There is no explicit when-not-to-use guidance or routing to the sibling tools that overlap this space, so it is clear context without alternatives.

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