Wraps the Stack Exchange API to let Claude search questions, pull complete Q&A threads as markdown, browse tag FAQs, and look up user profiles across the entire network. The get_thread tool is the centerpiece: it fetches a question and all its answers in parallel, normalizes HTML to clean markdown, and sorts by accepted answer first. Built on the author's mcp-ts-core framework with backoff tracking and quota surfacing on every response so agents can plan around rate limits. Ships with a public hosted instance at stackexchange.caseyjhand.com, or run it locally via npx or Bun. Optional API key lifts the daily quota from 300 to 10,000 requests. Reach for this when you need programmatic access to Stack Overflow content with proper attribution.
Search Stack Exchange questions, fetch complete Q&A threads as clean markdown, browse tag FAQs, and look up user profiles via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://stackexchange.caseyjhand.com/mcp
Five tools for working with Stack Overflow and the wider Stack Exchange network:
| Tool | Description |
|---|---|
stackexchange_search_questions | Search questions across a Stack Exchange site with full-text query, tag filters, score threshold, and sort order |
stackexchange_get_thread | Fetch a complete Q&A thread — question body and all answers as clean markdown, accepted answer first |
stackexchange_get_tag_faq | Fetch the highest-voted answered questions for a tag — the canonical "best answers in X" list |
stackexchange_get_user | Fetch a user profile by ID: reputation, badge counts, top tags by answer score, and account metadata |
stackexchange_list_sites | Enumerate all Stack Exchange network sites and their api_site_parameter values |
stackexchange_search_questionsSearch questions across any Stack Exchange site.
stackexchange_get_threadstackexchange_get_threadFetch a complete Q&A thread in one call — the server's primary value-add.
Promise.all)<pre><code> → fenced code blocks, <p>, <a>, lists, headers, blockquotes all convertedmaxAnswers (default 10, up to 100)stackexchange_get_tag_faqBrowse the authoritative community answers on a topic.
/tags/{tag}/faq — the highest-voted answered questions in a tagstackexchange_get_thread for full contentstackexchange_get_userCredibility context for an answer author.
owner.user_id from stackexchange_get_thread output can be passed directlystackexchange_list_sitesDiscover api_site_parameter values for any Stack Exchange community.
api_site_parameter value (e.g. stackoverflow, superuser, serverfault) is what every other tool's site parameter acceptsBuilt on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1Stack Exchange-specific:
backoff field in SE API responses to avoid throttlingquota_remaining and quota_max surfaced via enrichment on every tool callinvalid_site, question_not_found, user_not_found, invalid_id_or_url, and quota_exceededget_thread and get_user via Promise.allSTACKEXCHANGE_API_KEY lifts the per-IP quota from ~300/day to ~10,000/day with no OAuth requiredAgent-friendly output:
not_found errors for missing questions and users (SE returns HTTP 200 with empty items[] — the server handles this correctly)A public instance is available at https://stackexchange.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"stackexchange-mcp-server": {
"type": "streamable-http",
"url": "https://stackexchange.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"stackexchange": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/stackexchange-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"stackexchange": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/stackexchange-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"stackexchange": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/stackexchange-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Rate limits: The Stack Exchange API allows ~300 requests/day per IP without a key. Set STACKEXCHANGE_API_KEY in env to lift this to ~10,000/day. Register a key at stackapps.com/apps/oauth/register (the OAuth flow is only required for write access — a key alone is sufficient for read-only use).
STACKEXCHANGE_API_KEY is optional but strongly recommended for any sustained usegit clone https://github.com/cyanheads/stackexchange-mcp-server.git
cd stackexchange-mcp-server
bun install
cp .env.example .env
# edit .env and set STACKEXCHANGE_API_KEY if desired
| Variable | Description | Default |
|---|---|---|
STACKEXCHANGE_API_KEY | Optional. Stack Exchange API key — lifts per-IP quota from ~300/day to ~10,000/day. | — |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_HTTP_HOST | Host for HTTP server. | 127.0.0.1 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t stackexchange-mcp-server .
docker run --rm -e STACKEXCHANGE_API_KEY=your-key -p 3010:3010 stackexchange-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/stackexchange-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Path | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and inits services. |
src/config/ | Server-specific environment variable parsing with Zod (STACKEXCHANGE_API_KEY). |
src/mcp-server/tools/ | Tool definitions (*.tool.ts). |
src/services/stackexchange/ | Stack Exchange API v2.3 HTTP client, backoff tracking, quota logging, HTML→markdown normalizer. |
tests/ | Vitest unit and integration tests. |
docs/ | Design document and directory tree. |
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/tools/definitions/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
STACKEXCHANGE_API_KEYStack Exchange API key — lifts per-IP quota from ~300/day to ~10,000/day. Register at https://stackapps.com/apps/oauth/register.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
csoai-org/pdf-document-mcp
xt765/mcp-document-converter
io.github.xjtlumedia/markdown-formatter
io.github.ai-aviate/better-notion
suekou/mcp-notion-server
meterlong/mcp-doc