Metadata-Version: 2.4
Name: daknode-mcp
Version: 0.1.0
Summary: DakNode's email API as MCP tools for AI agents, over stdio.
Project-URL: Homepage, https://daknode.com
Project-URL: Documentation, https://daknode.com/developers
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: daknode<0.2,>=0.1
Requires-Dist: mcp<3,>=2.2

# DakNode MCP server

DakNode's API as MCP tools, over **stdio**. The client launches it as a
subprocess; there is no hosted endpoint and no infrastructure.

## Install

Python 3.10+. With [uv](https://docs.astral.sh/uv/), nothing needs installing
up front — the client starts it with `uvx`. Otherwise `pipx install daknode-mcp`.

Get an API key with the two-request signup at <https://daknode.com/developers>.

## Configure

```json
{
  "mcpServers": {
    "daknode": {
      "command": "uvx",
      "args": ["daknode-mcp"],
      "env": { "DAKNODE_API_KEY": "…" }
    }
  }
}
```

With `pipx`, use `"command": "daknode-mcp"` and no `args`. From a repository
checkout, `"command": "python", "args": ["-m", "mcp_server.server"]`.

The key comes from the environment and **never from a command-line argument**:
argv is visible to every process through `ps`, and shells record it in history.
The server refuses to start without it, so a misconfiguration is obvious at
launch rather than looking like a broken tool.

## Tools

`create_inbox` · `list_threads` · `list_messages` · `get_thread` · `get_message`
· `search` · `send`

**Every tool is 1:1 with a published API operation.** That is `architecture.md`
§0 consequence 4, and it is the boundary this server exists inside: DakNode
exposes operations, the agent decides which to call. A tool like
`reply_to_latest` or `auto_respond` would cross that line — DakNode would be
choosing which message to answer — **while looking like a convenience**.
`tests/test_mcp_server.py` enforces it rather than leaving it to review.

## What is deliberately absent

**Erasure.** It is irreversible, and an agent that can erase a data subject
through a tool call is a liability no convenience justifies. It stays an
explicit API call a human integrates.

**Console and operator APIs.** Not a product surface.

## Notes for whoever uses this

`send` without `thread_id` opens a **new** conversation in the recipient's
client. Pass `thread_id` to reply into an existing one — the server then derives
`In-Reply-To` and `References` from that thread's latest received message.

`search` returns identifiers and scores, **not content**. Resolve them with
`get_message` or `get_thread`.

`body_text` is already cleaned: quoted history and signatures are stripped.
Check `risk_level` before feeding content to a model — `high` means
prompt-injection patterns were detected in mail from the internet.
