AI agent이 테스트용 인박스를 생성하고 OTP 또는 매직 링크가 도착할 때까지 자동으로 대기하여 애플리케이션을 테스트할 수 있습니다.
다른 이름 mailsocket/mailsocket-sdk, mailsocket-mcp
- 스타
- 1
- Tools
- —
- 다운로드, 30일
- 861
- 최신 버전
- 0.4.2
- 마지막 커밋
- 2026년 11월 1일
- 라이선스
- MIT
mailsocket MCP란?
mailsocket은(는) MCP server입니다. AI agent이 테스트용 인박스를 생성하고 OTP 또는 매직 링크가 도착할 때까지 자동으로 대기하여 애플리케이션을 테스트할 수 있습니다.
프로젝트 README에서 생성된 요약
mailsocket MCP server 정보
Mailsocket은 이메일 인증이 포함된 애플리케이션 테스트를 수행하도록 설계된 AI 코딩 에이전트용 MCP server를 제공합니다. 에이전트가 전용 테스트 인박스를 생성하고 일회용 비밀번호(OTP)나 매직 링크와 같은 특정 인증 요소를 자동으로 기다릴 수 있게 해줍니다. 이를 통해 개발자가 에이전트 프롬프트나 코드베이스에 별도의 폴링 로직을 작성할 필요가 없습니다.
사용자는 uvx 또는 pip를 사용하여 stdio를 통해 이 서버를 로컬에서 실행하거나, HTTP를 통해 원격 호스팅 버전에 연결할 수 있습니다. 서버를 사용하려면 환경 변수 또는 authorization header를 통해 Mailsocket API key를 제공해야 합니다. 테스트 라이프사이클 관리를 위해 create_inbox, wait_for_otp, wait_for_link와 같은 특화된 도구를 포함합니다. 빠른 디버깅을 위해 send_test_code 도구를 사용하면 실제 메일 서버의 처리를 기다리지 않고 인박스에 샘플 OTP를 직접 주입할 수 있습니다.
활용 사례
- 1자동 OTP 추출AI agent이 새 인박스에 도착하는 인증 코드를 기다린 후 문자열을 자동으로 추출할 수 있습니다.
- 2매직 링크 추출서버가 수신된 이메일에서 특정 인증 링크를 식별하여 에이전트가 사용할 수 있도록 반환합니다.
- 3이메일 루프 테스트개발자가 인박스에 가짜 코드를 즉시 주입하여 에이전트의 대기 로직을 검증할 수 있습니다.
- 4인박스 관리에이전트가 테스트 완료 후 임시 메일함을 삭제하여 테스트 환경을 정리할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
mailsocket MCP 설치 방법
형식 확인: 2026년 11월 10일Claude Code에 mailsocket MCP 설치
$ claude mcp add --env MAILSOCKET_API_KEY=<YOUR_MAILSOCKET_API_KEY> mailsocket-mcp -- uvx mailsocket-mcpCursor에 mailsocket MCP 설치
~/.cursor/mcp.json
{
"mcpServers": {
"mailsocket-mcp": {
"command": "uvx",
"args": [
"mailsocket-mcp"
],
"env": {
"MAILSOCKET_API_KEY": "<YOUR_MAILSOCKET_API_KEY>"
}
}
}
}VS Code에 mailsocket MCP 설치
.vscode/mcp.json
{
"servers": {
"mailsocket-mcp": {
"type": "stdio",
"command": "uvx",
"args": [
"mailsocket-mcp"
],
"env": {
"MAILSOCKET_API_KEY": "<YOUR_MAILSOCKET_API_KEY>"
}
}
}
}Claude Desktop에 mailsocket MCP 설치
claude_desktop_config.json
{
"mcpServers": {
"mailsocket-mcp": {
"command": "uvx",
"args": [
"mailsocket-mcp"
],
"env": {
"MAILSOCKET_API_KEY": "<YOUR_MAILSOCKET_API_KEY>"
}
}
}
}Codex에 mailsocket MCP 설치
~/.codex/config.toml
[mcp_servers.mailsocket-mcp] command = "uvx" args = ["mailsocket-mcp"] [mcp_servers.mailsocket-mcp.env] MAILSOCKET_API_KEY = "<YOUR_MAILSOCKET_API_KEY>"
Gemini CLI에 mailsocket MCP 설치
~/.gemini/settings.json
{
"mcpServers": {
"mailsocket-mcp": {
"command": "uvx",
"args": [
"mailsocket-mcp"
],
"env": {
"MAILSOCKET_API_KEY": "<YOUR_MAILSOCKET_API_KEY>"
}
}
}
}구성
MAILSOCKET_API_KEY필수비밀mailsocket API key (ms_live_...). Create one in the dashboard or via POST /api/v1/agents/register.
MAILSOCKET_BASE_URLOverride the API base URL. Defaults to https://dash.mailsocket.app/api/v1.
| 이름 | 설명 | 유형 |
|---|---|---|
| MAILSOCKET_API_KEY | mailsocket API key (ms_live_...). Create one in the dashboard or via POST /api/v1/agents/register. | 필수비밀 |
| MAILSOCKET_BASE_URL | Override the API base URL. Defaults to https://dash.mailsocket.app/api/v1. |
자동 검사
2026년 11월 12일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 이는 보안 감사가 아닙니다. 코드를 직접 읽고 서버에 필요한 최소한의 권한만 부여하십시오. 검사 방식
- 소스 저장소 연결 및 접근 가능통과
- 오픈 소스 라이선스 (OSI)통과
- 최근 1년 내 커밋 또는 릴리스통과
- 패키지 이름이 인기 패키지와 유사하지 않음통과
- 원격 엔드포인트가 HTTPS 사용통과
- 파괴적인 도구에 라벨 표시됨검사되지 않음
- 모델에 대한 숨겨진 지침 없음통과
- 패키지와 의존성에 심각한 보안 권고 없음통과
README
GitHub에서 보기mailsocket — MCP server
An MCP server that exposes mailsocket to AI coding agents as native tools, so an agent can create a per-test inbox and block on the OTP or magic link without writing any polling code. For testing apps you own or are authorized to test. Not for creating accounts on services you don't control.
It wraps the Python SDK — no second HTTP client, no re-implemented polling.
What it does
| Tool | What the agent gets |
|---|---|
create_inbox(label?) |
a fresh inbox id + address |
wait_for_otp(inbox_id, timeout?=60, min_confidence?=0, since?) |
the headline — blocks (bounded: requested deadline clamped to 120s locally, 55s on the remote server) and returns the OTP string + confidence + subject/from/id/received_at. Default since omitted: only messages arriving after this call are matched. |
wait_for_link(inbox_id, timeout?=60, since?) |
the extracted magic link (returned, not followed) + subject/from/id/received_at. Default since omitted: only messages arriving after this call are matched. |
list_inboxes(limit?, cursor?) |
one page of inboxes owned by the key (server default page size 25) + next_cursor/has_more |
list_messages(inbox_id, has_otp?, subject_contains?, sender?, limit?, cursor?) |
one page of messages, optionally filtered (server default page size 25) + next_cursor/has_more |
get_latest(inbox_id) |
the newest message, without blocking |
send_test_code(inbox_id) |
puts one sample OTP email straight into the inbox (no mail server) and returns its message_id + sent_at, so you can check the wait loop without real email. 5 per inbox / 20 per account per hour. |
delete_inbox(inbox_id) |
remove an inbox when done |
Errors from the SDK (AuthError / NotFound / RateLimited / WaitTimeout)
are turned into clean MCP tool errors — no stack traces, and the API key is
never echoed back.
Reusing an inbox
create_inbox needs no since — a fresh inbox only ever has new messages.
By default, wait_for_otp/wait_for_link omit since entirely, so the
server matches only messages arriving AFTER the call (the request start
time). But if you reuse an existing inbox (e.g. to request a second
OTP/link), pass since explicitly: otherwise a call with no since will
correctly ignore anything already sitting in the inbox, which is right for
most reuse, but if you actually WANT to catch a code that already arrived
before you called the tool, pass either the time right before you triggered
the new email (ISO8601 or unix seconds), or the id of the last message you
saw (msg_..., meaning "only messages after that one") — both tools return
id/received_at on the matched message so you can chain since=<id> into
the next call on that same inbox.
Trying the loop without real email
send_test_code does not go through the mail server, so the code is
already in the inbox when the tool returns. Take a cutoff first: the id
from get_latest (or since=0 if the inbox is empty), or the current time.
Then call send_test_code(inbox_id), then
wait_for_otp(inbox_id, since=<that cutoff>). Without since the wait only
sees mail that arrives during the wait, so it would miss the test code.
Requirements
- Python 3.10+
- A mailsocket API key — from the dashboard or
POST /api/v1/agents/register.
Install
No install needed with uv:
uvx mailsocket-mcp
Or install with pip:
pip install mailsocket-mcp
mailsocket-mcp
Either way, it reads MAILSOCKET_API_KEY (and optional
MAILSOCKET_BASE_URL) from the environment. If the key is missing it exits
with a clear message and status 2; the key is never logged.
Register with an MCP client
Claude Desktop / Cursor
Add this to your client's MCP config file — claude_desktop_config.json for
Claude Desktop, ~/.cursor/mcp.json for Cursor:
{
"mcpServers": {
"mailsocket": {
"command": "uvx",
"args": ["mailsocket-mcp"],
"env": {
"MAILSOCKET_API_KEY": "ms_live_..."
}
}
}
}
Claude Code CLI
claude mcp add mailsocket -e MAILSOCKET_API_KEY=ms_live_... -- uvx mailsocket-mcp
Any other MCP-compatible client works the same way: point it at the
mailsocket-mcp executable (or uvx mailsocket-mcp) over stdio and pass the
key through the environment.
Remote server (no install)
The same tools are hosted at https://mcp.mailsocket.app/mcp over
Streamable HTTP. Send your key on every request as a header:
Authorization: Bearer ms_live_.... Never put the key in the URL; a
?api_key= request is rejected.
Claude Code CLI
claude mcp add --transport http mailsocket https://mcp.mailsocket.app/mcp \
--header "Authorization: Bearer ms_live_..."
Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"mailsocket": {
"url": "https://mcp.mailsocket.app/mcp",
"headers": { "Authorization": "Bearer ms_live_..." }
}
}
}
VS Code (.vscode/mcp.json)
{
"servers": {
"mailsocket": {
"type": "http",
"url": "https://mcp.mailsocket.app/mcp",
"headers": { "Authorization": "Bearer ms_live_..." }
}
}
}
Any client that can set a custom HTTP header works the same way (OpenAI Agents SDK, the n8n MCP Client node, your own code).
Things to know:
- Claude.ai, Claude Desktop connectors and Smithery need OAuth, which is planned but not available yet. Until then, use the local stdio server above in those clients (Claude Desktop), or use a header-capable client.
- On the remote server,
wait_for_otp/wait_for_linkwait at most 55s per call, which keeps each response under proxy timeouts. On a timeout, call the tool again. - The server is stateless: no session to keep, and every request is authenticated on its own. It has no key of its own and only acts with yours, under your normal API rate limits.
- Self-hosting:
mailsocket-mcp-httpruns the same server (seemailsocket_mcp/remote.pyfor its env vars).
Env vars
| Variable | Required | Description |
|---|---|---|
MAILSOCKET_API_KEY |
yes (secret) | Your mailsocket API key (ms_live_...). |
MAILSOCKET_BASE_URL |
no | Override the API base URL. Defaults to https://dash.mailsocket.app/api/v1. |
Develop
pip install -e ".[dev]"
pytest
Tests make no external or live-API requests. The SDK client is faked, and the
remote-transport tests talk to a local fake upstream on 127.0.0.1.
Changelog
- 0.4.2 — wording only: server and tool descriptions and README say "test inbox for apps you own or are authorized to test". Tool names and behaviour unchanged.
- 0.4.1 — requires
mailsocket>=0.3.1:wait_for_otp/wait_for_linkcalled withoutsinceno longer miss a message that lands between the SDK's internal long-poll calls (each follow-up call sends the cutoff the server reported inMailsocket-Wait-Since). No tool signature changes. - 0.4.0 — new
send_test_code(inbox_id)tool (stdio and the hosted remote server, under the same per-key caps as the other non-wait tools): puts one sample OTP email into your own inbox without going through the mail server. Requiresmailsocket>=0.3.0(Client.send_test_code). - 0.3.0 — BEHAVIOUR CHANGE (via
mailsocket>=0.2.0):wait_for_otp/wait_for_linknow omitsinceby default instead of forwarding0("any message already in the inbox"). The old default could return a STALE OTP/link already sitting in a reused inbox; the new default matches only messages arriving after the call. Passsince=0explicitly to keep the old behaviour. Hosted server (mcp.mailsocket.app, deployed from the repo, no new PyPI release): per-key concurrent waits raised 3 → 10 (= the Pro plan cap; the API still enforces each plan's own cap) and the shared wait pool 16 → 32, following the backend's raised wait capacity (global 64). - 0.2.3 —
wait_for_otp/wait_for_linkaccept an optionalsince(ISO8601, unix seconds or a message id) so a reused inbox returns the NEW code; results include the messageidandreceived_at. - 0.2.2 — depends on
mailsocket>=0.1.3(stricter_segid validation in the underlying Python SDK).
mailsocket MCP 질문
mailsocket MCP를 Claude Code에 추가하려면 어떻게 하나요?
터미널에서 claude mcp add --env MAILSOCKET_API_KEY=<YOUR_MAILSOCKET_API_KEY> mailsocket-mcp -- uvx mailsocket-mcp를 실행합니다. 모든 프로젝트에서 사용할 수 있게 하려면 --scope user를 추가합니다.
mailsocket MCP를 Cursor에 추가하려면 어떻게 하나요?
~/.cursor/mcp.json를 열고 mcpServers 아래에 서버를 추가합니다. 위 설치 섹션에 표시된 Cursor 구성을 사용합니다.
실제 이메일을 보내지 않고 대기 루프를 테스트하려면 어떻게 하나요?
send_test_code 도구를 사용하면 메일 서버를 거치지 않고 인박스에 샘플 OTP 이메일을 직접 넣을 수 있습니다.
기존 인박스를 재사용하면 어떻게 되나요?
재사용하는 인박스에서 새로운 코드를 정확히 포착하려면 since 파라미터에 타임스탬프나 마지막으로 확인한 메시지 ID를 명시적으로 전달해야 합니다.
OTP나 링크를 기다리는 타임아웃이 있나요?
네, 요청한 데드라인은 로컬에서 120s로 제한되며, 프록시 타임아웃을 방지하기 위해 원격 서버에서는 55s로 제한됩니다.