ms-365-mcp-server
ms-365-mcp-server
Microsoft 365 MCP 서버
Microsoft 365 및 Microsoft Office 서비스와 Graph API를 통해 상호작용하기 위한 MCP(Model Context Protocol) 서버입니다.
참고: 이것은 A-Impact의 내부 빌드이며 npm에 공개되어 있지 않습니다. 아래의
npx @a-impact/ms365-mcp명령은 해당 스코프로 패키지를 직접 게시한 경우에만 적용됩니다. 이 저장소에서 바로 실행하려면npm install && npm run build를 사용하고 MCP 클라이언트가dist/index.js를 가리키게 하십시오. 자세한 내용은 로컬 개발을 참조하세요.
지원되는 클라우드
이 서버는 여러 Microsoft 클라우드 환경을 지원합니다:
클라우드 | 설명 | 인증 엔드포인트 | Graph API 엔드포인트 |
글로벌 (기본) | 국제 Microsoft 365 | login.microsoftonline.com | graph.microsoft.com |
중국 (21Vianet) | 21Vianet이 운영하는 Microsoft 365 | login.chinacloudapi.cn | microsoftgraph.chinacloudapi.cn |
Related MCP server: Microsoft Graph MCP Server
전제 조건
Node.js >= 20 (권장)
Node.js 14+ 이상은 의존성 경고와 함께 작동할 수 있습니다.
주요 기능
Microsoft 인증 라이브러리(MSAL)를 통한 인증
포괄적인 Microsoft 365 서비스 통합
안전한 작업을 위한 읽기 전용 모드 지원
세부적인 접근 제어를 위한 도구 필터링
출력 형식: JSON 대 TOON
이 서버는 전역적으로 구성할 수 있는 두 가지 출력 형식을 지원합니다:
JSON 형식 (기본값)
보기 좋게 출력되는 표준 JSON 형식:
{
"value": [
{
"id": "1",
"displayName": "Alice Johnson",
"mail": "alice@example.com",
"jobTitle": "Software Engineer"
}
]
}(실험적) TOON 형식
효율적인 LLM 토큰 사용을 위한 Token-Oriented Object Notation:
value[1]{id,displayName,mail,jobTitle}:
"1",Alice Johnson,alice@example.com,Software Engineer장점:
JSON보다 토큰을 30~60% 절약
균일한 배열 데이터(이메일 목록, 일정 이벤트, 파일 등)에 가장 적합
대규모 및 비용에 민감한 애플리케이션에 이상적
사용 방법: (실험적) TOON 형식을 전역으로 활성화:
CLI 플래그 사용:
npx @a-impact/ms365-mcp --toonClaude Desktop 구성 파일에서:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--toon"]
}
}
}환경 변수 사용:
MS365_MCP_OUTPUT_FORMAT=toon npx @a-impact/ms365-mcp지원되는 서비스 및 도구
이 서버는 Microsoft Graph API 대부분을 포괄하는 300개 이상의 도구를 제공합니다. 각 도구는 Graph API 엔드포인트와 1:1로 매핑되며, src/endpoints.json에서 선언적으로 정의됩니다.
개인 계정 도구 (기본 제공)
이메일(Outlook), 일정(Calendar), OneDrive 파일, Excel, OneNote, 할 일(To Do Tasks), Planner, 연락처, 사용자 프로필, 검색
조직 계정 도구 (--org-mode 플래그 필요)
Teams 및 채팅, 온라인 회의, 기록 및 녹화(Transcripts & Recordings), 출석 보고서, SharePoint 사이트 및 목록, 공유 사서함 및 일정, 사용자 관리, 현재 상태, 가상 이벤트
Graph API의 인증 권한
권한은 활성화된 도구에 따라 동적으로 요청됩니다. --list-permissions를 사용하면 귀하의 구성에 필요한 정확한 권한을 확인할 수 있습니다:
# Personal mode (default)
npx @a-impact/ms365-mcp --list-permissions
# Organization mode (includes Teams, SharePoint, etc.)
npx @a-impact/ms365-mcp --org-mode --list-permissions
# Filtered by preset
npx @a-impact/ms365-mcp --preset mail --list-permissions이 기능은 Graph API 권한이 새 버전을 배포하기 전에 사전 승인되고 관리자 동의를 받아야 하는 엔터프라이즈 환경에 유용합니다.
--st-permissions JSON에는 다음이 포함됩니다:
toolPermissions:--allowed-scopes필터링 전에 도구 surface에서다음에 필요한 권한effectivePermissions:--allowed-scopes이후에도 남아 활성화된 도구가 암시하는 권한permissions: 기존 스크립트와의 호환성을 위해 유지되는effectivePermissions용 기존 별칭allowedScopes: 구성된 사용 범위 허용 목록 (제공된 경우)disabledTools: 필요한 Graph 범위가allowedScopes로 적용되지 않아 숨겨진 도구missingAllowedScopesForTools: 비활성화된 도구에서 누락된 고유 범위extraAllowedScopesNotUsedByTools: 현재 도구가 abs 사용하지 않는 허용 범위
허용 범위
기본적으로 MSAL은 활성화된 도구가 필요로 하는 범위를 요청하며, 도구 구성은 --enabled-tools, --preset, --org-mode 및 --read-only에 의해 제어됩니다.
엔터프라이즈 및 무인(unattended) 배포는 --allowed-scopes 또는 MS365_MCP_ALLOWED_SCOPES로 범위 지정을 할 수 있습니다. 구성된 경우 서버는 먼저 일반 도구 노출 영역을 계산한 다음, 기본 범위가 허용 목록에 포함되지 않는 Graph 도구를 숨깁니다. OAuth 메타데이터와 로그인 흐름은 활성 상태로남은 도구들의 유효 권한만 요청합니다.
npx @a-impact/ms365-mcp \
--org-mode \
--enabled-tools '^(list-mail-messages|get-mail-message|list-drives|get-drive-item|download-bytes)$' \
--allowed-scopes 'User.Read Mail.Read Files.Read'CLI 값이 MS365_MCP_ALLOWED_SCOPES보다 우선합니다. 둘 다 설정하지 않으면 기본 동작인 도구 파생 범위가 그대로 유지됩니다. 빈 값을 제공하면 시작시 실패하여 배포가 실수로 더 넓은 도구 영역으로 전환하는 일이 없습니다.
범위 적용은 계층 구조를 인식합니다. 예를 들어 Mail.ReadWrite는 Mail.Read를 요구하는 도구를 포함하고, Files.ReadWrite.All는 Files.Read를 요구하는 도구를 포함합니다.
SharePoint는 두 가지 엔터프라이즈 권한 모델을 지원합니다:
테넌트 전체 범위 (예:
Sites.Read.All,Sites.ReadWrite.All,Sites.Manage.All).Microsoft Graph
Sites.Selected와 같은 범위는 특정 사이트 모음에서 앱에 SharePoint 사이트 액세스 권한을 부여하고, Graph는 요청 시 사용자 자신의 권한을 평가합니다.
기본 조직 모드 동작은 기존 배포에서 사용해 온 광범위 포괄 SharePoint 범위를 계속 요청합니다. 선택한 사이트 SharePoint 액세스를 원하는 엔터프라이즈는 광범위한 Sites.*.All 범위 대신 Sites.Selected를 포함한 허용 목록을 설정할 수 있습니다. 명확한 SharePoint 사이트를 대상으로 하는 직접 사이트/목록/항목 도구는 Sites.Selected로도 실행할 수 있으며, 테넌트 전체 SharePoint 검색 및 검색 도구에는 여전히 광범위한 SharePoint 범위가 필요합니다.
npx @a-impact/ms365-mcp \
--org-mode \
--read-only \
--enabled-tools 'sharepoint|site|drive|planner' \
--allowed-scopes 'User.Read Files.Read Notes.Read Tasks.Read Sites.Selected'HTTP 모드에서는 OAuth 검색이 유효한 필터링된 권한을 광범위하게 알려 클라이언트가 동일한 동의 범위를 요청하도록 합니다. On-Behalf-Of 모드(--obo)는 보호된 리소스 메타데이터에 api://<clientId>/access_as_user를 계속 광고합니다. --allowed-scopes는 OBO를 무시하지 않습니다.
추가 범위 요청
--allowed-scopes는 항상 토큰 요청을 좁힙니다(narrows). 번들 도구가 필요로 하지 않는 Graph 범위를 요청하려면(예: graph-batch로 엔드포인트를 구동하는 경우) --extra-scopes(또는 MS365_MCP_EXTRA_SCOPES)을 사용합니다. 이 범위는 도구에서 파생된 범위 위에 토큰 요청에 원본 그대로 추가됩니다.
npx @a-impact/ms365-mcp \
--org-mode \
--extra-scopes 'CopilotPackages.ReadWrite.All'이 옵션은 사용자의 Azure 앱 등록(MS365_MCP_CLIENT_ID / MS365_MCP_CLIENT_SECRET)과 함께 사용하도록 설계되었습니다. 기본 업스트림 앱은 소량의 고정 권한 집합만 선언하므로, 추가 범위는 사용자가 제어하는 앱에 대해 요청하십시오(테넌트 관리자가 해당 앱에서 직접 동의합니다). CLI 값이 환경 변수보다 우선하며, 빈 값은 시작시 실패합니다.
조직/직장 모드
직장/학교 기능(Teams, SharePoint 등)에 접근하려면 다음 플래그 중 하나로 조직 모드를 활용하십시오:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode"]
}
}
}직장 계정 터 사용 기능에 접근하려면 조직 모드를 처음부터 활성화해야 합니다. 이 플래그가 없으면 사용자 모드 계정 기능(이메일, 일정, OneDrive 등)만 사용할 수 있습니다.
공유 사물함 액세스
공유 사서함에 액세스하려면 다음이 필요합니다:
조직 모드: 공유 사서함 도구는
--org-mode플래그가 필요합니다(직장/학교 계정만 해당).위임된 사용 권한: 읽기에는
Mail.Read.Shared, 메시지 만들기/업데이트/이동에는Mail.ReadWrite.Shared, 보내기/회신/전달에는Mail.Send.Shared, 공유 일정 도구는Calendars.Read.Shared.Exchange 권한: 로그인한 사용자는 공유 사서함에 액세스 권한이 부여되어야 합니다.
사용 방법: 공유 사서함 도구에서
user-id매개변수에 공유 사서함의 전자메일 주소를 사용합니다.
공유 메일 찾기: list-users 도구를 사용해 조직에서 사용할 수 있는 사용자와 공유 사서함을 검색하세요.
예: list-shared-mailbox-messages와 함께 user-id를 shared-mailbox@company.com으로 설정
시작 예제
Claude Desktop에서 로그인 테스트:
예시
통합
Claude Desktop
Claude Desktop에 이 MCP 서버를 추가하려면 설정(Settings) > 개발자(Developer) 의 구성 파일을 편집하십시오.
개인 계정 (MSA)
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp"]
}
}
}직장/학교 계정 (글로벌)
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode"]
}
}
}직장/학교 계정 (중국 21Vianet)
{
"mcpServers": {
"ms365-china": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode", "--cloud", "china"]
}
}
}Claude Code CLI
개인 계정 (MSA)
claude mcp add ms365 -- npx -y @a-impact/ms365-mcp직장/학교 계정 (글로벌)
# macOS/Linux
claude mcp add ms365 -- npx -y @a-impact/ms365-mcp --org-mode
# Windows (use cmd /c wrapper)
claude mcp add ms365 -s user -- cmd /c "npx -y @a-impact/ms365-mcp --org-mode"직장/학교 계정 (중국 21Vianet)
# macOS/Linux
claude mcp add ms365-china -- npx -y @a-impact/ms365-mcp --org-mode --cloud china
# Windows (use cmd /c wrapper)
claude mcp add ms365-china -s user -- cmd /c "npx -y @a-impact/ms365-mcp --org-mode --cloud china"MCP를 지원하는 다른 인터페이스에 대해서는 각 문서의 특정 통합 방법을 참조하세요.
Open WebUI
Open WebUI는 OAuth 2.1을 통한 HTTP 전송 방식의 MCP 서버를 지원합니다.
HTTP 모드로 서버를 시작합니다:
npx @a-impact/ms365-mcp --httpOpen WebUI에서 Admin Settings → Tools (
/admin/settings/tools) → Add Connection 이동합니다:Type: MCP Streamable HTTP
URL:
/mcp경로에 있는 MCP 서버 URLAuth: OAuth 2.1
Register Client 클릭합니다.
참고: HTTP 모드에서는 동적 클라이언트 등록이 기본적으로 활성화되어 있습니다. 비활성화하려면
--no-dynamic-registration(또는MS365_MCP_DISABLE_DCR=true)을 사용하세요. 사용자 지정 Azure Entra 앱을 사용하는 경우 리디렉트 URI의 앱 플랫폼 유형은 앱에 클라이언트 암호 유무에 따라 다릅니다. 암호가 있으면 "Web"을, 없으면 "Mobile and desktop applications"을 사용하세요. ("Single-page application"은 사용하지 마세요.)
간편 테스트 구성 — 기본 Azure 앱 사용 (ID ms-365와 localhost:8080은 함께 미리 구성됨):
docker run -d -p 8080:8080 \
-e WEBUI_AUTH=false \
-e OPENAI_API_KEY \
ghcr.io/open-webui/open-webui:main
npx @a-impact/ms365-mcp --http그런 다음 URL http://localhost:3000/mcp, ID ms-365로 연결을 추가하세요.
Docker에서 리버스 프록시를 사용 중이십니까?
--public-url https://your-domain.com을 설정하여 사용자 브라우저에서 OAuth 인증 URL에 접근할 수 있도록 하십시오. 전체 가이드는 docs/deployment.md를 참고하세요.
로컬 개발
로컬 개발 또는 테스트를 위해:
# From the project directory
claude mcp add ms -- npx tsx src/index.ts --org-mode또는 Claude Desktop 수동 구성:
{
"mcpServers": {
"ms365": {
"command": "node",
"args": ["/absolute/path/to/ms-365-mcp-server/dist/index.js", "--org-mode"]
}
}
}참고: 코드 변경 후
dist/폴더를 업데이트하려면npm run build를 실행하세요.
###인증
⚠️ 도구를 사용하려먼 먼저 인증을 수행해야 합니다.
서버는 세 가지 인증 방법을 지원합니다:
1. 장치 코드 흐름 (기본)
장치 코드를 통한 대화형 인증:
MCP 클라이언트 로그인:
login도구 호출 (전 기존 토큰 자동 확인)필요한 경우 URL+코드를 받고 브라우저에서 방문
verify-login도구를 사용하여 확인
CLI 로그인:
npx @a-impact/ms365-mcp --login터미널에 표시된 URL과 코드를 따라가십시오.
토큰은 OS 자격 증명 저장소에 안전하게 캐시됩니다(없는 경우 파일 저장).
OAuth 인증 코드 흐름 (HTTP 모드 전용)
--http로 실행하면 서버가 OAuth 인증을 필수로 요구합니다:
npx @a-impact/ms365-mcp --http 3000이 모드는:
MCP 클라이언트에게 OAuth 기능을 공지
/auth/*(authorize, token, metadata) 엔드포인트 제공모든 MCP 요청에
Authorization: Bearer <token>필수Microsoft Graph API로 토큰 유효성 검증
기본적으로 로그인/로그아웃 도구를 비활성화 (활성화하려면
--enable-auth-tools사용)
MCP 클라이언트가 공지된 기능을 확인하면 OAuth 흐름이 자동으로 처리됩니다.
OAuth 테스트를위한 Azure AD 구성
OAuth 모드를 자체 Azure 자격을 사용하려면 (프로덕션 권장) Azure AD 앱 등록을 설정해야 합니다:
Azure AD 앱 등록 만들기:
Azure 포털로 이동
Azure Active Directory → App registrations → New registration로 이동
이름 설정: "MS300 MCP Server"
리디렉트 URI 구성:
OAuth 콜백 URI 구성: 앱 등록 페이지로 이동하고 왼쪽에서 Authentication(인증)으로 갑니다.
플랫폼 구성에서:
플랫폼 추가를 클릭합니다("Mobile and desktop applications" / "Public client"이 이미 보이지 않는 경우).
"Mobile and desktop applications" 또는 "Public client/native (mobile & desktop)"을 선택합니다(레이블은 포털 버전에 따라 다름).
MCP Inspector로 테스트(
npm run inspector):
앱 등록 페이지로 이동하고 왼쪽에서 Authentication(인증)으로 갑니다.
플랫폼 구성에서:
플랫폼 추가를 클릭합니다("Web"이 이미 보이지 않는 경우).
Web을 선택합니다.
다음 리디렉션 URI를 구성합니다.
http://localhost:6274/oauth/callbackhttp://localhost:6274/oauth/callback/debughttp://localhost:3000/callback(선택 사항, 서버 콜백용)
자격 증명 가져오기:
개요 페이지에서 Application (client) ID를 복사합니다.
Certificates & secrets → 새 클라이언트 암호(New client secret) → 암호 값을 복사합니다(공용 앱에서는 선택 사항).
환경 변수 구성: 프로젝트 루트에
.env파일을 만듭니다.MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here MS365_MCP_CLIENT_SECRET=your-secret-here # Optional for public apps MS365_MCP_TENANT_ID=common
이렇게 구성하면 서버는 기본 제공 앱 대신 사용자 지정 Azure 앱을 사용합니다.
참고:
.env는 서버가 시작된 디렉터리에서 읽으며, 그 디렉터리는 MCP 클라이언트가 결정합니다. 읽히는 변수는MS365_MCP_CLIENT_ID,MS365_MCP_CLIENT_SECRET,MS365_MCP_TENANT_ID및MS365_MCP_CLOUD_TYPE뿐입니다. 위에 나열된 다른 모든 변수는 셸 또는 MCP 클라이언트 구성에 설정해야 하며,.env에서 발견된 그 외의 값은 스터디 출력에 경고를 내보내고 무시됩니다.
3. Bring Your Own Token (BYOT)
Microsoft OAuth 토큰을 외부에서 관리하는 더 큰 시스템의 일부로 ms-365-mcp-server를 실행하는 경우, 액세스 토큰을 이 MCP 서버에 직접 제공할 수 있습니다.
MS365_MCP_OAUTH_TOKEN=your_oauth_token npx @a-impact/ms365-mcp이 방법은:
대화형 인증 흐름을 건너뜁니다.
Microsoft Graph API 요청에 기존 OAuth 토큰을 사용합니다.
토큰 새로 고침은 처리하지 않습니다(토큰 수명 주기 관리는 사용자 책임).
참고: HTTP 모드에서는 인증이 필요합니다. 인증 없이 테스트하려면 장치 코드 흐름과 함께 stdio 모드를 사용하세요.
인증 도구: HTTP 모드에서는 OAuth가 인증을 처리하므로 로그인/로그아웃 도구가 기본적으로 비활성화됩니다. 필요하면
--enable-auth-tools를 사용하세요.
다중 계정 지원
단일 서버 인스턴스로 여러 Microsoft 계정을 처리할 수 있습니다. 계정이 둘 이상 로그인되어 있으면 모든 도구에 account 매개변수가 자동으로 추가되어, 호출별로 사용할 계정을 지정할 수 있습니다.
여러 계정 로그인(계정마다 한 번):
# Login first account (device code flow)
npx @a-impact/ms365-mcp --login
# Follow the device code prompt, sign in as personal@outlook.com
# Login second account
npx @a-impact/ms365-mcp --login
# Follow the device code prompt, sign in as work@company.com구성된 계정 목록 표시:
npx @a-impact/ms365-mcp --list-accounts도구 호출에 사용: 모든 도구 요청에 "account": "work@company.com"을 전달합니다.
{ "tool": "list-mail-messages", "arguments": { "account": "work@company.com" } }동작:
단일 계정이 구성되어 있으면 자동으로 선택됩니다(
account매개변수 불필요).여러 계정이 있고
account매개변수가 없으면, 서버는 선택된 기본 계정을 사용하거나 사용 가능한 계정을 나열하는 도움말 오류를 반환합니다.100% 하위 호환: 기존 단일 계정 설정은 변경 없이 그대로 작동합니다.
account매개변수는 이메일 주소(예:user@outlook.com) 또는 MSALhomeAccountId를 허용합니다.
엄격한 계정 고정
헤드리스 stdio 배포에서는 로컬 MSAL 캐시를 특정 Microsoft 계정 하나에 고정할 수 있습니다.
# Username matching is case-insensitive
MS365_MCP_EXPECTED_USERNAME=work@company.com npx @a-impact/ms365-mcp --login
# Or pin the exact MSAL homeAccountId shown by --list-accounts
npx @a-impact/ms365-mcp --expected-home-account-id <homeAccountId> --login--list-accounts를 사용하여 homeAccountId 값을 확인하세요. MCP list-accounts 도구는 의도적으로 계정 ID를 숨기므로 정확한 ID 고정에는 CLI를 사용해야 합니다.
고정은 선택 사항이며 로컬 MSAL에만 적용됩니다:
CLI 값(
--expected-username,--expected-home-account-id)이MS365_MCP_EXPECTED_USERNAME및MS365_MCP_EXPECTED_HOME_ACCOUNT_ID보다 우선합니다.빈 고정 값을 제공하면 무시되지 않고 시작 시 실패합니다.
사용자 이름 고정은 대/소문자를 구분하지 않으며,
homeAccountId고정은 정확히 일치해야 합니다.두 고정을 모두 설정한 경우 동일한 캐시된 계정으로 확인되어야 합니다.
로컬 stdio 시작 시 예상 계정이 토큰 캐시에 없으면 즉시 실패합니다. 고정을 설정하고,
--login을 실행한 다음, 헤드리스 서버를 시작하는 방식으로 부트스트랩합니다.장치 코드 및 브라우저 로그인은 선택한 계정이나 토큰 캐시를 저장하기 전에 누락되었거나 일치하지 않는 계정을 거부합니다.
고정을 사용하면 유효 MCP 모드가 단일 계정으로 좁혀집니다. 서버는
account매개변수를 광고하지 않으며 MCP 지침도 계정 전환을 제안하지 않습니다.--http,--obo및MS365_MCP_OAUTH_TOKEN은 Graph 호출에 요청 제공 토큰을 사용하므로 해당 모드에서는 계정 고정이 경고에만 적용됩니다. HTTP 인증 도구가 활성화된 경우 고정은 여전히 해당 로컬 MSAL 도우미 흐름에 적용됩니다.--logout은 고정 계정을 포함한 모든 캐시된 계정을 지웁니다. 부분 정리를 원하면--remove-account <id>를 사용하는 것이 좋습니다.
MCP 멀티플렉서(Legate, Governor)의 경우: 다중 계정 모드는 N-프로세스 패턴을 대체합니다. 계정당 하나의 서버를 실행하는 대신 단일 인스턴스가
account매개변수를 통해 모든 계정을 처리하므로 도구 중복이 N×110에서 110으로 줄어듭니다.
도구 프리셋
초기 연결 오버헤드와 토큰 사용을 줄이기 위해 전체 도구 세트 대신 프리셋 도구 범주를 사용하세요.
npx @a-impact/ms365-mcp --preset mail
npx @a-impact/ms365-mcp --list-presets # See all available presets사용 가능한 프리셋: mail, calendar, files, personal, work, excel, contacts, tasks, onenote, search, users, outlook, onedrive, teams, teams-write, all
endpoints.json의 각 엔드포인트는 presets 배열을 통해 어떤 프리셋에 속하는지 선언하므로 모든 프리셋은 정확한 도구 이름 허용 목록이며 앱을 초과하는 일치가 없습니다(예: mail은 공유 사서함 도구를 포함하지 않으며, 그 도구는 work에 있습니다). 범용 이진 리더인 download-bytes는 teams-write를 제외한 모든 프리셋에 포함되어 있으므로 앱이 반환하는 것이 무엇이든(파일, 첨부, 사진, 녹음) 항상 가져올 수 있습니다. get-download-url(드라이브/SharePoint 파일에 대한 사전 인증 URL)은 드라이브 기반 프리셋과 함께 제공됩니다. 따라서 파일을 찾을 수 있는 프리셋은 항상 해당 파일의 바이트를 읽을 수 있습니다.
outlook, onedrive 및 teams 프리셋은 앱 범위입니다. 정확히 하나의 Microsoft 앱을 노출합니다. "정확히 하나의 앱만 노출" 배포에 사용하세요.
# Outlook only (mail + calendar + contacts; no shared mailboxes, no files)
npx @a-impact/ms365-mcp --preset outlook
# Teams only (requires --org-mode)
npx @a-impact/ms365-mcp --org-mode --preset teamsteams-write 프리셋은 --read-only의 보내기 전용 대응입니다. 채팅에서 보내기, 채널에서 보내기/회신, 이름으로 채팅/팀/채널 나열, 활동 알림 — 메시지 읽기와 바이트 다운로더는 없습니다. 요청된 토큰은 구조적으로 최소입니다(Chat.ReadBasic, *.Send 범위, 기본 팀/채널 목록 — 메시지 내용을 읽을 수 있는 것이 없음).
npx @a-impact/ms365-mcp --org-mode --preset teams-write동적 도구 검색
모든 도구를 미리 로드하는 대신 동적 검색을 사용하면 LLM이 필요할 때만 도구를 찾아 로드할 수 있습니다.
npx @a-impact/ms365-mcp --discovery초기 컨텍스트를 작게 유지하고 토큰 사용량을 줄여줍니다. 특히 긴 세션이나 비용에 민감한 환경(예: 유료 API를 사용하는 Open WebUI)에서 유용합니다.
CLI 옵션
ms-365-mcp-server를 명령줄에서 직접 실행할 때 다음 옵션을 사용할 수 있습니다.
--login Login using device code flow
--logout Log out and clear saved credentials
--verify-login Verify login without starting the server
--list-permissions List required Graph API permissions and exit (respects --org-mode, --preset, --enabled-tools, --allowed-scopes)
--org-mode Enable organization/work mode from start (includes Teams, SharePoint, etc.)
--work-mode Alias for --org-mode
--force-work-scopes Backwards compatibility alias for --org-mode (deprecated)
--cloud <type> Microsoft cloud environment: global (default) or china (21Vianet)
--allowed-scopes <scopes> Limit exposed tools to Graph scopes covered by this allowlist
--extra-scopes <scopes> Append additional Graph scopes to the token request (for use with your own app registration + graph-batch)
--expected-username <username> Require local MSAL auth to use this account username
--expected-home-account-id <id> Require local MSAL auth to use this exact homeAccountId서버 옵션
MCP 서버로 실행할 때 다음 옵션을 사용할 수 있습니다.
-v Enable verbose logging
--read-only Start server in read-only mode, disabling write operations
--http [port] Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)
Starts Express.js server with MCP endpoint at /mcp
--enable-auth-tools Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)
--no-dynamic-registration Disable OAuth Dynamic Client Registration (enabled by default in HTTP mode)
--enabled-tools <pattern> Filter tools using regex pattern (e.g., "excel|contact" to enable Excel and Contact tools)
--preset <names> Use preset tool categories (comma-separated). See "Tool Presets" section above
--list-presets List all available presets and exit
--toon (experimental) Enable TOON output format for 30-60% token reduction
--discovery Dynamic tool discovery: loads tools on demand to reduce initial token usage (see "Dynamic Tool Discovery" above)
--public-url <url> Public base URL for OAuth when behind a reverse proxy (see Open WebUI section and docs/deployment.md)환경 변수:
READ_ONLY=true|1: --read-only 플래그 대안ENABLED_TOOLS: regex 패턴으로 도구 필터링(--enabled-tools 플래그 대안)MS365_MCP_ORG_MODE=true|1: 조직/업무 모드 활성화(--org-mode 플래그 대안)MS365_MCP_FORCE_WORK_SCOPES=true|1: 이전MS365\_MCP\_ORG\_MODE에 대한 하위 호환성MS365_MCP_OUTPUT_FORMAT=toon: TOON 출력 형식 활성화(--toon 플래그 대안)MS365_MCP_MAX_TOP=<n>: 목록 요청에서 Graph$top/top에 대한 상한(양의 정수). 모델이 더 큰 값을 전달하면 서버가n으로 제한하여 응답이 더 작아지도록 유지합니다. 예:MS365_MCP_MAX_TOP=15MS365_MCP_MAX_PAGES=<n>:fetchAllPages: true로 도구를 호출할 때 추적할 최대 페이지 수(양의 정수, 기본값100). 큰 결과 집합의 메모리와 지연 시간을 제한합니다.MS365_MCP_MAX_ITEMS=<n>:fetchAllPages: true일 때 누적될 최대 항목 수(양의 정수, 기본값10000). 항목이 이만큼 모이면 페이지 추적이 멈추고 응답이 잘립니다.MS365_MCP_ALLOW_PAGINATION=0|false|no: 다중 페이지 추적을 완전히 비활성화합니다. 설정하면fetchAllPages매개변수가 도구에 선전하지 않으며, 여전히 전달하는 요청은 첫 번째 페이지만 반환합니다(기본값: 페이지네이션 활성화).MS365_MCP_BODY_FORMAT=html: 이메일 본문을 일반 텍스트 대신 HTML로 반환(기본값: text)MS365_MCP_MESSAGE_SIGNOFF_PREFIX=<text>: 보내는 메시지 앞에 붙는 서명 접두어로, 수신자가 에이전트가 보낸 것임을 알 수 있게 합니다(예:🤖). 기본값: 없음. CLI 등가:--message-signoff-prefix <text>(아래 Message Signoff 참조)MS365_MCP_MESSAGE_SIGNOFF_SUFFIX=<text>: 보내메시지 뒤에 붙는 서명. 기본값: 없음. CLI 등가:--message-signoff-suffix <text>.--no-message-signoff는 둘 다 비활성화합니다(아래 "Message Signoff" 참조)MS365_MCP_RATE_LIMIT_DISABLED=true|1: HTTP 모드에서 IP별 요청 속도 제한을 비활성화(기본값: 활성화 —/authorize,/token,/register에 분당 30회;/mcp에 분당 120회)MS365_MCP_TRUST_PROXY_HOPS=<n>: HTTP 모드에서 신뢰할 리전스 프록시 홉 수(기본값1). 정확한 IP별 요청 제한은 이 값이 배포 환경과 일치하는지에 따라 달라집니다 — 서버 앞의 프록시 수, 원시 소켓 피어 IP를 사용하려면0, 또는 쉼표로 구분된 서브넷 목록으로 설정MS365_MCP_CLOUD_TYPE=global|china: Microsoft 클라우드 환경(--cloud 플래그 대안)LOG_LEVEL: 로그 수준 설정(기본값: 'info')SILENT=true|1: 콘솔 출력 비활성화MS365_MCP_REDACT_PII=false|0: 로그 메시지에서 JWT, Bearer 헤더, OAuth 토큰 필드 및 이메일 주소의 난독(scrubbing) 비활성화(기본값: 활성화). 서버는 실시간 Graph 베어러 토큰을 처리하므로 전체 상세한 로컬 디버깅을 위해 명시적으로 변경하지 않는 한 난독화는 켜져 있습니다.MS365_MCP_CLIENT_ID: 사용자 지정 Azure 앱 클라이언트 ID(기본 제공 앱 대신)MS365_MCP_TENANT_ID: 사용자 지정 테넌트 ID(다중 테넌트의 기본값은 'common'). 개인 Microsoft 계정은 이것을consumers로 설정해야 합니다 — 2026년 6월 현재 기본 'common' 인증기관에서 발급된 새로고침 토큰은 처음 새로고침에서 거부되므로 로그인 후 약 1시간 이내에 세션이 중단됩니다MS365_MCP_OAUTH_TOKEN: Microsoft Graph API용 기존 OAuth 토큰(BYOT 방식)MS365_MCP_KEYVAULT_URL: 비밀번호 관리용 Azure Key Vault URL(Azure Key Vault 섹션 참조)MS365_MCP_TOKEN_CACHE_PATH: MSAL 토큰 캐시의 사용자 지정 파일 경로(아래 토큰 저장 참조)MS365_MCP_SELECTED_ACCOUNT_PATH: 선택된 계정 메타데이터의 사용자 지정 파일 경로(아래 토큰 저장 참조)MS365_MCP_AUTH_CACHE_COMMAND: 공급자 중립 인증-캐시 저장용 외부 실행 래퍼(아래 토큰 저장 참조)MS365_MCP_AUTH_CACHE_COMMAND_TIMEOUT_MS:MS365_MCP_AUTH_CACHE_COMMAND호출당 시간 초과(기본값:10000)MS365_MCP_EXPECTED_USERNAME: 로컬 MSAL 인증이 이 Microsoft 계정 사용자 이름을 사용하도록 요구(대/소문자를 구분하지 않음; CLI 플래그가 우선)MS365_MCP_EXPECTED_HOME_ACCOUNT_ID: 로컬 MSAL 인증이 이 정확한 MSAL homeAccountId를 사용하도록 요구(CLI 플래그가 우선)
토큰 저장
인증 토큰은 암호화된 파일(AES-256-GCM)에 저장됩니다. 32바이트 암호화 키만 keytar의 운영 체제 자격 증명 저장소로 이동합니다.
캐시 자체는 일부 자격 증명 저장소가 담기에는 너무 큽니다. Windows 자격 증명 관리자 Blob은 2560바이트로 제한되고 실제 토큰 캐시는 그 몇 배이므로, Windows에서는 쓰기가 성공할 수 없었습니다. 키는 계정 수와 관계없이 32바이트이므로 모든 플랫폼에서 동일하게 작동합니다.
기본 경로는 사용자별 구성 디렉터리에 있습니다.
플랫폼 | 위치 |
Windows |
|
macOS |
|
Linux |
|
이전 버전은 설치된 패키지 내부의 경로를 기본값으로 사용했는데, npx에서는 콘텐츠 해시 기반 캐시 디렉터리로 확인되며 npm cache clean이나 버전 업데이트 시 삭제됩니다. 패키지 디렉터리에 남아 있는 캐시는 첫 실행 시 새 위치로 이동됩니다.
이 방식은 전역 및 로컬 설치와 해시가 변경되지 않은 npx에 적용됩니다. 이전 npx 해시 디렉터리에 남겨진 캐시에는 접근할 수 없으므로, npx 설치를 마지막으로 한 번 더 업그레이드하면 다시 로그인해야 합니다. 다른 디렉터리에서 캐시를 가져오는 것은 이 패키지가 자신이 기록했다는 것을 증명할 수 없는 디렉터리를 신뢰해야 한다는 뜻이며, 로그인 한 번을 아끼기에는 그만한 가치가 없습니다.
필요한 경우 경로를 재정의할 수 있습니다:
export MS365_MCP_TOKEN_CACHE_PATH="$HOME/.config/ms365-mcp/.token-cache.json"
export MS365_MCP_SELECTED_ACCOUNT_PATH="$HOME/.config/ms365-mcp/.selected-account.json"상위 디렉터리는 자동으로 생성됩니다. 파일은 0600 권한으로 기록됩니다.
자격 증명 저장소가 없는 경우(헤드리스 Linux, 대부분의 컨테이너)에는 키가 캐시 파일 옆의 .cache-key에 0600 권한으로 기록됩니다. 이렇게 하면 토큰이 우연한 cat 실행, 백업, 실수로 인한 커밋에 노출되지 않습니다. 이미 디렉터리를 읽을 수 있는 사용자로부터는 보호되지 않습니다. 키가 바로 그곳에 있기 때문입니다. 실제 비밀 저장소에 캐시가 필요하다면 아래의 MS365_MCP_AUTH_CACHE_COMMAND를 사용하세요.
캐시를 해독할 수 없다면(키 분실, 키체인 잠김, 파일 수정) 서버가 시작되지 못하는 대신 다시 로그인하라는 메시지가 표시됩니다. 캐시 파일은 그대로 유지됩니다. 삭제되지도 않고 새 로그인으로 덮어쓰지도 않습니다. 단순히 잠겨 있는 키체인은 대개 다음 시작 시 정상적으로 읽히며, 그때 캐시도 그대로 남아 있습니다.
그 대가로 이 상황이 지속되는 동안에는 새 세션이 저장되지 않으므로 시작할 때마다 다시 로그인해야 합니다. 키가 진짜로 유실되어 캐시가 절대 열리지 않는다면 로그가 그 사실을 알리고 경로를 명시하므로 .token-cache.json을 삭제하면 처음부터 다시 시작할 수 있습니다.
호스팅/샌드박스 환경(예: Anthropic Cowork): 세션 간에 토큰을 유지하려면
MS365_MCP_TOKEN_CACHE_PATH와MS365_MCP_SELECTED_ACCOUNT_PATH를 영구 마운트로 설정하십시오.
외부 인증-캐시 명령
헤드리스 로컬-MSAL 배포에서는 내장 keytar/파일 저장소를 공급자 중립적인 외부 명령으로 대체할 수 있습니다:
export MS365_MCP_AUTH_CACHE_COMMAND="/path/to/ms365-auth-cache-store"
export MS365_MCP_AUTH_CACHE_COMMAND_TIMEOUT_MS=10000로컬 인증 흐름에서 MS365_MCP_AUTH_CACHE_COMMAND가 설정되면 서버는 MSAL 토큰 캐시 및 선택된 계정 메타데이터에 대해 해당 명령만 사용합니다. keytar나 로컬 파일로 대체(fall back)하지 않습니다. 명령 경로가 없거나 POSIX에서 실행 가능하지 않거나, 0이 아닌 종료 코드를 반환하거나, 시간 초과하거나, 잘못된 형식의 데이터를 반환하면 인증-캐시 작업은 안전하게 실패(fail closed) 처리된 상태에서 정제된 오류 메시지를 반환합니다.
값은 실제 실행 가능한 래퍼 경로여야 합니다. 셸 명령 문자열이 아니며 별도의 인자 환경 변수도 없습니다. 인터프리터, 지역, 프로필, 공급자별 설정은 모두 래퍼 안에 넣으십시오. Windows 사용자는 Node가 셸 구문 해석 없이 직접 실행할 수 있는 래퍼 실행 파일이나 스크립트로 변수를 지정하십시오.
서버는 다음과 같이 래퍼를 호출합니다:
$MS365_MCP_AUTH_CACHE_COMMAND load token-cache
$MS365_MCP_AUTH_CACHE_COMMAND save token-cache
$MS365_MCP_AUTH_CACHE_COMMAND delete token-cache
$MS365_MCP_AUTH_CACHE_COMMAND load selected-account
$MS365_MCP_AUTH_CACHE_COMMAND save selected-account
$MS365_MCP_AUTH_CACHE_COMMAND delete selected-account프로토콜 v1:
load <key>는 표준 입력을 읽지 않습니다. 키가 있으면{"found":true,"value":"<stored envelope string>"}와 함께 종료 코드0으로 종료합니다. 캐시 누락 시에는{"found":false}또는 빈 표준 출력과 함께 종료 코드0으로 종료합니다.save <key>는 표준 입력으로{"value":"<stamped envelope string>"}를 수신하며, 값이 영구적으로 커밋된 후에만 종료 코드0으로 종료해야 합니다. v1에는 즉시 무시(fire-and-forget) 또는 통합(coalesced) 저장 기능이 없습니다.delete <key>는 표준 입력을 읽지 않고, 키가 존재했는지 여부와 무관하게 종료 코드0으로 종료합니다.<key>는token-cache또는selected-account입니다.0이 아닌 종료 코드는 저장소 오류입니다. 캐시 누락을 나타내기 위해 종료 코드
2를 사용하지 마십시오.표준 오류(stderr)는 캡처되어 정제된 오류 메시지에서 잘릴 수 있습니다. 서버는 stdin과 stdout의 페이로드를 절대 로그에 남기지 않습니다.
토큰 캐시 페이로드는 클 수 있습니다. 래퍼는 최소 256KB 값을 처리해야 합니다.
일반 상태 비저장 HTTP Graph 요청은 로컬 인증-캐시 저장소를 사용하지 않습니다. HTTP 모드에서는 로컬 인증 도구가 명시적으로 활성화되어 있거나 --login, --verify-login, --list-accounts, --select-account, --logout 같은 로컬 계정 명령이 사용되는 경우가 아니라면 명령 저장소는 시작 시와 요청 시 모두 건너뜁니다.
Azure Key Vault 통합
프로덕션 배포의 경우 환경 변수 대신 Azure Key Vault에 비밀을 저장할 수 있습니다. 이는 관리 ID를 사용하는 Azure Container Apps에서 특히 유용합니다.
설정
Key Vault 생성(아직 없는 경우):
az keyvault create --name your-keyvault-name --resource-group your-rg --location eastusKey Vault에 비밀 추가:
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-id --value "your-client-id" az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-tenant-id --value "your-tenant-id" # Optional: if using confidential client flow az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-secret --value "your-secret"Key Vault에 대한 액세스 권한 부여:
관리 ID를 사용하는 Azure Container Apps의 경우:
# Get the managed identity principal ID PRINCIPAL_ID=$(az containerapp show --name your-app --resource-group your-rg --query identity.principalId -o tsv) # Grant access to Key Vault secrets az keyvault set-policy --name your-keyvault-name --object-id $PRINCIPAL_ID --secret-permissions get listAzure CLI를 사용한 로컬 개발의 경우:
# Your Azure CLI identity already has access if you have appropriate RBAC roles az login서버 구성:
MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net npx @a-impact/ms365-mcp
비밀 이름 매핑
Key Vault 비밀 이름 | 환경 변수 | 필수 |
ms365-mcp-client-id | MS365_MCP_CLIENT_ID | 예 |
ms365-mcp-tenant-id | MS365_MCP_TENANT_ID | 아니요 (기본값: 'common') |
ms365-mcp-client-secret | MS365_MCP_CLIENT_SECRET | 아니요 |
인증
Key Vault 통합은 Azure Identity SDK의 DefaultAzureCredential을 사용하며, 이는 여러 인증 방법을 순서대로 자동으로 시도합니다:
환경 변수 (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
관리 ID (Azure Container Apps 권장)
Azure CLI 자격 증명 (로컬 개발용)
Visual Studio Code 자격 증명
Azure PowerShell 자격 증명
선택적 종속성
Azure Key Vault 패키지(@azure/identity, @azure/keyvault-secrets)는 선택적 종속성입니다. MS365_MCP_KEYVAULT_URL이 설정되어 있어야지만 로드됩니다. Key Vault를 사용하지 않으면 이 패키지가 필요하지 않습니다.
메시지 서명
외부 전송 메시지에는 구성 가능한 서명(예: 🤖 접두사)을 붙일 수 있어, 수신자가 에이전트가 보낸 메시지와 직접 입력한 메시지를 구분할 수 있습니다. 기본적으로 꺼져 있으며, --message-signoff-prefix / --message-signoff-suffix(환경 변수: MS365_MCP_MESSAGE_SIGNOFF_PREFIX / MS365_MCP_MESSAGE_SIGNOFF_SUFFIX)로 활성화할 수 있습니다. --no-message-signoff 또는 빈 환경 변수 값으로 다시 끌 수 있습니다.
일단 구성하면 이 기능은 모든 Teams 메시지(전송, 답변, 편집 – graph-batch 경유 포함), 직접 메일 전송(send-mail, 답장/전달, 해당 공유 사서함 변형, 그룹 스레드 답장), 그리고 초안 내용이 작성될 때 메일 초안에 적용됩니다. send-draft-message는 초안을 그대로 보내므로 직접 작성한 초안은 변경되지 않은 채로 전송됩니다. 이미 마커가 있는 메시지에는 두 번 서명하지 않으며, 본문에 서명을 넣을 수 없는 전송은 서명 없이 보내지 않고 거부됩니다.
마커는 시각적인 텍스트를 만드는 한 마크업(예: 색상이 적용된 <span>)을 포함할 수 있습니다. 이 서명은 에이전트가 제공받은 도구를 오용하는 것을 막기 위한 안전장치일 뿐, 안전한 경계선으로 사용할 수는 없습니다. 같은 시스템에서 셸에 접근할 수 있는 에이전트는 서명 없이 서버를 그냥 다시 시작하기만 하면 됩니다.
프로덕션 배포
조직 전체에서 액세스할 수 있도록 서버를 호스팅하는 전체 가이드(Docker, Azure Container Apps, Azure App Service, Azure AD 앱 등록, 역방향 프록시 설정, 클라이언트 구성, 노출되는 엔드포인트 포함)는 docs/deployment.md를 참조하세요.
기여
기여를 환영합니다! Pull Request를 제출하기 전에 변경 사항이 우리의 품질 기준을 충족하는지 확인하십시오.
모든 코드 품질 요구 사항을 확인하려면 검증 스크립트를 실행하세요:
npm run verify개발자를 위한
저장소를 클론한 후, Microsoft Graph OpenAPI 사양에서 클라이언트 코드를 생성해야 할 수도 있습니다:
npm run generate관련 프로젝트
ms-365-admin-mcp-server — @okapi-ca 제작: application permissions(클라이언트 자격 증명 흐름)을 사용하는 관리자/데몬 시나리오용 보조 서버이며, 보안 경고, 감사 로그, 서비스 상태 및 사용 제한 보고서를 제공합니다.
지원
문제가 발생하거나 도움이 필요하면:
issue 만들기
discussion 시작하기
이메일: eirikb@eirikb.no
Discord: https://discord.gg/WvGVNScrAZ 또는 @eirikb
라이선스
MIT © 2026 A-Impact
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Microsoft Graph API services including Outlook email, Calendar events, OneDrive files, and Contacts. Supports multiple Microsoft accounts with unified search across all services.
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to interact with Microsoft 365 services (users, mail, calendar, files) via Microsoft Graph API.371MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Microsoft 365 through the Microsoft Graph API, including searching Teams messages, managing chats, and sending messages.77MIT
- FlicenseNot gradedqualityDmaintenanceConnects AI assistants to Microsoft 365 via the Graph API, enabling email search, attachment extraction, and OneDrive file reading through natural conversation.
Related MCP Connectors
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/A-Impact-Pavel/ms365-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server