Dreyyyyy/mcp-server
If you are the rightful owner of mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Model Context Protocol (MCP) server is a framework designed to facilitate communication between different machine learning models and applications, ensuring seamless integration and data exchange.
Battle School MCP Server with OAuth 2.1
A complete implementation of an MCP (Model Context Protocol) server with OAuth 2.1 authorization, built with TypeScript, Node.js, and Express. Inspired by Ender's Game's Battle School, this server demonstrates how to create authenticated MCP tools that Claude AI can securely access. All that work was done following Danila Loginov article and his repository, which can be found on the resources section.
🚀 Features
-
Full OAuth 2.1 Implementation
- Server metadata discovery (
/.well-known/oauth-authorization-server) - Dynamic client registration
- Authorization code flow
- JWT-based access tokens
- HTML authorization page
- Server metadata discovery (
-
MCP Protocol Support
- Streamable HTTP transport
- Tool listing and execution
- Protocol initialization and notifications
- User-specific authenticated tools
-
Battle School Demo Tools
get-student-info- Look up student details by IDget-my-info- Get authenticated user's profileget-my-army- View your army roster and statisticsget-opponent-army- Intelligence on opponent armies
-
Production Ready
- Dockerized with multi-stage builds
- TypeScript with strict typing
- CORS enabled for cross-origin requests
- Environment-based configuration
- In-memory data storage (easily replaceable with database)
📋 Prerequisites
- Node.js 20+
- Docker & Docker Compose (optional, for containerized deployment)
- ngrok or similar tunneling service (for Claude integration testing)
🛠️ Installation
1. Clone and Install Dependencies
git clone https://github.com/Dreyyyyy/mcp-server.git
cd mcp-server-test
npm install
2. Configure Environment
Copy .env.example to .env:
cp .env.example .env
Edit .env and set your values:
PORT=3000
NODE_ENV=development
ACCESS_TOKEN_SECRET=your-long-random-secret-key-here
TOKEN_EXPIRATION=1h
SERVER_URL=http://localhost:3000
🏃 Running Locally
Development Mode
npm run dev
Server will start on http://localhost:3000 with hot-reload enabled.
Production Build
npm run build
npm start
🐳 Docker Deployment
Build and Run
docker compose up --build
Run in Background
docker compose up -d
Stop
docker compose down
🧪 Testing the Server
1. Test Basic Endpoints
# Health check
curl http://localhost:3000/
# OAuth metadata
curl http://localhost:3000/.well-known/oauth-authorization-server
# MCP health
curl http://localhost:3000/mcp/health
2. Test OAuth Flow
Register a client:
curl -X POST http://localhost:3000/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "Test Client",
"redirect_uris": ["http://localhost:3000/callback"]
}'
Save the client_id from response.
Authorize (in browser):
http://localhost:3000/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/callback&response_type=code
- Enter student ID:
BS-2401(Ender Wiggin) orBS-2404(Petra Arkanian) - Click "Authorize Access"
- Copy the
codefrom redirect URL
Exchange code for token:
curl -X POST http://localhost:3000/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "YOUR_CODE",
"redirect_uri": "http://localhost:3000/callback",
"client_id": "YOUR_CLIENT_ID"
}'
Save the access_token.
3. Test MCP Tools
List available tools:
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'
Call a tool:
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get-my-info",
"arguments": {}
}
}'
🔗 Integrating with Claude
Claude requires a publicly accessible URL. Use ngrok for testing:
1. Install ngrok
# Linux/WSL
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update && sudo apt install ngrok
Or download from: https://ngrok.com/download
2. Configure ngrok
Sign up at https://dashboard.ngrok.com and get your auth token:
ngrok config add-authtoken YOUR_AUTH_TOKEN
3. Expose Local Server
ngrok http 3000
Copy the HTTPS URL (e.g., https://abc123.ngrok-free.app)
4. Update Configuration
Update your .env or docker-compose.yaml:
SERVER_URL=https://abc123.ngrok-free.app
Restart your server:
docker compose down
docker compose up
5. Add to Claude
- Open Claude → Settings → Integrations
- Click "Add integration"
- Name:
Battle School MCP - URL:
https://abc123.ngrok-free.app/mcp - Click "Connect"
- You'll be redirected to authorize
- Enter student ID (e.g.,
BS-2401) - Click "Authorize Access"
- Done! ✅
6. Test with Claude
Start a new conversation and try:
- "Show me my student profile"
- "What's my army roster?"
- "Get intelligence on Phoenix Army"
- "Look up student BS-2402"
Claude will use your MCP tools to respond with personalized data!
📁 Project Structure
mcp-server-test/
├── src/
│ ├── index.ts # Main Express server
│ ├── config.ts # Environment configuration
│ ├── interfaces/
│ │ └── index.ts # TypeScript interfaces
│ ├── data/
│ │ └── mock-data.ts # Mock Battle School data
│ ├── utils/
│ │ ├── oauth-storage.ts # In-memory OAuth state
│ │ └── token.ts # JWT utilities
│ ├── middleware/
│ │ └── auth.ts # Bearer token authentication
│ ├── routes/
│ │ ├── oauth.ts # OAuth 2.1 endpoints
│ │ └── mcp.ts # MCP protocol endpoints
│ └── mcp/
│ ├── server.ts # MCP tool definitions
│ └── tools.ts # Tool implementations
├── views/
│ └── authorize.html # OAuth authorization page
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yaml # Docker Compose config
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── .env.example # Environment template
└── README.md # This file
🔐 OAuth 2.1 Flow
┌─────────┐ ┌──────────────┐
│ Claude │ │ MCP Server │
└────┬────┘ └──────┬───────┘
│ │
│ 1. Discover OAuth metadata │
├───────────────────────────────────────────>│
│ GET /.well-known/oauth-authorization... │
│ │
│ 2. Register as client │
├───────────────────────────────────────────>│
│ POST /oauth/register │
│ │
│ 3. Redirect user to authorize │
├───────────────────────────────────────────>│
│ GET /oauth/authorize?client_id=... │
│ │
│ 4. User sees authorization page │
│ and enters credentials (BS-2401) │
│ │
│ 5. Authorization code issued │
│<───────────────────────────────────────────┤
│ Redirect with code parameter │
│ │
│ 6. Exchange code for access token │
├───────────────────────────────────────────>│
│ POST /oauth/token │
│ │
│ 7. Access token (JWT) returned │
│<───────────────────────────────────────────┤
│ │
│ 8. Use MCP tools with Bearer token │
├───────────────────────────────────────────>│
│ POST /mcp │
│ Authorization: Bearer <token> │
│ │
🛠️ Available MCP Tools
get-student-info
Get detailed information about any student by ID.
Parameters:
studentId(string, required): Student ID (e.g., "BS-2401")
Example:
{
"name": "get-student-info",
"arguments": {
"studentId": "BS-2401"
}
}
get-my-info
Get the authenticated user's own profile and statistics.
Parameters: None
get-my-army
Get information about the army commanded by the authenticated user.
Parameters: None
get-opponent-army
Get intelligence on an opponent army by ID.
Parameters:
armyId(string, required): Army ID (e.g., "dragon", "phoenix")
Example:
{
"name": "get-opponent-army",
"arguments": {
"armyId": "phoenix"
}
}
📝 Environment Variables
| Variable | Description | Default | Required |
|---|---|---|---|
PORT | Server port | 3000 | No |
NODE_ENV | Environment | development | No |
ACCESS_TOKEN_SECRET | JWT signing secret | dev-secret-key | Yes (production) |
TOKEN_EXPIRATION | Token validity | 1h | No |
SERVER_URL | Public server URL | http://localhost:3000 | Yes |
🚀 Deployment
Docker
See Docker Deployment section above.
🤝 Contributing
This is a learning project demonstrating MCP with OAuth.
- Use as a template for your own MCP servers
📚 Resources
- Model Context Protocol Documentation
- OAuth 2.1 Specification
- Anthropic MCP Documentation
- Original Article
📄 License
MIT License - feel free to use this project however you'd like!
🙏 Acknowledgments
- Inspired by the article "Build Remote MCP with Authorization" by Danila Loginov
- Battle School concept from Orson Scott Card's "Ender's Game"
Built with using TypeScript, Express, and MCP Protocol