Deploys the MCP server as a publicly accessible HTTP service on Render's EU region (Frankfurt) for integration with Claude Desktop
Uses Supabase as a caching layer and local database for storing 1.85M Swedish company records, company details cache (30-day TTL), document lists cache (7-day TTL), financial reports, and API request logs
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Personupplysning MCP Serversearch for companies named 'Spotify' and show me their financial details"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Personupplysning MCP Server
MCP server för svensk företags- och persondata via Bolagsverket API och Supabase cache
Ett HTTP MCP-server som tillhandahåller sökfunktioner för svenska företag och hämtar detaljerad finansiell data från Bolagsverket, med lokal cache i Supabase för snabbare svar.
🚀 Features
Företagssökning - Sök bland 1.85M svenska företag i lokal databas
Företagsdetaljer - Hämta fullständig företagsinformation från Bolagsverket
Årsredovisningar - Ladda ner och parsera iXBRL årsredovisningar
Smart caching - Supabase cache-first strategi (30 dagar företagsdata, 7 dagar dokument)
HTTP MCP Server - Publikt tillgänglig via Render deployment
Local development - Stdio mode för lokal utveckling
📋 MCP Tools
Tool | Description | Cache |
| Sök företag lokalt (1.85M) | Lokal DB |
| Hämta företagsinfo | 30 dagar |
| Lista årsredovisningar | 7 dagar |
| Hämta iXBRL årsredovisning | Permanent |
| Cache-statistik | - |
🏗️ Architecture
┌─────────────┐ ┌──────────────┐
│ Claude │ ◄─────► │ HTTP MCP │
│ Desktop │ SSE │ Server │
└─────────────┘ │ (Render) │
└──────┬───────┘
│
┌──────┴───────┐
│ │
┌────▼────┐ ┌─────▼────┐
│Supabase │ │Bolagsver-│
│ Cache │ │ket API │
└─────────┘ └──────────┘🛠️ Installation
Prerequisites
Node.js 18+ och npm
Supabase project (gratis tier fungerar)
Bolagsverket API credentials (portal.api.bolagsverket.se)
Local Development
Clone repository:
git clone <repo-url>
cd personupplysningInstall dependencies:
npm installSetup environment:
cp .env.example .env
# Edit .env with your credentialsSetup database:
npm run db:setupImport company data (optional):
npm run db:importRun in stdio mode (local):
npm run dev🌐 Render Deployment
Deploy to Render
Push to GitHub:
git init
git add .
git commit -m "Initial commit"
git remote add origin <your-github-repo>
git push -u origin mainCreate Render service:
Go to dashboard.render.com
Click "New +" → "Web Service"
Connect your GitHub repository
Render will detect
render.yamlautomatically
Configure environment variables:
Add these in Render dashboard (Environment):
NODE_ENV=production
MCP_TRANSPORT=http
SUPABASE_URL=<your-supabase-url>
SUPABASE_SERVICE_ROLE_KEY=<your-service-role-key>
BOLAGSVERKET_CLIENT_ID=<your-client-id>
BOLAGSVERKET_CLIENT_SECRET=<your-client-secret>Deploy:
Render will automatically build and deploy
Your MCP server will be available at:
https://personupplysning-mcp.onrender.com/mcp
Connect from Claude Desktop
Add to your Claude Desktop MCP config (claude_desktop_config.json):
{
"mcpServers": {
"personupplysning": {
"type": "sse",
"url": "https://personupplysning-mcp.onrender.com/sse"
}
}
}Note: The server uses SSE (Server-Sent Events) transport with two endpoints:
GET /sse- Establishes SSE connectionPOST /messages?sessionId=<id>- Sends JSON-RPC messages
📁 Project Structure
personupplysning/
├── src/
│ ├── index.ts # HTTP/stdio MCP server
│ ├── clients/
│ │ ├── bolagsverket-api.ts # Bolagsverket API client
│ │ └── __tests__/ # API client tests
│ └── services/
│ └── company-data-service.ts # Cache-first service layer
├── scripts/
│ ├── setup-supabase.ts # Database setup
│ ├── import-parquet.ts # Import 1.85M companies
│ ├── download-annual-report.ts # Example script
│ ├── check-tables.ts # Utility: Check tables
│ ├── verify-import.ts # Utility: Verify imports
│ └── schema.sql # Database schema
├── sql/
│ ├── 002-create-cache-tables.sql # Cache tables migration
│ └── 003-create-storage-bucket.sql # Storage setup
├── tests/
│ └── test-supabase.ts # Supabase connection test
├── docs/
│ └── CACHING-ARCHITECTURE.md # Architecture documentation
├── render.yaml # Render deployment config
├── .env.example # Environment template
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies🔧 Configuration
Environment Variables
Variable | Description | Required |
| Environment ( | Yes |
| Transport mode ( | Yes |
| HTTP server port (default: 3000) | HTTP only |
| Bind address (default: 0.0.0.0) | HTTP only |
| Supabase project URL | Yes |
| Supabase service role key | Yes |
| Bolagsverket OAuth2 client ID | Yes |
| Bolagsverket OAuth2 client secret | Yes |
Cache TTL Configuration
Cache expiration kan konfigureras i src/services/company-data-service.ts:
this.cacheTTL = 30 * 24 * 60 * 60 * 1000; // 30 days company details
this.documentCacheTTL = 7 * 24 * 60 * 60 * 1000; // 7 days document lists📊 Database Schema
Tables
companies- 1.85M svenska företag (lokal kopia)company_details_cache- API-svar från Bolagsverket (30 dagar TTL)company_documents_cache- Dokumentlistor (7 dagar TTL)financial_reports- Parsad finansiell data från iXBRLapi_request_log- Request logging och analytics
Storage
company-documentsbucket - Lagrar nedladdade iXBRL ZIP-filer
🧪 Testing
Run tests:
npm testTest specific file:
npm test -- bolagsverket-api.test.tsTest API connection:
npx tsx scripts/download-annual-report.ts📝 Development Scripts
Script | Description |
| Compile TypeScript → |
| Run in stdio mode (local) |
| Run compiled JS (production) |
| Run test suite |
| Setup Supabase schema |
| Import 1.85M companies |
🔒 Security
OAuth2 tokens cached with 1-minute safety buffer before expiry
Service role key required for Supabase (never expose publicly)
API credentials stored in environment variables only
GDPR compliance - EU Render region (Frankfurt)
No personal data persisted without consent
📈 Performance
Cache hit rate: ~95% after warm-up
Local search: < 100ms (Supabase full-text search)
Cached company details: < 50ms
Fresh API call: 1-3 seconds (Bolagsverket rate limits)
iXBRL download: 2-5 seconds (depends on file size)
🐛 Troubleshooting
Health Check Fails
Check endpoint:
curl https://personupplysning-mcp.onrender.com/healthExpected response:
{
"status": "healthy",
"server": "personupplysning-mcp",
"version": "0.1.0",
"uptime": 123.45,
"endpoint": "/mcp",
"environment": {
"SUPABASE_URL": "configured",
"BOLAGSVERKET_CLIENT_ID": "configured"
}
}MCP Connection Issues
Check Render logs for startup errors
Verify all environment variables are set
Test health endpoint first
Check Claude Desktop logs (
~/Library/Logs/Claude/)
Database Connection Failed
# Test Supabase connection
npx tsx tests/test-supabase.tsBolagsverket API 401/403
Verify credentials in Render environment
Check token expiry (should auto-refresh)
Ensure OAuth2 scope:
vardefulla-datamangder:ping vardefulla-datamangder:read
📜 License
MIT
🤝 Contributing
Contributions welcome! Please follow these steps:
Fork the repository
Create feature branch (
git checkout -b feature/amazing-feature)Commit changes (
git commit -m 'Add amazing feature')Push to branch (
git push origin feature/amazing-feature)Open Pull Request
📧 Support
For issues or questions:
Open a GitHub issue
Check existing issues first
Built with: TypeScript, MCP SDK, Supabase, Bolagsverket API Deployed on: Render (EU region - Frankfurt)