Metadata-Version: 2.4
Name: nornweave
Version: 0.1.4
Summary: Open-source, self-hosted Inbox-as-a-Service API for AI Agents
Project-URL: Homepage, https://github.com/DataCovey/nornweave
Project-URL: Documentation, https://nornweave.datacovey.com/docs/
Project-URL: Repository, https://github.com/DataCovey/nornweave
Project-URL: Issues, https://github.com/DataCovey/nornweave/issues
Project-URL: Changelog, https://github.com/DataCovey/nornweave/blob/main/CHANGELOG.md
Author: NornWeave Contributors
Maintainer: NornWeave Contributors
License: Apache-2.0
License-File: LICENSE
Keywords: agents,ai,api,email,inbox,llm,mcp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.14
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: alembic>=1.14.0
Requires-Dist: click>=8.1.0
Requires-Dist: cryptography>=44.0.0
Requires-Dist: email-validator>=2.2.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: html2text>=2024.2.26
Requires-Dist: httpx>=0.28.0
Requires-Dist: markdown>=3.7
Requires-Dist: pydantic-settings>=2.6.0
Requires-Dist: pydantic>=2.10.0
Requires-Dist: python-multipart>=0.0.18
Requires-Dist: sqlalchemy[asyncio]>=2.0.36
Requires-Dist: svix>=1.24.0
Requires-Dist: uvicorn[standard]>=0.32.0
Provides-Extra: all
Requires-Dist: anthropic>=0.42.0; extra == 'all'
Requires-Dist: asyncpg>=0.30.0; extra == 'all'
Requires-Dist: boto3>=1.35.0; extra == 'all'
Requires-Dist: fastmcp>=2.0.0; extra == 'all'
Requires-Dist: google-cloud-storage>=2.18.0; extra == 'all'
Requires-Dist: google-genai>=1.0.0; extra == 'all'
Requires-Dist: mcp>=1.0.0; extra == 'all'
Requires-Dist: openai>=1.57.0; extra == 'all'
Requires-Dist: pgvector>=0.3.6; extra == 'all'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'all'
Requires-Dist: pypdf>=5.1.0; extra == 'all'
Requires-Dist: python-magic>=0.4.27; extra == 'all'
Requires-Dist: redis>=5.2.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.42.0; extra == 'anthropic'
Provides-Extra: attachments
Requires-Dist: pypdf>=5.1.0; extra == 'attachments'
Requires-Dist: python-magic>=0.4.27; extra == 'attachments'
Provides-Extra: dev
Requires-Dist: aiosqlite>=0.20.0; extra == 'dev'
Requires-Dist: httpx>=0.28.0; extra == 'dev'
Requires-Dist: mypy>=1.13.0; extra == 'dev'
Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Provides-Extra: gcs
Requires-Dist: google-cloud-storage>=2.18.0; extra == 'gcs'
Provides-Extra: gemini
Requires-Dist: google-genai>=1.0.0; extra == 'gemini'
Provides-Extra: llm
Requires-Dist: anthropic>=0.42.0; extra == 'llm'
Requires-Dist: google-genai>=1.0.0; extra == 'llm'
Requires-Dist: openai>=1.57.0; extra == 'llm'
Provides-Extra: mcp
Requires-Dist: fastmcp>=2.0.0; extra == 'mcp'
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
Provides-Extra: openai
Requires-Dist: openai>=1.57.0; extra == 'openai'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.30.0; extra == 'postgres'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgres'
Provides-Extra: ratelimit
Requires-Dist: redis>=5.2.0; extra == 'ratelimit'
Provides-Extra: s3
Requires-Dist: boto3>=1.35.0; extra == 's3'
Provides-Extra: search
Requires-Dist: openai>=1.57.0; extra == 'search'
Requires-Dist: pgvector>=0.3.6; extra == 'search'
Description-Content-Type: text/markdown

<p align="center">
  <img src="web/static/images/Nornorna_spinner.jpg" alt="The Norns weaving fate at Yggdrasil" width="400">
</p>

<h1 align="center">NornWeave</h1>

<p align="center">
  <em>"Laws they made there, and life allotted / To the sons of men, and set their fates."</em><br>
  - Voluspa (The Prophecy of the Seeress), Poetic Edda, Stanza 20
</p>

<p align="center">
  <strong>Open-source, self-hosted Inbox-as-a-Service API for AI Agents</strong>
</p>

<p align="center">
  <a href="https://github.com/DataCovey/nornweave/actions"><img src="https://github.com/DataCovey/nornweave/workflows/CI/badge.svg" alt="CI Status"></a>
  <a href="https://github.com/DataCovey/nornweave/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License"></a>
</p>

---

## What is NornWeave?

Standard email APIs are stateless and built for transactional sending. **NornWeave** adds a **stateful layer** (Inboxes, Threads, History) and an **intelligent layer** (Markdown parsing, Semantic Search) to make email consumable by LLMs via REST or MCP.

In Norse mythology, the Norns (Urdr, Verdandi, and Skuld) dwell at the base of Yggdrasil, the World Tree. They weave the tapestry of fate for all beings. Similarly, NornWeave:

- Takes raw "water" (incoming email data streams)
- Weaves disconnected messages into coherent **Threads** (the Tapestry)
- Nourishes AI Agents with clean, structured context

## Features

### Foundation (The Mail Proxy)
- **Virtual Inboxes**: Create email addresses for your AI agents
- **Webhook Ingestion**: Receive emails from Mailgun, SES, SendGrid, Resend
- **Persistent Storage**: PostgreSQL with abstracted storage adapters
- **Email Sending**: Send replies through your configured provider

### Intelligence (The Agent Layer)
- **Content Parsing**: HTML to clean Markdown, cruft removal
- **Threading**: Automatic conversation grouping via email headers
- **MCP Server**: Connect directly to Claude, Cursor, and other MCP clients
- **Attachment Processing**: Extract text from PDFs and documents

### Enterprise (The Platform Layer)
- **Semantic Search**: Vector embeddings with pgvector
- **Real-time Webhooks**: Get notified of new messages
- **Rate Limiting**: Protect against runaway agents
- **Multi-Tenancy**: Organizations and projects

## Quick Start

### Install from PyPI

```bash
# Base installation (SQLite, all email providers)
pip install nornweave

# With PostgreSQL support
pip install nornweave[postgres]

# With MCP server for AI agents
pip install nornweave[mcp]

# Full installation
pip install nornweave[all]
```

### Using Docker (Recommended for Production)

```bash
# Clone the repository
git clone https://github.com/DataCovey/nornweave.git
cd nornweave

# Copy environment configuration
cp .env.example .env
# Edit .env with your API keys

# Start the stack
docker compose up -d

# Run migrations
docker compose exec api alembic upgrade head
```

### Using uv (Development)

```bash
# Clone the repository
git clone https://github.com/DataCovey/nornweave.git
cd nornweave

# Install dependencies
make install-dev

# Copy environment configuration
cp .env.example .env

# Start PostgreSQL (or use your own)
docker compose up -d postgres

# Run migrations
make migrate

# Start the development server
make dev
```

### Configure Your Email Provider

1. Set `EMAIL_PROVIDER` in `.env` (e.g., `mailgun`)
2. Add your provider's API key
3. Configure the webhook URL in your provider's dashboard:
   ```
   https://your-server.com/webhooks/mailgun
   ```

## API Overview

### Create an Inbox

```bash
curl -X POST http://localhost:8000/v1/inboxes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Support Agent", "email_username": "support"}'
```

### Read a Thread

```bash
curl http://localhost:8000/v1/threads/th_123 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Response (LLM-optimized):
```json
{
  "id": "th_123",
  "subject": "Re: Pricing Question",
  "messages": [
    { "role": "user", "author": "bob@gmail.com", "content": "How much is it?", "timestamp": "..." },
    { "role": "assistant", "author": "agent@myco.com", "content": "$20/mo", "timestamp": "..." }
  ]
}
```

### Send a Reply

```bash
curl -X POST http://localhost:8000/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inbox_id": "ibx_555",
    "reply_to_thread_id": "th_123",
    "to": ["client@gmail.com"],
    "subject": "Re: Pricing Question",
    "body": "Thanks for your interest! Our pricing starts at $20/mo."
  }'
```

## MCP Integration

NornWeave exposes an MCP server for direct integration with Claude, Cursor, and other MCP-compatible clients.

### Available Tools

| Tool | Description |
|------|-------------|
| `create_inbox` | Provision a new email address |
| `send_email` | Send an email (auto-converts Markdown to HTML) |
| `search_email` | Find relevant messages in your inbox |
| `wait_for_reply` | Block until a reply arrives (experimental) |

### Configure in Cursor/Claude

```bash
pip install nornweave[mcp]
```

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

## Architecture

NornWeave uses a thematic architecture inspired by Norse mythology:

| Component | Name | Purpose |
|-----------|------|---------|
| Storage Layer | **Urdr** (The Well) | Database adapters (PostgreSQL, SQLite) |
| Ingestion Engine | **Verdandi** (The Loom) | Webhook processing, HTML to Markdown |
| API & Outbound | **Skuld** (The Prophecy) | REST API, email sending, rate limiting |
| Gateway | **Yggdrasil** | API router connecting all providers |
| MCP Tools | **Huginn & Muninn** | Read/write tools for AI agents |

## Supported Providers

| Provider | Sending | Receiving | Auto-Route Setup |
|----------|---------|-----------|------------------|
| Mailgun | yes | yes | yes |
| AWS SES | yes | yes | manual |
| SendGrid | yes | yes | yes |
| Resend | yes | yes | yes |

## Documentation

- [Getting Started Guide](https://nornweave.datacovey.com/docs/getting-started/)
- [API Reference](https://nornweave.datacovey.com/docs/api/)
- [Architecture Overview](https://nornweave.datacovey.com/docs/concepts/architecture/)
- [Provider Setup Guides](https://nornweave.datacovey.com/docs/guides/)

## Repository Structure

This is a monorepo:

- **`src/nornweave/`** – Main NornWeave server components
- **`clients/python/`** – Python client SDK (`nornweave-client`)
- **`packages/n8n-nodes-nornweave/`** – n8n community node (`@nornweave/n8n-nodes-nornweave`)

The root **`credentials`** symlink points to `packages/n8n-nodes-nornweave/credentials` so n8n’s package verification can find the credential file when checking the repo.

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## License

NornWeave is open-source software licensed under the [Apache 2.0 License](LICENSE).

---

<p align="center">
  <sub>Image: "Nornorna spinner odet tradar vid Yggdrasil" by L. B. Hansen</sub><br>
  <sub><a href="https://commons.wikimedia.org/w/index.php?curid=164065">Public Domain</a></sub>
</p>
