Skip to main content
Glama

stackexchange-mcp-server

Get Stack Exchange Q&A Thread

stackexchange_get_thread
Read-onlyIdempotent

Fetch a complete Q&A thread — question body and all answers, accepted answer first then sorted by score, rendered as clean markdown with fenced code blocks. Accepts a full Stack Exchange question URL, which is read from the site its host names (e.g. "https://unix.stackexchange.com/questions/88490/how-do-i-use-a-heredoc"), or an integer question ID read from site (e.g. "11227809"). HTML is normalized to markdown automatically; attribution (author + link) included per CC BY-SA 4.0. Get question IDs from stackexchange_search_questions or stackexchange_get_tag_faq.

Input Schema

NameRequiredDescriptionDefault
siteNoStack Exchange site a numeric question ID belongs to — the api_site_parameter (e.g. "stackoverflow", "unix") or the site's domain (e.g. "unix.stackexchange.com"). Defaults to "stackoverflow". Not needed with a URL, which names its own site: a site naming a different one is ignored, or used when the URL host is not a Stack Exchange site, and either way reported as siteConflict. Call stackexchange_list_sites to discover valid values.
maxAnswersNoMaximum number of answers to include (1–100, default 10). Answers are sorted: accepted first, then by score.
includeCommentsNoFetch the comment thread under the question and under every returned answer (default false). Comments are where a stale answer usually gets corrected ("this breaks on v3", "use X instead now"), so set this when the answer's continued accuracy matters. Costs 2 extra API calls against the daily quota regardless of how many answers are returned.
questionIdOrUrlYesNumeric question ID (e.g. "11227809") or a full Stack Exchange question URL (e.g. "https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster"). A URL carries its own site: the question is read from the URL's host, so question IDs from any Stack Exchange site resolve correctly. A URL whose host is not a Stack Exchange site is read from site when one is given, and fails as invalid_site otherwise.

Output Schema

NameRequiredDescriptionDefault
capNoThe maxAnswers cap applied to this request.
linkNoDirect URL to the question.
tagsNoTags applied to this question.
errorNoPresent when the call failed. Absent on success.
scoreNoQuestion score (upvotes minus downvotes).
shownNoNumber of answers returned.
titleNoQuestion title.
answersNoAnswers sorted: accepted answer first, then by score descending.
commentsNoComments on the question, newest first, present only when includeComments is true. An empty array means this post has no comments; an absent array means its comment state is unknown — either comments were not requested, or the batched fetch was cut short before this post contributed any. Never read an absent array as "no comments".
quotaMaxNoMaximum API quota calls per day (300 keyless, ~10,000 with API key).
truncatedNoTrue when answers were capped at maxAnswers.
authorLinkNoQuestion author profile URL when available.
authorNameNoQuestion author display name when available.
questionIdNoNumeric question ID — identifies this thread on the site.
answerCountNoTotal answers the question has upstream. When greater than the returned answers[] length, more answers exist — raise maxAnswers to fetch them.
commentsCapNoMaximum comments carried per post — a post at this count reports commentsTruncated.
authorUserIdNoQuestion author numeric user ID when available — pass to stackexchange_get_user to fetch the full profile.
bodyMarkdownNoQuestion body normalized from HTML to markdown.
creationDateNoISO 8601 timestamp of when the question was asked — use it to judge whether the advice is still current.
siteConflictNoPresent only when questionIdOrUrl is a URL and site names a different site — says which of the two the question was read from.
quotaRemainingNoRemaining API quota calls for the current day.
acceptedAnswerIdNoID of the accepted answer when one exists.
lastActivityDateNoISO 8601 timestamp of the most recent activity on the question (edit, answer, or comment).
commentsTruncatedNoTrue when the question's comments[] is a partial list — more exist upstream than were returned.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • changedInput schema / properties / questionIdOrUrl / description
      Previous value: -"Numeric question ID (e.g. \"11227809\") or a full Stack Exchange question URL (e.g. \"https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster\"). The integer immediately following /questions/ is extracted from URLs."New value: +"Numeric question ID (e.g. \"11227809\") or a full Stack Exchange question URL (e.g. \"https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster\"). A URL carries its own site: the question is read from the URL's host, so question IDs from any Stack Exchange site resolve correctly. A URL whose host is not a Stack Exchange site is read from site when one is given, and fails as invalid_site otherwise."
    • removedInput schema / properties / site / default
      Removed value: -"stackoverflow"
    • changedInput schema / properties / site / description
      Previous value: -"Stack Exchange site — use the api_site_parameter value (e.g. \"stackoverflow\", \"superuser\"). Defaults to \"stackoverflow\". Must match the site where the question lives. Call stackexchange_list_sites to discover valid values."New value: +"Stack Exchange site a numeric question ID belongs to — the api_site_parameter (e.g. \"stackoverflow\", \"unix\") or the site's domain (e.g. \"unix.stackexchange.com\"). Defaults to \"stackoverflow\". Not needed with a URL, which names its own site: a site naming a different one is ignored, or used when the URL host is not a Stack Exchange site, and either way reported as siteConflict. Call stackexchange_list_sites to discover valid values."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `invalid_parameter`: Stack Exchange rejected a request parameter other than the question ID, and named the field. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. `invalid_api_key`: Stack Exchange does not recognize the API key this server is configured with. `upstream_unavailable`: Stack Exchange answered with a body that is not the expected JSON envelope. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The site value, or the host of a question URL, is not a Stack Exchange network site. `invalid_id_or_url`: The input is neither an integer ID nor text holding a /questions/{id} path, or Stack Exchange refused the ID. `invalid_parameter`: Stack Exchange rejected a request parameter other than the question ID, and named the field. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. `throttled`: Stack Exchange is throttling this server's IP address, or its backoff window outlasts what the call can wait. `pacer_shed`: The call would wait in this server's queue to Stack Exchange longer than its time budget allows. `invalid_api_key`: Stack Exchange does not recognize the API key this server is configured with. `upstream_unavailable`: Stack Exchange reported itself temporarily unavailable or failing internally, or answered with a body that is not the expected JSON envelope. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "question_not_found",
      -  "invalid_site",
      -  "invalid_id_or_url",
      -  "invalid_parameter",
      -  "quota_exceeded",
      -  "invalid_api_key",
      -  "upstream_unavailable"
      -]New value: +[
      +  "question_not_found",
      +  "invalid_site",
      +  "invalid_id_or_url",
      +  "invalid_parameter",
      +  "quota_exceeded",
      +  "throttled",
      +  "pacer_shed",
      +  "invalid_api_key",
      +  "upstream_unavailable"
      +]
    • addedOutput schema / properties / siteConflict
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present only when questionIdOrUrl is a URL and site names a different site — says which of the two the question was read from.",
      +  "properties": {
      +    "resolvedBy": {
      +      "description": "Which one the question was read from: \"url_host\" when site was ignored in favor of the URL's own site, \"site\" when the URL host is not a Stack Exchange site and site was used instead.",
      +      "enum": [
      +        "url_host",
      +        "site"
      +      ],
      +      "type": "string"
      +    },
      +    "site": {
      +      "description": "The site value passed.",
      +      "type": "string"
      +    },
      +    "urlHost": {
      +      "description": "Host of the question URL.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "resolvedBy",
      +    "urlHost",
      +    "site"
      +  ],
      +  "type": "object"
      +}
  2. Changed8 schema fields changed
    • addedInput schema / properties / includeComments
      Added value: +{
      +  "default": false,
      +  "description": "Fetch the comment thread under the question and under every returned answer (default false). Comments are where a stale answer usually gets corrected (\"this breaks on v3\", \"use X instead now\"), so set this when the answer's continued accuracy matters. Costs 2 extra API calls against the daily quota regardless of how many answers are returned.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / answers / items / properties / comments
      Added value: +{
      +  "description": "Comments on this answer, newest first, present only when includeComments is true. An empty array means this post has no comments; an absent array means its comment state is unknown — either comments were not requested, or the batched fetch was cut short before this post contributed any. Never read an absent array as \"no comments\".",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "A single comment with markdown body, score, date, and author attribution.",
      +    "properties": {
      +      "authorLink": {
      +        "description": "Comment author profile URL when available.",
      +        "type": "string"
      +      },
      +      "authorName": {
      +        "description": "Comment author display name when available.",
      +        "type": "string"
      +      },
      +      "bodyMarkdown": {
      +        "description": "Comment body normalized from HTML to markdown.",
      +        "type": "string"
      +      },
      +      "commentId": {
      +        "description": "Numeric comment ID.",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "creationDate": {
      +        "description": "ISO 8601 timestamp of when the comment was posted — the newest comments carry the freshest corrections.",
      +        "type": "string"
      +      },
      +      "score": {
      +        "description": "Comment score — comments can score below zero.",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "commentId",
      +      "score",
      +      "bodyMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / answers / items / properties / commentsTruncated
      Added value: +{
      +  "description": "True when this answer's comments[] is a partial list — more exist upstream than were returned.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / comments
      Added value: +{
      +  "description": "Comments on the question, newest first, present only when includeComments is true. An empty array means this post has no comments; an absent array means its comment state is unknown — either comments were not requested, or the batched fetch was cut short before this post contributed any. Never read an absent array as \"no comments\".",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "A single comment with markdown body, score, date, and author attribution.",
      +    "properties": {
      +      "authorLink": {
      +        "description": "Comment author profile URL when available.",
      +        "type": "string"
      +      },
      +      "authorName": {
      +        "description": "Comment author display name when available.",
      +        "type": "string"
      +      },
      +      "bodyMarkdown": {
      +        "description": "Comment body normalized from HTML to markdown.",
      +        "type": "string"
      +      },
      +      "commentId": {
      +        "description": "Numeric comment ID.",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "creationDate": {
      +        "description": "ISO 8601 timestamp of when the comment was posted — the newest comments carry the freshest corrections.",
      +        "type": "string"
      +      },
      +      "score": {
      +        "description": "Comment score — comments can score below zero.",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "commentId",
      +      "score",
      +      "bodyMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / commentsCap
      Added value: +{
      +  "description": "Maximum comments carried per post — a post at this count reports commentsTruncated.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / commentsTruncated
      Added value: +{
      +  "description": "True when the question's comments[] is a partial list — more exist upstream than were returned.",
      +  "type": "boolean"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `invalid_parameter`: Stack Exchange rejected a request parameter other than the question ID, and named the field. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `invalid_parameter`: Stack Exchange rejected a request parameter other than the question ID, and named the field. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. `invalid_api_key`: Stack Exchange does not recognize the API key this server is configured with. `upstream_unavailable`: Stack Exchange answered with a body that is not the expected JSON envelope. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "question_not_found",
      -  "invalid_site",
      -  "invalid_id_or_url",
      -  "invalid_parameter",
      -  "quota_exceeded"
      -]New value: +[
      +  "question_not_found",
      +  "invalid_site",
      +  "invalid_id_or_url",
      +  "invalid_parameter",
      +  "quota_exceeded",
      +  "invalid_api_key",
      +  "upstream_unavailable"
      +]
  3. Changed7 schema fields changed
    • changedOutput schema / properties / answers / items / description
      Previous value: -"A single Q&A answer with markdown body, score, and author attribution."New value: +"A single Q&A answer with markdown body, score, dates, and author attribution."
    • addedOutput schema / properties / answers / items / properties / creationDate
      Added value: +{
      +  "description": "ISO 8601 timestamp of when the answer was posted — an old answer may predate the current API.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / answers / items / properties / lastActivityDate
      Added value: +{
      +  "description": "ISO 8601 timestamp of the most recent edit or activity on the answer.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / creationDate
      Added value: +{
      +  "description": "ISO 8601 timestamp of when the question was asked — use it to judge whether the advice is still current.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `invalid_parameter`: Stack Exchange rejected a request parameter other than the question ID, and named the field. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "question_not_found",
      -  "invalid_site",
      -  "invalid_id_or_url",
      -  "quota_exceeded"
      -]New value: +[
      +  "question_not_found",
      +  "invalid_site",
      +  "invalid_id_or_url",
      +  "invalid_parameter",
      +  "quota_exceeded"
      +]
    • addedOutput schema / properties / lastActivityDate
      Added value: +{
      +  "description": "ISO 8601 timestamp of the most recent activity on the question (edit, answer, or comment).",
      +  "type": "string"
      +}
  4. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "questionId",
      +      "title",
      +      "link",
      +      "score",
      +      "tags",
      +      "bodyMarkdown",
      +      "answers",
      +      "quotaRemaining",
      +      "quotaMax"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `question_not_found`: The question lookup returns an empty result set — SE returns HTTP 200 with no items for unknown question IDs rather than 404. `invalid_site`: The provided site value is not a valid Stack Exchange network site identifier. `invalid_id_or_url`: The input is not a parseable integer ID and not a recognizable SE question URL. `quota_exceeded`: The Stack Exchange API quota_remaining has reached 0. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "question_not_found",
      +            "invalid_site",
      +            "invalid_id_or_url",
      +            "quota_exceeded"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "questionId",
      -  "title",
      -  "link",
      -  "score",
      -  "tags",
      -  "bodyMarkdown",
      -  "answers",
      -  "quotaRemaining",
      -  "quotaMax"
      -]
  5. Changed1 schema field changed
    • addedOutput schema / properties / answerCount
      Added value: +{
      +  "description": "Total answers the question has upstream. When greater than the returned answers[] length, more answers exist — raise maxAnswers to fetch them.",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
  6. Changed3 schema fields changed
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The maxAnswers cap applied to this request.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Number of answers returned.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when answers were capped at maxAnswers.",
      +  "type": "boolean"
      +}
  7. First observed

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description still adds real value beyond that: HTML-to-markdown normalization, per-post author attribution under CC BY-SA 4.0, and deterministic answer ordering — behavior an agent could not infer from the structured fields.

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?

Front-loaded with the operation and its output shape, then input forms with concrete examples, then rendering/licensing, then a pointer to sibling tools for IDs. Every sentence carries distinct information with no redundancy.

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?

Output schema exists, so return values need no prose, yet the description still usefully previews the markdown rendering and ordering. With a single required parameter, four documented options, and full annotations, an agent has everything needed to call this correctly.

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 description coverage is 100%, so the schema already documents site, maxAnswers, includeComments, and questionIdOrUrl in depth, including the siteConflict behavior and quota cost. The description only restates the URL-carries-its-site and integer-ID-read-from-site semantics, adding little beyond the schema baseline.

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?

Specific verb and resource — fetch a complete Q&A thread including question body and all answers — plus the exact ordering rule (accepted first, then by score) and output form (markdown with fenced code blocks). This clearly distinguishes it from stackexchange_search_questions, which returns a result list rather than a full thread.

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?

Explicitly routes the agent to stackexchange_search_questions or stackexchange_get_tag_faq for obtaining question IDs, and clarifies the two input modes (URL vs integer ID). It stops short of stating when not to use this tool, and the useful guidance about enabling includeComments for accuracy-sensitive answers lives in the schema rather than the description.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.