# Interfaces

> Agent NAS uses files for the data plane and tools for the control plane: bytes travel over mounts, Git and S3; authorization, approval, memory, search and explanation go through MCP, HTTP and a CLI. Every interface is a projection of the same data, and differences in semantics are expressed as explicit errors instead of being pretended away.

## Principles

1. **Files for the data plane, tools for the control plane.** Bytes travel over mounts, Git and S3; authorization, approval, memory, search and explanation go through MCP, HTTP and a CLI.
2. **Gateways are stateless.** Authorization happens at exactly one point in the Trust layer.
3. **Every interface is a projection.** Differences in semantics are expressed through explicit error mappings (for example “gate pending” maps to an `EACCES` with an explanatory file), and S3 is not pretended to have branches.
4. **A narrow tool surface.** No more than 10 MCP tools face agents; actions for people and operators live in a separate operator interface.
5. **Adapters isolate protocol change.** Version changes in MCP and A2A only affect the adapters.

## Interface matrix

| Interface | Plane | Aimed at | Mapping | Level |
| --- | --- | --- | --- | --- |
| Mount (FUSE, NFS, SMB) | Data | Agents, people, any program | A branch view; error mapping below | L0 |
| Git (SSH, HTTPS) | Data | Agents, people, CI | A run branch is a Git branch; an Agent PR is a merge request | L0 |
| S3-compatible | Data | Data pipelines, batch jobs | A bucket maps to a branch view of one tree; a version ID is a commit | L0 (optional) |
| WebDAV | Data | People (Finder, Explorer) | A read-only activity view | L0 (optional) |
| CLI `nas` | Control | People, scripts | One to one with the HTTP API | L0 |
| HTTP API | Control | Orchestrators, the control room | All `POST` with JSON; fields in `snake_case` | L1 |
| MCP | Control | Agents | Nine tools (below) | L1, L2 |
| A2A | Control | Other agents | A task maps to `inbox/` and `outbox/` | L4 (optional) |

## The MCP tool surface

Only nine tools face agents:

| Tool | What it does | Lease action needed | Note |
| --- | --- | --- | --- |
| `nas_list` | List a directory, with labels and review state | `list` | Paths outside the lease are invisible. |
| `nas_read` | Budgeted read: view, range, budget | `read` | [Budgeted Reads](https://agentnas.com/concepts/budgeted-reads/) |
| `nas_search` | Search (full-text, optionally vector), returning snippets and pointers | `read` | Quarantine is excluded by default. |
| `nas_write` | Write a file inside the branch, with an optional `intent` | `write` | Most runtimes use the mount directly and do not need it. |
| `nas_branch` | Create, checkpoint, restore and list branches | `write` | [Agent Branch](https://agentnas.com/concepts/agent-branch/) |
| `nas_propose` | Create an Agent PR | `propose` | May trigger a gate. |
| `nas_lease` | Request a narrower child lease; query the current lease and budgets; request wider authority (via a gate) | None | [Capability Lease](https://agentnas.com/concepts/capability-lease/) |
| `nas_remember` | Write a note, with sources and kind | `write` | [Agent Memory](https://agentnas.com/concepts/agent-memory/) |
| `nas_recall` | Recall notes: budgeted, with sources and review state | `read` | [Agent Memory](https://agentnas.com/concepts/agent-memory/) |

> **Actions for people and operators only.** `explain`, `gate approve/deny`, `forget`, `trash restore`, `label admin`, `lease revoke` and `policy edit` are **not exposed** to agents. These actions change the guarantees themselves and should not be callable by the party being constrained. An agent may **request** some of them (wider authority, forgetting) but cannot execute them.

## Mount semantics

- A mount binds **one branch and one lease**; when the lease expires the mount turns read-only and is then unmounted.
- Automatic commits (debounced, for example after 5 quiet seconds); `fsync` triggers a commit.
- Paths outside the lease **do not appear in directory listings:** this reduces information leakage and shrinks the attack surface for prompt injection.
- Sandbox-friendly: no root needed; FUSE or NFS, one of the two, with no kernel module; read-only mounts are possible.

| Situation | POSIX error | Note |
| --- | --- | --- |
| A path outside the lease | `ENOENT` (`EACCES` when visible but refused) | The refusal is recorded. |
| Quota or budget exhausted | `EDQUOT` | Lets the run throttle itself. |
| Gate pending | `EACCES`, with an explanation in `/.nas/pending` | Keeps the agent from retrying forever. |
| Lease expired | `ESTALE`, then read-only | The branch is kept until its own TTL expires. |

## Git

- Run branches are named `<role>/<run_id>`; `main` is protected, and a server-side `pre-receive` hook rejects direct pushes.
- `nas propose` creates an Agent PR.
- Commits automatically carry trailers such as `Run:`, `Lease:` and `Principal:`.

## S3

- A bucket corresponds to a branch view of one tree; an object version ID is a commit.
- Semantics S3 lacks, such as branches, are expressed with a bucket prefix or a request header (`x-nas-branch`). This is a **degraded projection:** data pipelines can read and write, but do not get the full branch experience.
- Leases are passed as STS-style temporary credentials.

## A2A (optional)

- Incoming tasks land as task files in `inbox/`; deliverables go into `outbox/`.
- The Agent Card declares the role’s skills and the leases it needs.
- **The NAS is not an A2A participant;** the runtime acting for the role is. The NAS only stores tasks and deliverables, handoff bundles and leases.

## HTTP API conventions

- **Every endpoint uses `POST`, with parameters in a JSON body;** response fields are always `snake_case`.
- Paths are versioned: `/v1/...`.
- Idempotency: write operations accept an `idempotency_key`.
- Pagination: `cursor` plus `limit`.
- Budgets and rate limits are fed back in response headers (bytes left, requests left) so runtimes can throttle themselves.

A budgeted read request and response look roughly like this:

*Budgeted read*

```http
POST /v1/files/read
{ "path": "/agents/cleo/memory/notes/customer-acme.md",
  "view": "outline", "budget_tokens": 400 }

200 OK
{ "view": "outline", "tokens": 212, "generated": false, "truncated": false,
  "content": "# Acme\n## Renewal (L12-L18)\n## Contacts (L19-L31)\n## Open issues (L32-L40)",
  "evidence": [
    { "pointer": "nas://home-box/agents/cleo/memory/notes/customer-acme.md@9f2c1de#L1-L40" }
  ] }
```

Errors use one uniform structure:

*Error response*

```json
{
  "error": {
    "code": "gate_required",
    "message": "This merge requires human approval.",
    "retryable": false,
    "request_id": "req_01JB7W2X4N",
    "details": { "gate_id": "gt_2Mx4" }
  }
}
```

## Discovery

- The machine-readable entry points are the same as on this site: `/.well-known/ai-catalog.json`, the MCP Server Card and `llms.txt`.
- An endpoint that resolves and verifies `nas://` evidence pointers.
- MCP `server/discover`.

---

Canonical URL: https://agentnas.com/interfaces/
Updated: 2026-11-11 · Draft specification v0.2 · CC BY 4.0
