Skip to main content
Glama
README.md
# docshare

Hand someone a PDF and actually know what happened to it.
docshare talks to EveryPage: you upload a document once,
share the tracked link it gives back, and from then on every
open, download, and email-gate completion is recorded
against that link — or, with variants, against the exact
recipient you sent it to.

There are fifteen tools. Sharing and lifecycle:
`everypage_share_pdf` uploads a PDF from a local path or an
https URL and can apply its share settings in the same
call; `everypage_list_files` and `everypage_get_file`
browse what you have shared; `everypage_update_file_settings`
changes the passcode, expiry, download permission, viewer
mode, email gate, view limit, page range, or slug;
`everypage_replace_content` swaps the PDF behind a live
link while the link and its history stay put; and
`everypage_delete_file` trashes a document, or purges it
for good when you ask for that explicitly.

Readership: `everypage_get_readership` reports who read a
document, how far they got, and where they dropped off,
while `everypage_list_events` streams recent views,
downloads, or captured leads behind a polling cursor you
carry from one call to the next (a cursor only works for
the stream type it came from).

Variants and webhooks: `everypage_create_variants` makes
one tracked link per named recipient, `everypage_list_variants`,
`everypage_update_variant`, and `everypage_delete_variant`
manage them (including GDPR redaction of a recipient's
name), `everypage_list_webhooks` and `everypage_manage_webhook`
look after webhook endpoints and their delivery health,
and `everypage_account` shows the connected account, its
plan, and what that plan allows.

A file argument is forgiving about form: paste the UUID,
the short link id, or the full share URL — `/embed/` links
and links carrying `?via=` work too. Uploads are checked
before they leave the machine: the bytes must start with
the PDF magic `%PDF-`, and a PDF fetched from an https URL
is downloaded without your EveryPage key, which is only
ever sent to EveryPage itself.

## Configuration

```bash
export EVERYPAGE_API_KEY="..."            # required
export EVERYPAGE_BASE_URL="https://everypage.co"   # optional override
export EVERYPAGE_READ_ONLY="true"         # optional: read tools only
```

Without `EVERYPAGE_API_KEY`, every tool fails with
`EVERYPAGE_API_KEY is not set` before any request is made.
With `EVERYPAGE_READ_ONLY=true`, only the seven read tools
(`everypage_list_files`, `everypage_get_file`,
`everypage_get_readership`, `everypage_list_events`,
`everypage_list_variants`, `everypage_list_webhooks`,
`everypage_account`) are listed, and calling any other
tool is refused.

## CLI

Each tool is a subcommand taking one JSON argument string:

```bash
npx @reneturcios/docshare everypage_share_pdf '{"source":"./deck.pdf","settings":{"requireEmail":true}}'
npx @reneturcios/docshare everypage_list_events '{"type":"view","limit":20}'
npx @reneturcios/docshare everypage_create_variants '{"file":"https://everypage.co/s/abc123?via=email","labels":["Ana","Ben"]}'
npx @reneturcios/docshare --version
```

Output is the tool's result text (normally the upstream
JSON). Exit codes: `0` on success, `1` on a runtime error
(including a validation or upstream failure), `2` on a
usage error.

## MCP server

```bash
npx -y @reneturcios/docshare mcp
```

MCP client config:

```json
{
  "mcpServers": {
    "docshare": {
      "command": "npx",
      "args": ["-y", "@reneturcios/docshare", "mcp"],
      "env": { "EVERYPAGE_API_KEY": "..." }
    }
  }
}
```

## Docker

```bash
docker run -i -e EVERYPAGE_API_KEY=... ghcr.io/cloudcorprecords/docshare
docker run --rm -e EVERYPAGE_API_KEY=... ghcr.io/cloudcorprecords/docshare everypage_account '{}'
```

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # tsx --test test/*.test.ts (fake fetch + fake file reader, no network)
npm run dev     # run the CLI from source
```

## License

MIT — Copyright (c) 2026 Rene Turcios