MCP Integration Guide

NornWeave exposes an MCP (Model Context Protocol) server that allows Claude, Cursor, LangChain, and other MCP-compatible clients to interact with email directly.

Installation

Install NornWeave with MCP support:

pip install nornweave[mcp]

Configuration

Add NornWeave to your MCP client configuration:

Claude Desktop / Cursor

{
  "mcpServers": {
    "nornweave": {
      "command": "nornweave",
      "args": ["mcp"],
      "env": {
        "NORNWEAVE_API_URL": "http://localhost:8000"
      }
    }
  }
}
Make sure the NornWeave API server is running before using MCP. Start it with nornweave api.

Environment Variables

VariableDescriptionDefault
NORNWEAVE_API_URLNornWeave REST API URLhttp://localhost:8000
NORNWEAVE_API_KEYAPI key for authentication (not yet enforced)(none)

Transports

NornWeave MCP server supports three transport types:

stdio (Default)

For Claude Desktop, Cursor, and local CLI usage:

nornweave mcp
# or explicitly:
nornweave mcp --transport stdio

SSE (Server-Sent Events)

For web-based MCP clients and browser integrations:

nornweave mcp --transport sse --host 0.0.0.0 --port 3000

HTTP (Streamable)

For cloud deployments, load balancing, and LangChain integration:

nornweave mcp --transport http --host 0.0.0.0 --port 3000

Resources (Read-Only)

MCP Resources provide read-only access to email data.

Recent Threads

email://inbox/{inbox_id}/recent

Returns the last 10 thread summaries for an inbox.

Example Response:

[
  {
    "id": "th_123",
    "subject": "Re: Pricing Question",
    "last_message_at": "2025-01-31T10:05:00Z",
    "message_count": 2,
    "participants": ["bob@gmail.com", "support@mail.yourdomain.com"],
    "summary": "Customer asked about pricing. Support replied with $20/month starting price."
  }
]
The summary field contains an LLM-generated thread summary when LLM summarization is enabled. It is null when the feature is disabled or the summary hasn’t been generated yet.

Thread Content

email://thread/{thread_id}

Returns the full thread content in Markdown format, optimized for LLM context.

Example Response:

## Thread: Re: Pricing Question

## Summary

Customer asked about pricing. Support replied with $20/month starting price.

**From:** bob@gmail.com ←
**Date:** 2025-01-31 10:00

Hi, how much does your service cost?

---

**From:** support@mail.yourdomain.com →
**Date:** 2025-01-31 10:05

Thanks for reaching out! Our pricing starts at $20/month.

Tools (Actions)

MCP Tools allow AI agents to perform actions.

create_inbox

Provision a new email address for the agent.

Arguments:

NameTypeRequiredDescription
namestringYesDisplay name for the inbox
usernamestringYesLocal part of email address

Example:

Create a new inbox called "Sales Bot" with username "sales"

send_email

Send an email, automatically converting Markdown to HTML.

Arguments:

NameTypeRequiredDescription
inbox_idstringYesInbox ID to send from
recipientstringYesEmail address to send to
subjectstringYesEmail subject
bodystringYesMarkdown content
thread_idstringNoThread ID for replies

Example:

Send an email to bob@gmail.com with subject "Thanks for your interest" 
saying "We'd love to schedule a demo. Are you available next week?"
When thread_id is provided, NornWeave handles all threading headers automatically.

list_messages

List messages with flexible filters.

Arguments:

NameTypeRequiredDescription
inbox_idstringOne of theseFilter by inbox
thread_idstringOne of theseFilter by thread
limitnumberNoMax results (default: 50)
offsetnumberNoPagination offset (default: 0)
At least one of inbox_id or thread_id must be provided.

Example:

List all messages in the support inbox

Returns:

Messages with full email metadata including subject, from_address, to_addresses, text, html, timestamp, labels, and more.

search_email

Search for messages with flexible filters.

Arguments:

NameTypeRequiredDescription
querystringYesSearch query (subject, body, sender, attachment filenames)
inbox_idstringOne of theseFilter by inbox
thread_idstringOne of theseFilter by thread
limitnumberNoMax results (default: 10)
offsetnumberNoPagination offset (default: 0)
At least one of inbox_id or thread_id must be provided. Search looks across subject, body, sender address, and attachment filenames.

Example:

Search for emails about "invoice" in the support inbox
Search for messages with attachments named "contract" in thread th_123

send_email_with_attachments

Send an email with file attachments.

Arguments:

NameTypeRequiredDescription
inbox_idstringYesInbox ID to send from
recipientstringYesEmail address to send to
subjectstringYesEmail subject
bodystringYesMarkdown content
attachmentsarrayYesList of attachments
thread_idstringNoThread ID for replies

Attachment Object:

NameTypeRequiredDescription
filenamestringYesOriginal filename
content_typestringYesMIME type (e.g., application/pdf)
contentstringYesBase64-encoded file content

Example:

Send an email to client@example.com with a PDF attachment 
Subject: "Contract for Review"
Body: "Please review the attached contract."
Attach: contract.pdf (application/pdf)

list_attachments

List attachments for a message, thread, or inbox.

Arguments:

NameTypeRequiredDescription
message_idstringOne of theseFilter by message
thread_idstringOne of theseFilter by thread
inbox_idstringOne of theseFilter by inbox

Example:

List all attachments for message msg_001

Returns:

[
  {
    "id": "att_789",
    "message_id": "msg_001",
    "filename": "document.pdf",
    "content_type": "application/pdf",
    "size": 102400
  }
]

get_attachment_content

Get the content of an attachment.

Arguments:

NameTypeRequiredDescription
attachment_idstringYesAttachment ID
formatstringNobase64 (default) or binary

Example:

Get the content of attachment att_789 as base64

Returns (base64):

{
  "content": "JVBERi0xLjQKJeLjz9M...",
  "content_type": "application/pdf",
  "filename": "document.pdf"
}
For MCP, base64 format is recommended as it’s easier to handle in JSON-based protocols.

wait_for_reply (Experimental)

Block execution until a new email arrives in a thread. Useful for synchronous agent scripts.

Arguments:

NameTypeRequiredDescription
thread_idstringYesThread to wait on
timeout_secondsnumberNoMax wait time (default: 300)

Example:

Wait for a reply to thread th_123 for up to 5 minutes
This tool is experimental and uses polling. It may not be suitable for all use cases.

Usage Examples

Natural Language with Claude

Once configured, you can interact with NornWeave using natural language:

“Check my support inbox for any new messages”

“Reply to the pricing question thread saying we offer a 14-day free trial”

“Create a new inbox for handling sales inquiries”

“Search for any emails mentioning ‘refund’ in the support inbox”

Automated Agent Script

# Pseudo-code for an agent workflow

# 1. Check for new messages
recent = mcp.resource("email://inbox/ibx_support/recent")

for thread in recent:
    if is_urgent(thread):
        # 2. Get full context
        content = mcp.resource(f"email://thread/{thread.id}")
        
        # 3. Generate response
        response = llm.generate(
            prompt=f"Respond to this email:\n{content}"
        )
        
        # 4. Send reply
        mcp.tool("send_email", {
            "inbox_id": "ibx_support",
            "recipient": thread.participants[0],
            "subject": f"Re: {thread.subject}",
            "body": response,
            "thread_id": thread.id
        })

MCP Registries

NornWeave is available on popular MCP registries:

Troubleshooting

MCP Server Not Found

Ensure NornWeave is installed with MCP support:

pip install nornweave[mcp]
which nornweave

Connection Refused

Make sure the NornWeave API server is running:

# Start the API server
nornweave api

# Verify it's running
curl http://localhost:8000/health

Connection Errors

If the MCP server can’t reach the API, verify the URL and that the API is running:

export NORNWEAVE_API_URL=http://localhost:8000
nornweave mcp

Or in your MCP client configuration:

{
  "mcpServers": {
    "nornweave": {
      "command": "nornweave",
      "args": ["mcp"],
      "env": {
        "NORNWEAVE_API_URL": "http://localhost:8000"
      }
    }
  }
}

SSE/HTTP Transport Issues

For network transports, ensure the port is available:

# Check if port 3000 is in use
lsof -i :3000

# Use a different port
nornweave mcp --transport sse --port 3001