entraid-mcp
by sedattavukcu
README.md
# Entra ID MCP Sunucusu
Microsoft Entra ID (Azure AD) hakkında salt-okunur bir
[Model Context Protocol](https://modelcontextprotocol.io) sunucusu.
[ArubaCentralMCP](https://github.com/sedattavukcu/aruba-central-mcp) /
[JamfMCP](https://github.com/sedattavukcu/jamf-pro-mcp) /
[DefenderCloudAppsMCP](https://github.com/sedattavukcu/defender-cloud-apps-mcp) /
[TeamsCallsMCP](https://github.com/sedattavukcu/teams-calls-mcp) /
[IntuneMCP](https://github.com/sedattavukcu/intune-mcp) ile aynı mimari
desenle yazılmıştır ve NetRadar Copilot Studio ajan ailesinin bir parçasıdır.
## Mimari
```mermaid
flowchart LR
A["MCP İstemcisi<br/>(Copilot Studio / Claude Code)"] -->|"HTTPS<br/>Authorization: Bearer <token>"| B["Caddy<br/>(aruba-mcp-vm üzerinde,<br/>altıncı site block'u)"]
B -->|"127.0.0.1:8425"| C["entraid-mcp.service<br/>Python / mcp.server.MCPServer"]
C -->|"OAuth2 client_credentials<br/>Bearer <access_token>"| D["Microsoft Graph API<br/>graph.microsoft.com<br/>/auditLogs/signIns, /users/{id}/memberOf, /subscribedSkus"]
```
**Barındırma:** Ayrı bir VM açılmadı — `aruba-mcp-vm` (Azure, `ArubaMCP`
resource group) üzerinde **altıncı bir systemd servisi**
(`entraid-mcp.service`, port `8425`) ve Caddy'de **altıncı bir site
block'u** (ayrı subdomain, ayrı bearer token) olarak çalışır. Dedike,
ayrıcalıksız `entraidmcp` sistem kullanıcısı altında.
## Kimlik Doğrulama
Microsoft Entra ID, Doğuş Grubu tenant'ı (`dogusgrubu.onmicrosoft.com`).
Ayrı bir Entra ID App Registration (`EntraIDMCP`), OAuth2
`client_credentials` akışı, 4 application permission (hepsi admin consent
almış):
| İzin | Neden |
|---|---|
| `AuditLog.Read.All` | Sign-in (oturum açma) logları |
| `Directory.Read.All` | Başka bir kullanıcının grup üyeliği (`/users/{id}/memberOf`) — Microsoft'un app-only erişimde sunduğu en dar seçenek budur, daha kısıtlı bir alternatif yok |
| `User.Read.All` | Temel kullanıcı profili + `assignedLicenses` alanı |
| `LicenseAssignment.Read.All` | `/subscribedSkus` (tenant lisans kataloğu) |
**Not — lisans bilgisi neden `/subscribedSkus` üzerinden geliyor:**
`/users/{id}/licenseDetails` uç noktası Microsoft Graph'ta **uygulama
(app-only) izniyle hiç desteklenmiyor**, yalnızca delegated (kullanıcı
oturumu) erişimle çalışıyor. Bu yüzden `get_user_licenses` tool'u, tenant'ın
SKU kataloğunu (`/subscribedSkus`, 1 saat önbelleklenir) kullanıcının
`assignedLicenses` alanıyla eşleştirerek çalışıyor — servis planı bazında
ayrıntı yok, yalnızca üst seviye SKU adı (örn. `ENTERPRISEPREMIUM`).
## Araçlar
| Tool | Açıklama |
|---|---|
| `list_signins_by_user` | Kullanıcının sign-in geçmişi — başarı/hata, Conditional Access sonucu, cihaz/uygulama, IP + şehir/ülke (yalnızca şehir/ülke düzeyinde — geoCoordinates hiç döndürülmez) |
| `get_user_groups` | Kullanıcının doğrudan grup/rol üyelikleri (transitif değil) |
| `get_user_licenses` | Kullanıcıya atanmış Microsoft 365 lisansları (üst seviye SKU adı) |
## Gizlilik / Kapsam Notları
- Sign-in loglarında hassas `geoCoordinates` (enlem/boylam) alanı bilinçli
olarak hiç döndürülmez — yalnızca şehir/ülke düzeyi tutulur.
- Risk alanları (`riskLevelDuringSignIn`, `riskDetail`) yalnızca Entra ID P2
lisansında dolu gelir; P1/Free'de Graph "hidden" döndürür.
- Yazma/aksiyon işlemi (parola sıfırlama, hesap kilitleme, grup üyeliği
değiştirme, sign-in riskli/güvenli işaretleme vb.) hiç içermez.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing