@forumone/throughlineBLOCK
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
A conversational content management framework. Exposes Payload CMS as a set of MCP tools so marketers can operate websites through Claude rather than a traditional admin UI.
Documentation
Full documentation lives at docs/ — getting-started tutorials, conceptual explanations of the architecture, how-to guides, per-package reference, and operations docs. Start at docs/README.md.
Status
1.0. Releases publish under latest, and a snapshot of every merge to main under next. 0.x is closed; its source stays on the v0 branch. See docs/roadmap.md for phase status, and Upgrading from 0.x to 1.0 to move a site.
Packages
Three published packages, released together at one version:
@forumone/throughline—throughline(), which registers the suite, and each part on its own subpath: publishing, approvals, the audit log, components, integrations, email, editorial reports, media, the field kit, and background jobs on Inngest or Payload Jobs@forumone/throughline-design-system— the component contract and manifest, its lint, and the manifest's Payload blocks, rendering and admin components@forumone/create-throughline— the scaffolder (pnpm create @forumone/throughline my-site), with the brand-neutral reference design system a new project starts from
Internal, non-published config packages:
@forumone/throughline-tsconfig— shared TypeScript configs@forumone/throughline-eslint-config— shared ESLint flat config@forumone/throughline-prettier-config— shared Prettier config
Using in a client project
The fastest path is the scaffolder:
pnpm create @forumone/throughline my-client-site
It asks a small set of questions and produces a pnpm monorepo with Payload, the suite registered by throughline(), and an Inngest endpoin
4fefe9156715OBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add throughline-tsconfig --env APPROVAL_TOKEN_SECRET=${APPROVAL_TOKEN_SECRET} --env INNGEST_EVENT_KEY=${INNGEST_EVENT_KEY} --env PAYLOAD_SECRET=${PAYLOAD_SECRET} --env RESEND_API_KEY=${RESEND_API_KEY} -- npx -y @forumone/[email protected]{
"mcpServers": {
"throughline-tsconfig": {
"command": "npx",
"args": [
"-y",
"@forumone/[email protected]"
],
"env": {
"APPROVAL_TOKEN_SECRET": "${APPROVAL_TOKEN_SECRET}",
"INNGEST_EVENT_KEY": "${INNGEST_EVENT_KEY}",
"PAYLOAD_SECRET": "${PAYLOAD_SECRET}",
"RESEND_API_KEY": "${RESEND_API_KEY}"
}
}
}
}Exposed tools (79)
59 read · 19 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
2 | read | Two columns |
3 | read | Three columns |
4 | read | Four columns |
Custom | read | |
Fake | read | Fake integration |
auto | read | Media\ |
build_landing_page | read | Compose a landing page from design-system blocks for a goal and an audience, as a draft. |
center | read | Center-aligned |
check | write | Whether a document would publish right now, without publishing it: every check |
check_slug | read | Whether a URL slug is free in a collection, before creating or renaming a document. Normalises it the way the slug field will (lowercase, hyphens, no accents), and if it is taken says by which document, including one in the trash, and suggests the first free alternative. |
compact | read | Small vertical margin |
compose_section | read | For a section no component fits: checks a composed section |
create_draft | write | Creates a new draft of a content type from the fields |
default | read | Standard vertical margin |
describe_content_type | read | What a content type is made of, before creating or editing one: every field an author may set, with its type, limits, whether it is required, a select\ |
design_guide | read | The design system, for choosing and filling blocks. With |
draft_post | write | Write a new post (or another article-like content type) from a topic and notes, as a draft. |
edit_blocks | write | Changes the blocks in one blocks field of a draft — |
find | read | Finds content to work on or link to. With a query across every content type, or within one |
find_anti_pattern | read | Scans a proposed composition for known design anti-patterns (multiple Heroes, Hero at the bottom of a page, etc.). Returns matches with explanation and suggested alternatives. Use before publishing to surface editorial issues. |
find_content_needing_attention | read | Lists published content that needs a review, by check: pages not revised within their threshold, pages missing a meta description or image, images in use without alt text, and any other checks the site configures. Each result names the document, why it is listed, and its admin link. Use for |
find_related | read | Looks up something a document links to — an author, a client, a taxonomy term, an image — by a few letters of its name, to get the id a field needs. Images come back with their alt text and dimensions. Which kinds exist is in each field\ |
get | read | Reads content. With |
get_approval_status | read | Returns the current status of an approval request including who decided, when, and any notes. Read-only; no audit record is written. |
get_change_history | read | Returns the complete chronological history of actions on a single document, including diffs. Use to answer |
get_content_calendar | read | One month of the content calendar: scheduled publishes, past publishes and events, by day in the site\ |
get_contract | read | Returns the full contract for a named component, including intent, composition rules, content fields, variants, tokens, accessibility requirements, examples, and anti-examples. |
get_document | write | Reads one document in the shape the write tools accept: the fields an author may set, relationships as ids, and blocks with their ids. The latest draft by default; pass draft: false for the published version. Also its status and its admin and preview links. |
get_integration_status | write | Detailed status for a single integration instance — including its last sync time, last error, and current configuration metadata (config values themselves are admin-only and not returned). |
get_publish_status | write | Returns the current publishability of a document without actually publishing: a dry run of every check |
get_ready_to_publish | write | Take an existing draft through every publishing check and, with your go-ahead, publish or request approval. |
get_recent_failures | read | Recent failed operations across all MCP servers. Use for |
get_tokens | read | Returns the design tokens a component consumes plus the configurable token-backed props and their allowed values. |
get_variants | read | Returns the available variants for a component, with descriptions and guidance about when to use each. |
insert_block | write | Adds one block to a blocks field of a draft — |
inverse | read | Dark background |
large | read | Oversized display treatment |
lg | read | Large |
linked | read | Entire card is clickable |
list_components | read | Returns the list of components available in the design system. Use this to discover what components exist before composing content. |
list_integration_types | read | Lists the integration plugins available in this deployment. Use when answering |
list_integrations | write | Lists configured integration instances and their last-sync status. Use to answer |
list_job_failures | read | Background jobs that ran out of retries, and healthchecks that failed, most recent first: what failed, when, the error, and the run id to find it in the job runner. Use for |
list_my_requests | read | Returns approval requests the current user has submitted, optionally filtered by status. Use to answer |
list_my_work | read | What is waiting on somebody: documents with unpublished changes, newest first, and scheduled publishes, soonest first, each with its admin link. These are the dashboard\ |
list_pending_approvals | read | Returns pending approval requests routed to one of the caller |
md | read | Medium (default) |
move_block | write | Moves one block within its blocks field: to the start, to the end, or after another block. Checked against the composition rules, which care about order. |
odd | read | Takes a bare string. |
primary | read | Standard background |
publish | write | Takes a document live, or changes what is live. |
query_audit | read | General-purpose audit log query. Filter by collection, document, actor, action, server, date range, or failure-only. Returns chronologically ordered results, most recent first. Use when you need a custom view of system activity that doesn |
remove_block | destructive | Removes one block from a draft |
request_approval | read | Kicks off the approval workflow for a document that requires approval before publishing. Provide a clear changesSummary explaining what changed and why; approvers see this in their notifications. Returns the approval ID, expiration time, and the list of approvers who were notified. |
respond_to_approval | read | Records an approver |
rollback | read | Rolls a document back to a prior version from Payload |
save_draft | write | Saves a draft. Without |
save_recipe | write | Saves a recipe as a draft, or updates a draft one by id. Refused if it does not pass validate_recipe, or if the recipe is approved (an approved recipe does not change: save a new one). A person approves it in the admin; until then no page using it can be published. |
schedule_publish | write | Schedules a future publish. Validates the document would currently pass the preflight pipeline (composition, accessibility, required fields, embargo, approval), then stores |
search_content | read | Finds documents by a few letters of their title, across every collection the admin |
secondary | read | Subtle grey background |
sm | read | Small |
spacious | read | Large vertical margin |
split | read | Text on one side, media on the other |
square | read | 1:1 |
start | write | Left-aligned |
static | read | No link; presentational only |
suggest_for_intent | read | Given a natural-language description of what the author wants to accomplish, returns ranked component recommendations with reasoning. Optionally accepts the existing page context so duplicate Heroes / composition conflicts surface as warnings on the suggestions. |
test_integration | read | Calls the integration |
trigger_sync | write | Runs a real sync of one integration now, exactly as the admin\ |
unpublish | read | Unpublishes a published document by reverting it to draft. Use when content needs to be removed from the public site without deleting it. Fires content/page.unpublished so revalidation and integrations can react. |
update_block | write | Changes fields of one block in a draft, by the block |
update_draft | write | Changes fields of a document\ |
validate_composition | read | Validates a proposed page layout against the design system |
validate_recipe | read | Checks a recipe — { contract, tree } — against the design system as it is now, without saving it. Returns every problem with its path in the tree and what to do instead. Run it until it returns none, then save_recipe. |
what_changed_in_range | read | Summarized activity over a time range, grouped by action type, actor, and target collection. Use for |
who_changed_what | read | A user |
xl | read | Extra large |
xs | read | Extra small |
Trust audit
BLOCKgrade F · trust 36/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | FAIL |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (3 observation(s))
- Network
- declared (7 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
payload.config.ts
payload.config.ts.template
payload-cli.d.mts
payload-cli.mjs
DATABASE_URI=postgres://postgres:postgres@localhost:5433/throughline_playground
url: `http://127.0.0.1:${String(site.port)}${site.home}`,baseURL: site.baseURL ?? `http://127.0.0.1:${String(site.port)}`,DATABASE_URI: postgres://ci:ci@localhost:5432/ci
# DATABASE_URI=postgres://postgres:dev@localhost:5432/throughline
const DIRECT = 'postgres://u:[email protected]/neondb'
const POOLED = 'postgres://u:[email protected]/neondb'
secret: 'test-secret-test-secret-test-secret',
secret: 'test-secret-test-secret-test-secret',
secret: 'test-secret-test-secret-test-secret',
secret: 'test-secret-test-secret-test-secret',
secret: 'test-secret-test-secret-test-secret',
remove_block
.prettierignore
.prettierrc.json
C2-design-contract.md
import { resolveDatabaseConnection } from '../../src/lib/database''../../../create-throughline/reference-ds/src/components',
const bin = path.resolve(here, '../../bin/check-block-props.mjs')
const bin = path.resolve(here, '../../bin/check-block-props.mjs')
dir = await mkdtemp(path.join(here, '../../.tmp-check-block-props-'))
Gates applied: no_behavioural_pass.
4fefe9156715full audit observations/trust-audit/mcp-server/forumone__throughline.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | 4fefe9156715 | BLOCK | F | 36 | first audit |
Questions
What tools does @forumone/create-throughline expose?
79 in total: 59 read-only, 19 that write, and 1 that can delete or overwrite (remove_block). Every one is listed on this page with its risk.
Is @forumone/create-throughline safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (36/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does @forumone/create-throughline need?
It reads APPROVAL_TOKEN_SECRET, INNGEST_EVENT_KEY, PAYLOAD_SECRET and RESEND_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How current is this page?
The grade is for one exact copy of the source (4fefe9156715), read on 2026-10-07. The repository is watched and re-audited when it changes.