Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM node:24-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY tsconfig.json ./

# Install all dependencies (including dev dependencies for build)
# Use --ignore-scripts to skip the prepare hook (which runs build) until source files are copied
RUN npm install --ignore-scripts --legacy-peer-deps

# Copy source files
COPY . .

# Build TypeScript
RUN npm run build

# Remove dev dependencies after build to reduce image size
RUN npm prune --omit=dev --legacy-peer-deps

# Set environment variables
ENV NODE_ENV=production
ENV PORT=3008

# Expose port
EXPOSE 3008

# Run the server (automatically uses HTTP transport if PORT is set, otherwise stdio)
CMD ["node", "build/index.js"]
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Stackoverflow MCP Server
# Stack Overflow MCP Server

A Model Context Protocol server for querying Stack Overflow. This server helps AI models find solutions to programming problems by searching Stack Overflow questions and answers.

Expand All @@ -10,6 +10,13 @@ A Model Context Protocol server for querying Stack Overflow. This server helps A
- Filter results by score/votes
- Include question and answer comments
- Output in JSON or Markdown format
- Supports both stdio and HTTP (streamable-http) transport modes
- Automatic rate limiting with backoff handling
- API quota monitoring
- Structured logging with Pino
- Graceful shutdown handling
- Health check endpoint (`/health`)
- Session management for HTTP transport

## Installation

Expand Down Expand Up @@ -52,10 +59,15 @@ Add the following configuration:

### Optional: Stack Overflow API Authentication

The server works without authentication but has rate limits. To increase the rate limits:
The server works without authentication but has rate limits (10,000 requests/day shared quota). To increase the rate limits:

1. Get an API key from [Stack Apps](https://stackapps.com/apps/oauth/register)
2. Add the API key to your MCP settings configuration
2. Add the API key to your MCP settings configuration or set `STACKOVERFLOW_API_KEY` environment variable

With an API key, you get:
- 10,000 requests/day per user/app pair (instead of shared IP quota)
- Higher rate limits (30 requests/second)
- Better quota management

## Usage

Expand Down Expand Up @@ -174,6 +186,27 @@ The markdown format provides a nicely formatted view with:
- Answer comments (if requested)
- Links to the original posts

## Transport Modes

The server supports two transport modes:

- **stdio** (default): Standard input/output transport for direct process communication
- **HTTP** (streamable-http): HTTP-based transport for Docker/containerized deployments

HTTP mode is automatically enabled when the `PORT` environment variable is set. The server will listen on the specified port and expose:
- `POST /mcp` - Main MCP endpoint for tool calls and session initialization
- `GET /mcp` - SSE stream endpoint for streaming responses (requires session ID)
- `DELETE /mcp` - Session termination endpoint
- `GET /health` - Health check endpoint with service status and active session count

## Rate Limiting

The server implements intelligent rate limiting:
- **25 requests/second** (safety margin below API's 30/sec limit)
- **Method-specific backoff** - respects API `backoff` field in responses
- **Quota monitoring** - warns when quota drops below 100 requests
- **Automatic retry** - exponential backoff on 429 errors

## Development

1. Build in watch mode:
Expand All @@ -186,6 +219,11 @@ npm run watch
npm test
```

3. Test HTTP mode locally:
```bash
PORT=3008 npm run build && node build/index.js
```

## Contributing

1. Fork the repository
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default {
],
},
testEnvironment: "node",
testMatch: ["**/src/__tests__/**/*.test.ts"],
collectCoverageFrom: ["src/**/*.ts"],
coveragePathIgnorePatterns: ["/node_modules/", "__tests__"],
globals: {
Expand Down
Loading