Skip to main content
Glama
rajesh-taylor

@refueler/mcp-server

README.md
# @refueler/mcp-server

[![Apache 2.0](https://img.shields.io/badge/licence-Apache_2.0-blue)](./LICENSE)

---

## What this is

An MCP server that runs in your own infrastructure and gives an AI agent a
privacy-first file-transfer capability backed by Refueler Share. The server
handles local encryption, BLAKE3 chunk integrity, and upload orchestration;
the Refueler Worker relays the resulting ciphertext to R2 storage without
being able to read it. Four tools ship in v0.1: `refueler_capabilities`,
`refueler_quote`, `refueler_send_file`, and `refueler_check_transfer`.

> **Status: in development — not yet published to npm.** The Refueler
> Worker moved to direct-to-R2 uploads (`initiate` → signed uploads →
> `finalise`); `refueler_send_file` is being moved onto that path and cannot
> complete a transfer against production until it lands. This README will be
> updated when it does.

The identity rail — HMAC-authenticated, credit-pool-funded — is the first
rail this server targets. The anonymous rail, which settles transfers over Lightning
with no identity at all, gates on the B7 infrastructure milestone and is not
in this release.

---

## Trust boundary

This is the section that matters. Read it once; it decides whether this
product is right for your threat model.

**What the server does in your infrastructure**

- Chunks and encrypts files locally using AES-256-GCM before anything
  leaves the process. The session key lives in the returned `share_url`
  fragment only — it is never transmitted to the Refueler Worker, never
  written to a log, never present in any request.
- Computes a BLAKE3 hash over each ciphertext chunk and a Merkle root over
  those hashes, and hands both to the Worker when the upload is finalised.
- Holds your API credentials (`rfs_live_`, `rfs_sign_`) locally, in your
  environment. They are used to sign HMAC-SHA256 requests outbound to the
  Refueler API. They never leave your infrastructure in any request payload.
- On the anonymous rail (B7): holds a local stack of blind-signed capability
  tokens. The balance is your local state — Refueler's server is blind to it.

**What the Refueler Worker sees**

- Ciphertext chunks and their BLAKE3 hashes.
- Byte counts, UUID, credential commitment, and expiry.
- The declared Content-Type at the upload boundary, checked against an
  execution-capable denylist and not stored.
- On the identity rail: your `rfs_live_` handle and an optional
  `transfer_ref` you supply for your own attribution. No plaintext.
  No key. No passphrase.

**What the Refueler Worker never sees**

- Plaintext bytes. The Worker is a blind byte-relay; it physically cannot
  produce your file content under compulsion because it never held the key.
- The AES-256-GCM session key.
- The passphrase, if set. The Worker receives only a SHA-256 hash of the
  passphrase — not the passphrase itself.
- The filename. From SW-MCP-4 onward, the filename travels in the URL
  fragment alongside the session key, never in any request. Until that
  release, the filename is present in the upload manifest — scope your trust
  claims accordingly.
- On the anonymous rail: any identity, email address, or Supabase row. The
  anonymous rail has no identity by architectural construction, not policy.

**What "chunk integrity" means, and what it does not**

Ciphertext storage integrity is live on the Refueler Worker. At upload,
the per-chunk BLAKE3 hashes and the Merkle root over them
(`rfc6962-unbalanced-blake3-v1`) are recorded when the transfer is
finalised. On download, the Worker checks each stored chunk against that
record before serving it and refuses (`409`) on any mismatch. The claim
this supports is "the encrypted object served equals the encrypted object
stored" — ciphertext storage integrity.

It is not end-to-end file integrity. The Worker never sees plaintext, so it
cannot vouch for the file you meant to send. Only the recipient, after
decrypting, can check the plaintext — and that check never passes through
this server or the Worker.

**The server runs in your infrastructure.** Refueler has no visibility
into your MCP server process, your credential store, or your agent's
conversation history. If your security model requires an audit,
the full source is on GitHub under Apache 2.0.

---

## Requirements

- Node.js ≥ 18
- Credentials from `refueler.io/share/` — you need two keys per
  credential relationship:
  - `rfs_live_…` — identifies the API relationship
  - `rfs_sign_…` — signs outbound requests (HMAC-SHA256)
- Optional: `rfs_whsec_…` — webhook signing verification (Chartered /
  identity-API tier only)

Environment variable names:

```
REFUELER_LIVE_KEY=rfs_live_…
REFUELER_SIGN_KEY=rfs_sign_…
REFUELER_WHSEC_KEY=rfs_whsec_…   # optional; Chartered tier only
REFUELER_API_BASE=https://api.share.refueler.io
```

Use a `.env` file for local development or a secrets manager for
production. Never commit key values to version control — the `rfs_live_`
and `rfs_sign_` prefixes are pattern-matched by common secret scanners.

---

## Install

Not yet on npm (see Status above). When published:

```bash
npm install @refueler/mcp-server
```

Add to your MCP host configuration — the exact method depends on your
agent framework. The server expects credentials via environment variables
or a `.env` file in the working directory. You manage your own config;
no credentials are ever pulled from a remote source by this package.

---

## Tools

**`refueler_capabilities`** — discover the live feature set and rate card.
Unauthenticated, free, called automatically before any send. The agent
will not offer features the server cannot honour.

**`refueler_quote`** — price a transfer before committing. Returns cost in
Share credits, your remaining balance, and whether the transfer would exceed
your allocation. No spend occurs.

**`refueler_send_file`** — encrypt and send a file. Chunks, encrypts, and
BLAKE3-hashes locally; uploads ciphertext to R2; returns a `share_url` with
the session key in the fragment. Accepts an optional passphrase for a second
access factor. Deducts credits from your pool on issuance.

**`refueler_check_transfer`** — pull a signed receipt. Acceptance receipt is
available immediately after upload. Collection receipt is available once the
recipient has downloaded. These are collection receipts — they confirm
collection, not delivery; delivery to a specific person is not something the
server can verify.

**Gates on B7:** Anonymous-rail sends — where no identity is associated with
the transfer and credits settle over Lightning — require the B7/NB-4
Lightning infrastructure milestone. The tool is present in v0.1 but the
anonymous rail is not available until that milestone lands.

**Gates on Silent Drop:** `refueler_receive` — a standing agent-to-agent
inbox — is not in v0.1. A recipient in v0.1 collects via a browser link.

---

## Licence

Apache 2.0. §3 of the licence gives you an express patent licence from
contributors for their contributions, so you can build on this server
without patent risk from those who wrote it.

---

## Roadmap

- **Anonymous rail (B7):** Lightning-settled transfers with no identity
  required — credits purchased over BOLT11, stored locally, spent per send.
- **Silent Drop standing inbox (SD-block):** `refueler_receive` — publish
  a receiving address; senders lodge ciphertext without a prior link exchange.
- **Inline Lightning payment (B9+):** the agent prices a transfer, pays
  inline in the same tool call, and sends — no separate top-up step.

TDQS

A3.8/5.0

Scored across 1 tool

Disambiguation5/5

With a single tool there is no possibility of misselection or overlapping purpose. Its intent (fetch server capabilities/rate card before sending) is unambiguous.

Naming Consistency4/5

The lone name refueler_capabilities is snake_case and namespaced, which is readable and predictable. It is noun-based rather than a verb_noun action pattern, but consistency cannot really be violated with one tool.

Tool Count2/5

A single tool is far too thin for a server whose description implies a send workflow. There is no operation to actually do anything, making the surface feel like a stub.

Completeness1/5

The tool explicitly exists as a precondition for 'any send', yet no send, quote, status, or account operation is exposed. The advertised domain is essentially uncovered, leaving agents at a dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues