# oakstack-mcp

Cron jobs with retries, webhook relay, HTML-to-PDF, and transactional email for your app.

- **Type:** MCP server
- **Trust:** 60/100 (B), scored on the package rubric
- **Verification:** community-indexed — nobody has claimed this listing
- **Version:** 0.5.0
- **Author:** dev.oakstack
- **License:** MIT
- **npm:** oakstack-mcp
- **Endpoints:** streamable-http https://oakstack.dev/mcp
- **Source:** https://oakstack.dev
- **Endpoint health:** reachable (last checked 2026-10-09T15:15:42.584Z, 1 sample) — uptime is not a security property and is not part of the trust score
- **Compatible clients:** claude-code, cursor, copilot, chatgpt, gemini (basis: transport)

## Trust

60/100 (B), scored on the package rubric
- Publisher verified: no
- Install scripts: nothing suspicious found
- Prompt-injection scan: not run
- Obfuscation scan: not run
- Evidence age: 3 days

## Security scan

- **Status:** clean
- **Scanned:** 2026-10-09T15:15:34.001Z
- **Version scanned:** 0.5.0
- **CVEs:** none found by OSV at scan time

## Tools

39 declared. Statically extracted from the shipped source — a floor on the surface, not a census.
- `clock_create_job` — Schedule Oakstack to call a URL in the user's app on a cron schedule (like a cron job or Vercel Cron, but with retries and a run log). Returns the job, includin
- `clock_list_jobs` — List the workspace's scheduled jobs with status, next run time, and last result.
- `clock_get_job` — Get one job, including its schedule, status, pausedReason, and signingSecret.
- `clock_update_job` — Change a job's fields, or pause/resume it with status 'paused' or 'active'. A job that auto-paused after repeated failures shows why in pausedReason; fix the UR
- `clock_delete_job` — Delete a job and its run history. This cannot be undone; prefer pausing if unsure.
- `clock_run_job` — Call the job's URL right now, outside its schedule (at most once every 10 seconds per job). Use it to test a new job. Then check clock_list_runs for the result 
- `clock_list_runs` — Recent runs of a job, newest first: status (pending, running, succeeded, failed), attempt, responseStatus, the first 2 KB of the response, and the error. Use th
- `hook_create_endpoint` — Create a permanent inbound webhook URL that stores every event and forwards it to the user's app with the original headers and body, retrying for about 11 hours
- `hook_list_endpoints` — List the workspace's webhook endpoints with their inbound URL, forward URL, and status.
- `hook_get_endpoint` — Get one endpoint, including its inbound URL and signingSecret.
- `hook_update_endpoint` — Change the name or forwardUrl, or pause/resume forwarding with status 'paused' or 'active'. Pausing holds events (they are still accepted and stored) and forwar
- `hook_delete_endpoint` — Delete an endpoint and its events. Its inbound URL stops accepting immediately, so senders will start failing. Cannot be undone; prefer pausing if unsure.
- `hook_list_events` — Recent events received by an endpoint, newest first, with delivery status (pending, delivering, delivered, failed), attempts, last response status, and last err
- `hook_get_event` — One event with its original headers, body, and every delivery attempt (status code, response snippet, error, duration). Use this to debug why the user's app rej
- `hook_replay_event` — Forward an event to the endpoint again (for example after fixing a bug in the user's webhook handler). Creates a new event linked by replayOf. Each replay count
- `lens_extract` — Read photos, screenshots, PDFs (by public URL or base64) or pasted text and return structured data. Use template 'product-list' (products, quantities, condition
- `lens_list_templates` — The hosted extraction templates with their JSON Schema.
- `post_status` — Check whether live email can be sent from this workspace: whether sending is enabled, paused (after bounces or complaints), limited to workspace members (Free p
- `post_send_email` — Send a transactional email. `from` must use a verified domain (see post_add_domain). With an ok_test_ key nothing is delivered: delivery is simulated and logged
- `post_list_emails` — Recent emails, newest first, with status (queued, sent, delivered, bounced, complained, failed, suppressed). Filter by status to debug.
- `post_get_email` — One email with its body and every event: sent, delivered, bounced (with the receiving server's reason), complained, suppressed.
- `post_add_domain` — Add a domain to send from. Returns DNS records: the user must add the required ones (3 DKIM CNAMEs) at their DNS provider; the recommended ones improve delivera
- `post_list_domains` — The workspace's sending domains with status (pending, verified, failed) and their DNS records.
- `post_verify_domain` — Check a pending domain's DNS records right away instead of waiting for the automatic check.
- `post_create_inbound_address` — Create an email address whose incoming mail is parsed (from, subject, text, html, attachments) and delivered as JSON to a webhook endpoint (create one with hook
- `print_list_templates` — List the hosted PDF templates (invoice, proposal, report). Each has a JSON Schema for its data and a working example. Call this before print_create_pdf with a t
- `print_create_pdf` — Render a PDF from a full HTML document (`html`) or a hosted template (`template` + `data`). Returns the PDF with a private download `url` valid for an hour, pag
- `print_list_pdfs` — Recent PDFs, newest first, with status (rendering, succeeded, failed), error, page count, and a fresh download url. Filter with status 'failed' to debug.
- `print_get_pdf` — One PDF with a fresh download url (valid an hour), its error if it failed, and any resources the page tried to load that were blocked.
- `ring_status` — Check whether live texts (SMS) can go out from this workspace: whether texting is enabled, the plan allows it (not on Free), numbers and their toll-free verific
- `ring_send_text` — Send an SMS to a US or Canadian phone. Comes from the workspace's approved toll-free number (or, before it's approved, the sandbox number to verified phones onl
- `ring_list_texts` — Recent texts, newest first, sent and received (direction 'inbound' are replies). Status: queued, sent, delivered, undelivered, failed, opted_out, canceled, rece
- `ring_get_text` — One text with every event (sent, delivered, undelivered with Twilio's error code).
- `ring_list_numbers`
- `ring_set_reply_hook`
- `ring_add_opt_out`
- `oakstack`
- `oakstack_usage`
- `oakstack_docs`

## Install

**Verdict: review** — Installable, but 1 thing to check first: No publisher has proved control of this listing; it is indexed, not vouched for.
**Cautions** (coverage gaps and advisories — never blocking)
- No publisher has proved control of this listing; it is indexed, not vouched for.
**Config** (claude-code):
```json
"{\n  \"mcpServers\": {\n    \"oakstack\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"oakstack-mcp\"\n      ],\n      \"env\": {\n        \"OAKSTACK_API_KEY\": \"<YOUR_OAKSTACK_API_KEY>\"\n      }\n    }\n  }\n}"
```
**Credentials it will ask for** (names only — Forge never holds a value):
- `OAKSTACK_API_KEY` — Oakstack API Key (required)
Placeholders only. Forge never holds, brokers, or transmits a credential value — replace each <YOUR_NAME> in your own config file. Do not send a value back to Forge; no Forge endpoint accepts one.
- This entry needs 1 credential (1 required). The generated config carries placeholders, so it will fail in the editor rather than at runtime if they are left unset.

## Blast radius

Extensive blast radius — deletes data; runs locally and hosted.
- Floor 57, ceiling 57 (tier: extensive)
- This is impact, not likelihood. A high radius is not a defect: a filesystem server is supposed to write files. It is never part of the trust score.

## Machine-readable views of this entry

- Signed JSON: https://forgeregistry.com/api/v1/packages/oakstack-mcp
- Install plan: https://forgeregistry.com/api/v1/packages/oakstack-mcp/install-plan
- Alternatives: https://forgeregistry.com/api/v1/alternatives/oakstack-mcp
- HTML page: https://forgeregistry.com/registry/oakstack-mcp
- MCP: POST https://forgeregistry.com/api/mcp → `forge_get_package` / `forge_install_plan`

## About this document

Generated by Forge (https://forgeregistry.com) — a compact rendering of the same record served, signed, at the JSON URL above. Trust and scan facts are the registry's own measurements; anything Forge did not measure is named as unmeasured rather than omitted.
