outlook-mcp
outlook-ews-mcp
outlook-ews-mcp는 EWS(exchangelib)를 통해 온프레미스 Microsoft Exchange용 MCP 서버입니다. MCP 호환 클라이언트(Claude Desktop, Claude Code 및 기타 모든 MCP 클라이언트)가 단일하고 테스트 가능한 Python 서비스를 통해 이메일, 일정, 연락처, 폴더, 첨부 파일 및 가용성 데이터에 액세스할 수 있게 해줍니다. 직접 사서함 스크립팅이 필요 없습니다.
outlook-mcp에서 이름이 변경되었습니다. 해당 이름은 이미 PyPI에서 관련 없는 프로젝트가 사용 중이므로, 배포 및 CLI 이름은 이제outlook-ews-mcp입니다. Python import 경로는 변경되지 않았습니다. 첫 번째 태그된 PyPI 릴리스 전까지는 아래와 같이 이 저장소에서 설치하세요.
목차
Related MCP server: owa-mail-mcp
주요 기능
이메일 — 목록, 검색(부분 문자열 또는 Advanced Query Syntax), 읽기, 보내기, 답장, 전달, 이동, 복사, 삭제, 표시, 분류, 일괄 작업, 원시 MIME 내보내기, 첨부 파일 추가/삭제
시스템 — 받은 편지함 규칙, 부재 중(자동 회신), 읽기 전용 대리인 목록
일정 — 목록, 생성, 업데이트, 삭제, 초대 응답, 빈 시간 찾기, 공유/대리 사서함 일정 보기, Room Finder, 일괄 작업
연락처 — 검색, 읽기, 생성, 업데이트, 삭제
폴더 및 첨부 파일 — 폴더 CRUD 및 첨부 파일 다운로드
인증 — 온프레미스 Exchange에 대한
NTLM및Basic전송 —
stdio및SSE아키텍처 — 단일
ExchangeClient추상화를 통한 중앙 집중식 오류 매핑(프로젝트 참고 사항 참조)안전성 — 기본적으로 개인정보 보호에 더 안전한 스모크 체크(스모크 체크 참조)
운영 — Docker 이미지 및 GitHub 및 GitLab CI/CD 파이프라인 포함
도구 카탈로그
아래의 모든 도구는 이름, 설명 및 스키마의 단일 소스인 tool_specs.py에 등록되어 있습니다. 읽기 전용은 사서함을 수정하지 않는 도구를 표시합니다. 이러한 도구는 더 높은 동시성을 가지며(요청 큐 참조) 추측성 호출에 안전합니다.
시스템
도구 | 설명 | 읽기 전용 |
| Exchange 연결 확인 | ✅ |
| 사서함 메타데이터 가져오기 | ✅ |
| 사서함 대리인 및 해당 폴더 권한 수준 나열 — | ✅ |
| 서버 측 받은 편지함 규칙 나열 | ✅ |
| 서버 측 받은 편지함 규칙 생성(예: "이 보낸 사람 → 폴더로 이동") | |
| 규칙 활성화/비활성화 또는 우선순위 변경(다른 필드는 여기서 업데이트할 수 없음) | |
| ID로 서버 측 받은 편지함 규칙 삭제 | |
| 부재 중(자동 회신) 설정 가져오기 | ✅ |
| 자동 회신 끄기, 켜기 또는 시작/종료 기간 예약 |
⚠️
create_inbox_rule/update_inbox_rule/delete_inbox_rule는 EWS를 통해 규칙을 관리하며, 이는 데스크톱 Outlook이 유지하는 클라이언트 측 규칙 blob을 제거합니다. 이로 인해 사용자가 Outlook 자체에서 만든 규칙이 삭제될 수 있습니다. 이는 문서화된 EWS 동작이며, 여기서의 버그가 아닙니다.
이메일
도구 | 설명 | 읽기 전용 |
| 폴더의 이메일 나열 | ✅ |
| ID로 전체 이메일 가져오기 | ✅ |
| 메시지의 원시 RFC 822 MIME 콘텐츠를 base64로 인코딩하여 내보내기 | ✅ |
| 대화의 모든 메시지를 순서대로 가져오기(본문 포함) | ✅ |
| 부분 문자열(제목/본문/보낸 사람) 또는 서버 측 Advanced Query Syntax로 검색 | ✅ |
| 새 이메일 보내기 | |
| 이메일에 답장 | |
| 이메일 전달 | |
| 이메일을 다른 폴더로 이동 | |
| 이메일을 다른 폴더로 복사 | |
| 항목별 결과가 포함된 일괄 이동 — 잘못된 ID 하나가 나머지를 실패시키지 않음 | |
| 항목별 결과가 포함된 일괄 복사 | |
| 항목별 결과가 포함된 일괄 삭제( | |
| 이메일 삭제 | |
| 읽음 상태, 중요도 또는 후속 조치 플래그 업데이트 | |
| Outlook 범주(색상 레이블) 설정, 추가 또는 제거 | |
|
| |
|
| |
| 최근 메시지에서 샘플링된 사용 중인 범주를 개수와 함께 나열(사서함 마스터 범주 목록 아님) | ✅ |
| 사서함 폴더 나열 | ✅ |
| 사서함 폴더 생성 | |
| 폴더 이름 변경 — 기본 제공 폴더(받은 편지함, 보낸 항목, 일정 등)는 거부 | |
| 폴더 및 그 안의 모든 항목 삭제 — 기본 제공 폴더는 거부 | |
| 이메일 초안 생성 | |
| 초안 업데이트; 생략된 필드는 변경되지 않으며, | |
| 기존 초안 보내기 | |
| 메시지(일반적으로 초안)에 로컬 파일 첨부 — 파일은 | |
| ID로 메시지에서 첨부 파일 하나 제거 | |
| 첨부 파일을 디스크에 저장 | ✅ |
일정
도구 | 설명 | 읽기 전용 |
| 시간 범위의 일정 이벤트를 나열합니다. 동료의 기본 일정을 보려면 | ✅ |
| ID로 일정 이벤트를 가져옵니다. 동료의 일정을 보려면 | ✅ |
| 일정 이벤트를 생성합니다 | |
| 일정 이벤트를 업데이트합니다 | |
| 일정 이벤트를 삭제합니다 | |
| 초대를 수락, 거절 또는 잠정적으로 응답합니다 | |
| 열린 회의 시간 슬롯을 찾습니다 | ✅ |
| 이벤트를 일괄 삭제하고 항목별 결과를 반환합니다 | |
| 초대에 일괄 응답하고 항목별 결과를 반환합니다 | |
| 사용 가능/사용 중 슬롯을 가져옵니다. 동료의 일정을 보려면 | ✅ |
| 일정 목록을 나열합니다 | ✅ |
| Room Finder 회의실 목록(회의실 그룹)을 나열합니다 | ✅ |
| Room Finder 회의실 목록의 회의실을 나열합니다 | ✅ |
연락처
도구 | 설명 | 읽기 전용 |
| 연락처를 검색합니다 | ✅ |
| ID로 연락처를 가져옵니다 | ✅ |
| 개인 연락처를 생성합니다 | |
| 개인 연락처를 업데이트합니다 | |
| 개인 연락처를 삭제합니다 |
일반적인 사용 사례
Claude Desktop 또는 다른 MCP 클라이언트를 온프레미스 Exchange에 연결
받은 편지함 메시지 검색 및 전체 이메일 콘텐츠 가져오기
AI 워크플로에서 이메일 보내기 또는 초안 작성
일정 확인 및 회의 만들기
일정 조정을 위한 사용 가능/사용 중 시간 확인
개인 연락처 또는 전역 주소 목록 검색
직접 사서함 스크립팅 대신 제어된 MCP 경계를 통해 Exchange 작업 노출
보안 참고 사항
현재 코드가 수행하는 작업:
범위가 제한된 연결 |
|
원격 측정 없음 | 원격 측정, 분석 또는 타사 데이터 내보내기 로직이 포함되어 있지 않습니다 |
비밀은 로컬에 유지 | 비밀을 환경 변수 / |
깨끗한 오류 페이로드 | 구조화된 MCP 오류 응답에는 원시 Exchange 예외 텍스트, 메시지 본문, 첨부 파일 콘텐츠 또는 비밀번호가 포함되지 않습니다. 성공한 도구는 요청된 사서함 데이터만 반환합니다 |
깨끗한 로그 |
|
깨끗한 Docker 빌드 |
|
여전히 주의해야 할 사항:
EXCHANGE_VERIFY_SSL=false는 TLS 인증서 검증을 비활성화합니다 — 신뢰할 수 있는 내부/자체 서명 환경에서만 사용하세요.EXCHANGE_AUTH_TYPE=Basic은 자격 증명을 평문으로 전송하므로 서버는http://EXCHANGE_SERVER에 대해 시작을 거부합니다. 직접 제어하는 로컬/테스트 서버에서만EXCHANGE_ALLOW_INSECURE_BASIC_AUTH=true로 재정의하세요.get_attachment는 파일을 디스크에 쓰고,send_email/reply_email/forward_email/create_draft는(attachments를 통해) 로컬 파일을 읽어 그 내용을 발신 메일에 첨부합니다. 신뢰할 수 없는 이메일 콘텐츠와 결합하면 이는 프로세스가 읽을 수 있는 모든 파일의 프롬프트 주입 기반 유출 경로가 될 수 있습니다. 로컬 파일 액세스는 기본적으로 거부되며,EXCHANGE_ATTACHMENT_ROOT가 절대 디렉터리로 설정된 경우에만 작동합니다. 그러면attachments경로와get_attachment의save_path가 모두 해당 디렉터리 트리로 제한됩니다(save_path가 설정되지 않은 경우에도 시스템 임시 디렉터리로 대체됩니다).outlook-ews-mcp-smoke는 기본적으로 개인정보 보호에 안전하며 마스킹된 사서함 정보와 개수만 출력합니다. stdout에 실제 받은 편지함/이벤트 데이터를 명시적으로 원하는 경우에만OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true를 설정하세요.LOG_FILE로 파일 로깅을 활성화하는 경우 OS 권한으로 해당 파일을 보호하세요.CI에서 Docker 이미지를 게시하는 경우 GitLab/GitHub 프로젝트 액세스 및 레지스트리 권한을 보호하세요.
빠른 시작
uv venv
source .venv/bin/activate
uv pip install -e .[dev]
cp .env.example .env
outlook-ews-mcp기본적으로 서버는 stdio 모드로 실행됩니다. 대신 HTTP 서버를 시작하려면 MCP_TRANSPORT=sse를 설정하세요.
구성
시작하기 위한 최소 .env — 아래의 다른 모든 항목은 작동하는 기본값이 있습니다:
EXCHANGE_SERVER=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_USERNAME=DOMAIN\username
EXCHANGE_PASSWORD=secret
EXCHANGE_EMAIL_ADDRESS=user@company.com
EXCHANGE_AUTH_TYPE=NTLM모든 변수에 대한 완전한 주석이 포함된 사본은 .env.example에 있습니다.
변수 | 기본값 | 설명 |
| (필수) | EWS 엔드포인트 URL, 예: |
| (필수) |
|
| (필수) | 계정 비밀번호 |
| 설정 안 됨 | SMTP 주소; |
|
|
|
|
|
|
|
| 서버의 TLS 인증서 검증; 신뢰할 수 있는 내부/자체 서명 설정에서만 |
| 설정 안 됨 (자동 감지) | Exchange 서버 버전, 예: |
|
| Exchange가 해석 불가능한 GUID 시간대 ID를 보고할 때만 사용됨; 정상 운영에서는 사서함 자체의 기본 시간대 사용 |
|
| 요청당 제한 시간(초) (1–300) |
|
| Exchange가 사용 중임을 보고할 때 읽기 전용 호출에 대한 실제 경과 시간 기반 재시도 예산으로, 재시도 횟수가 아님; |
| 설정 안 됨 | 가장(impersonate)할 사서함 (Exchange 가장 권한 필요) |
|
| 첨부 파일당 최대 크기, 업로드와 |
|
| 단일 send/reply/forward/create_draft 호출의 최대 첨부 파일 수 (1–100) |
|
| 단일 호출의 첨부 파일 총 크기 상한 (1–500) |
| 설정 안 됨 (비활성화) | 첨부 파일 경로를 제한하는 디렉터리. 설정하지 않으면 |
|
|
|
|
| base64 확장 전 원시 MIME 내보내기 크기 상한 (1–100) |
| 설정 안 됨 | 발신 텍스트 본문과 답장/전달에 추가됨. EWS 서명 API가 없으므로 이는 사서함의 Outlook 서명이 아닌 구성 설정임 |
| 설정 안 됨 | 발신 HTML 본문에 추가됨. 위와 동일한 주의 사항; 둘 사이의 상호 변환은 없음. 호출별로 |
|
|
|
|
|
|
|
|
|
|
| 동시 읽기 전용 도구 호출 수 (1–8); 변경 호출은 항상 단독으로 실행됨. 요청 큐 참조 |
|
| 한 번에 수용되는 최대 호출 수(실행 중 + 대기 중) (1–1000); 초과 시 즉시 |
|
|
|
| 설정 안 됨 (stderr) | 로그 파일 경로; 설정 시 OS 권한으로 보호할 것 |
단일 변수에 국한되지 않는 동작 참고 사항:
list_events와find_free_slots는 제한된limit(기본 200, 최대 1000)을 허용하며, 이벤트 범위는 366일, 여유 슬롯 범위는 31일로 제한되므로 광범위한 쿼리가 무제한의 EWS 또는 MCP 응답을 생성할 수 없습니다.목록은 의도적으로 간결하게 유지됩니다: 이메일 요약에는 발신자가 포함되지만 수신자 목록은 포함되지 않으며 (
get_email에 있음),list_events는 본문 없이 이벤트를 반환하고 (get_event에 있음),get_email은include_headers: true일 때만 RFC-822 헤더를 반환합니다.전송 작업은 EWS가 전송된 사본에 대한 영구 ID를 제공하지 않을 때
id: null을 반환합니다 (특히 답장, 전달, 전송된 임시 보관함).첨부 파일 메타데이터에는
downloadable이 포함됩니다. 포함된 Exchange 항목 첨부 파일은downloadable: false이며get_attachment로 저장할 수 없습니다.
요청 큐
클라이언트는 여러 도구 호출을 병렬로 실행합니다. Exchange 작업은 차단(blocking) 방식이므로 서버는 이를 작업자 스레드에서 실행하고 하나의 공유 FIFO 큐를 통해 호출을 수용합니다.
MCP_MAX_CONCURRENCY(기본4)는 한 번에 실행되는 읽기 전용 호출 수를 설정하므로, 에이전트가 이메일, 폴더 목록, 캘린더를 요청할 때 각각의 합계가 아닌 가장 느린 왕복 시간만 부담합니다. 변경 호출은 항상 단독으로 실행됩니다 — 한 번에 하나씩, 읽기와 겹치지 않음 — 따라서 공유 계정 상태에 대한 읽기/쓰기 경합이 발생할 수 없습니다. 한도를 초과한 호출자는 도착 순서대로 차례를 기다립니다. 대기 중인 변경 호출은 이후의 읽기가 이를 추월하지 못하게 차단합니다.MCP_MAX_QUEUE_SIZE(기본20)는 한 번에 수용할 수 있는 호출 수(실행 중 또는 대기 중)를 제한합니다. 이미 그만큼 들어와 있으면 추가 호출은 무제한 큐에 합류하는 대신 즉시server_busy오류를 받습니다.작업이 진행되는 동안 전송 계층은 응답성을 유지합니다. 도구는 이벤트 루프 스레드에서 실행되는 대신 대기(await)되므로 완료된 응답은 즉시 나가고 긴 호출이 실행되는 동안에도 핑에 응답합니다.
의도적으로 호출별 제한 시간이 없습니다. 소켓 읽기에 차단된 스레드는 외부에서 종료할 수 없습니다. 런타임은 대기를 중지할 수만 있으며, 이는 스레드가 보유한 EWS 세션과 함께 스레드를 버리는 것입니다.
exchangelib의 세션 풀에는 하드 최대 한도가 있고 포기 경로 없이 루프에서 세션을 나눠주므로, 누출된 세션은 결국 풀을 고갈시키고 이후 모든 호출이 영원히 차단됩니다. 느린 호출은 대신EXCHANGE_TIMEOUT과EXCHANGE_MAX_RETRY_WAIT_SECONDS로 제한되는 범위 내에서 기다려집니다. 계정의 재시도 정책은 빠른 실패(fail-fast)이므로 모든 EWS 호출은exchangelib가 내부적으로 영원히 재시도하는 대신 첫 번째 일시적 오류에서 예외를 발생시키며,ExchangeClient는 해당 실제 경과 시간 예산으로 제한된 읽기 전용 호출만 자체적으로 재시도합니다. 쓰기는 자동 재시도되지 않습니다. 예상 예산을 초과하는 지연은 로그에 기록됩니다.
Claude Desktop 예시
{
"mcpServers": {
"outlook": {
"command": "outlook-ews-mcp",
"env": {
"EXCHANGE_SERVER": "https://mail.company.com/EWS/Exchange.asmx",
"EXCHANGE_USERNAME": "DOMAIN\\username",
"EXCHANGE_PASSWORD": "secret",
"EXCHANGE_EMAIL_ADDRESS": "user@company.com",
"EXCHANGE_AUTH_TYPE": "NTLM"
}
}
}
}스모크 테스트
.env를 채운 후 다음을 실행하세요:
outlook-ews-mcp-smoke기본 출력은 더 안전한 검증을 위해 정리(sanitize)됩니다. 출력에 샘플 사서함/이벤트 데이터를 의도적으로 포함하려면:
OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true outlook-ews-mcp-smokeDocker
docker build -t outlook-ews-mcp .
docker run --rm --env-file .env outlook-ews-mcpCI/CD
GitHub Actions와 GitLab CI는 모두 pyproject.toml에 고정된 uv 버전을 사용하여 린트, 포맷팅, 타입 검사, 테스트, 의존성
감사, 패키지 빌드를 실행합니다.
GitHub | 또한 OIDC 신뢰 게시(trusted publishing)를 통해 태그가 지정된 릴리스( |
GitLab | 또한 기본 브랜치와 태그에서 내장된 |
기본 이미지 태그 지정 동작:
트리거 | 푸시되는 태그 |
기본 브랜치 |
|
Git 태그 |
|
개발
uv run --python 3.12 --with '.[dev]' ruff check .
uv run --python 3.12 --with '.[dev]' pytest -q프로젝트 참고 사항
구현은 단일
ExchangeClient추상화를 중심으로 이루어져 인증, 전송, 재시도, 오류 매핑이 중앙 집중화됩니다.오류는 MCP
isError=true처리를 위한 구조화된 JSON 형식으로 반환됩니다.
기여하기
버그 리포트와 PR은 언제나 환영합니다 — CONTRIBUTING.md에서 개발 환경을 설정하고 실제 Exchange 서버 없이 테스트 스위트를 실행하는 방법을 확인하세요. 취약점 신고는 SECURITY.md를 참조하세요.
라이선스
MIT — LICENSE 참조.
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
- AlicenseAqualityDmaintenanceMCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.307MIT
- FlicenseAqualityBmaintenanceMCP server for corporate Exchange that provides access to email, calendar, and people directory via OWA JSON API.20
- FlicenseAqualityBmaintenanceMCP server for Claude to access on-premises Outlook/Exchange mailboxes via EWS with NTLM authentication, providing tools for email, calendar, and contact management without relying on Microsoft 365 or Graph API.18
- AlicenseNot gradedqualityAmaintenanceA local MCP server for on-premises Microsoft Exchange, connecting via EWS and NTLM. It provides mail, template, availability, and calendar workflow tools through stdio, with draft-first safety and Windows Credential Manager integration.7MIT
Related MCP Connectors
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
Fully-managed email as MCP tools - register domains, real mailboxes, send and receive mail.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
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/viartemev/outlook-ews-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server