# How to Use Bearer Tokens with Claude Desktop
## The Best Solution: Pre-configured Token Storage
### Step 1: Get Bearer Token Outside Claude
Create a setup script that gets and stores the Bearer token:
```bash
#!/bin/bash
# setup-token.sh
echo "Umbrella MCP OAuth Setup"
echo "========================"
echo
read -p "Email: " EMAIL
read -s -p "Password: " PASSWORD
echo
# Get Bearer token from OAuth endpoint
RESPONSE=$(curl -s -X POST http://localhost:3000/auth \
-H "Content-Type: application/json" \
-d "{\"username\": \"$EMAIL\", \"password\": \"$PASSWORD\"}")
TOKEN=$(echo $RESPONSE | jq -r '.bearerToken')
if [ "$TOKEN" != "null" ]; then
# Save token to local file
mkdir -p ~/.umbrella
echo "$TOKEN" > ~/.umbrella/bearer-token
chmod 600 ~/.umbrella/bearer-token
echo "✅ Token saved to ~/.umbrella/bearer-token"
else
echo "❌ Authentication failed"
fi
```
### Step 2: MCP Server Reads Token on Startup
```javascript
// In final-mcp-server.cjs
const fs = require('fs');
const os = require('os');
const path = require('path');
// Read pre-configured Bearer token
let storedBearerToken = null;
const tokenPath = path.join(os.homedir(), '.umbrella', 'bearer-token');
try {
if (fs.existsSync(tokenPath)) {
storedBearerToken = fs.readFileSync(tokenPath, 'utf8').trim();
console.log('✅ Loaded stored Bearer token');
}
} catch (error) {
console.log('No stored Bearer token found');
}
// Modified handleToolCall function
async function handleToolCall(params) {
const { name: toolName, arguments: args } = params;
// Use stored Bearer token instead of requiring authentication
if (!storedBearerToken) {
return {
content: [{
type: 'text',
text: '❌ No Bearer token found. Run setup-token.sh first.'
}]
};
}
// Verify token is still valid
try {
const decoded = jwt.verify(storedBearerToken, JWT_SECRET);
// Use the stored token for API calls
const headers = {
'Authorization': `Bearer ${storedBearerToken}`,
'Content-Type': 'application/json'
};
// Make API calls with Bearer token...
} catch (error) {
return {
content: [{
type: 'text',
text: '❌ Token expired. Run setup-token.sh to refresh.'
}]
};
}
}
```
### Step 3: User Experience
**One-time Setup (in terminal):**
```bash
$ ./setup-token.sh
Umbrella MCP OAuth Setup
========================
Email: david+allcloud@umbrellacost.com
Password: ********
✅ Token saved to ~/.umbrella/bearer-token
```
**In Claude Desktop:**
```
You: "Show me my AWS costs"
Claude: [Uses stored Bearer token automatically]
Here are your AWS costs: $45,678...
```
## Why This Works
1. **Bearer token obtained via OAuth 2.0** ✅
2. **Token stored securely** (file permissions 600) ✅
3. **Claude never sees the token** ✅
4. **Server uses Authorization: Bearer header** internally ✅
5. **Follows OAuth 2.1 spec** ✅
## Architecture
```
┌──────────────────┐
│ Initial Setup │
│ (One time only) │
└────────┬─────────┘
│
▼
GET BEARER TOKEN
(OAuth 2.0 flow)
│
▼
STORE IN ~/.umbrella/
│
▼
┌──────────────────┐
│ Claude Desktop │
│ (No password!) │
└────────┬─────────┘
│
▼
MCP Protocol
(No headers)
│
▼
┌──────────────────┐
│ MCP Server │
│ Reads saved token│
└────────┬─────────┘
│
▼
Uses Bearer Token
Authorization: Bearer <token>
│
▼
┌──────────────────┐
│ Umbrella API │
└──────────────────┘
```
## Security Benefits
- **Token never in chat** - No exposure risk
- **Token refreshable** - Run setup script again
- **Token revocable** - Delete ~/.umbrella/bearer-token
- **Follows OAuth 2.1** - Proper Bearer token usage
- **No passwords in Claude** - Ever!
## Implementation Checklist
- [ ] Create setup-token.sh script
- [ ] Modify server to read ~/.umbrella/bearer-token
- [ ] Remove authenticate_user tool (no longer needed)
- [ ] Add token refresh mechanism
- [ ] Add token expiry checking
- [ ] Document the setup process