Headless REST API for CSI MasterFormat-compatible specification automation.
SpecR parses specification documents into a canonical CSI AST (Abstract Syntax Tree: a structured, tree-shaped model of the document's content and hierarchy, independent of any file format), stores the result in PostgreSQL, and renders the same structure back to DOCX, Markdown, JSON, and SpecsIntact .SEC.
SpecR is an independent project and is not affiliated with CSI.
SpecR treats specifications as structured data rather than opaque Word files.
The core workflow is:
- Upload a
.docx,.SEC,.txt, or.pdfspec. - Parse it into a parent/child CSI paragraph tree.
- Store the canonical AST and paragraph lineage in PostgreSQL.
- Generate DOCX or
.SECoutput from the AST. - Diff and merge reviewer-edited DOCX files back into the database by UUID content-control anchors.
The current backend is API-first. Browser UI, authentication, and full Revit sync workflows are still roadmap items.
Analytical outputs: coordination report, submittal register, spec diff, and reference sets are computed by deterministic endpoints over that structured AST and surfaced to agents through a first-class MCP contract, not generated by a language model summarizing retrieved text. See Deterministic-First: Grounded Data, Not RAG.
- DOCX parser with 5-signal hierarchy inference, inference-conflict surfacing, source-fact capture, hidden/
vanishcontent retention (excluded from structural inference, not discarded), and ARCAT/CPI/LibreOffice fixture coverage. - UFGS SpecsIntact
.SECparser and.SECoutput renderer. - Plaintext
.txtparser for read-only ingest. - PDF parser: text-layer extraction with a
pdfjs-distfallback, automatic OCR (tesseract.js) for scanned pages, and font-encoding recovery, feeding the same text-based inference path with graceful degradation warnings. - PostgreSQL-backed specs, paragraphs, versions, projects, libraries, design packages, package revisions, style templates, conventions, locks, and lineage.
- DOCX generator with CSI multilevel numbering (seven CSI tiers), content-control UUID anchors, style-template application, multi-section manual assembly, cover page, and TOC field support.
- Immutable package revisions with revision/addendum manual rendering (
POST /revisions/{id}/generate) and project-scoped revision-nomenclature profiles. - Diff and merge endpoints for round-trip reviewer redlines.
- Document concurrency: optimistic paragraph writes, advisory spec locks, and a review/active lifecycle state.
- Project coordination / errors-&-omissions report: required-vs-present sections, dangling references, Related-Sections/References article-body consistency, umbrella↔subordinate call-outs, implied related sections, and a product-driven submittal register.
- Onboarding pipeline: async library-master import, per-paragraph editability classification with human overrides, reclassify, finalize/reopen, comment closure + open-comments reporting, and structural numbering profiles.
- Style-template CRUD, DOCX template import, convention profile CRUD, and spec/project soft-delete (withdraw) with restore.
- MCP Streamable HTTP server (
POST /mcp) with read-oriented tools/resources — stateless per request by default; aninitializecall can mint a stateful session (server-issuedmcp-session-id) that later requests reuse andDELETE /mcpterminates. - Revit 2024 add-in scaffold with a typed REST client and health-check ribbon command.
See ROADMAP.md for the fuller capability inventory and planned work.
The canonical contract is openapi.yaml, CI-enforced by a route↔spec coverage gate. It is rendered as a live Scalar reference at GET /docs and served raw at GET /openapi.yaml. Key groups:
- Parsing:
POST /parse(.docx/.SEC/.txt/.pdf, optional numbering profile),GET /parse/jobs/{jobId} - Specs:
GET/PATCH/DELETE /specs/{id}(soft-withdraw) +restore, paragraph updates, editability overrides, reversible paragraph removal, reclassify, finalize/reopen, external-content associations, lineage, style-source, numbering-profile assignment, and advisory locks - Generation:
POST /specs/{id}/generate,POST /projects/{id}/generate,POST /revisions/{id}/generate(issued/addendum manuals) - Round trip:
POST /specs/{id}/diff,POST /specs/{id}/merge - Projects: list/create, rename + settings, soft-delete + restore, sources, TOC, references (broken/inbound), division general-spec
- Coordination: required-sections (project + package),
GET /projects/{id}/coordination-report,POST /projects/{id}/submittal-register, open-comments - Libraries: list, client-tier create, rename, specs, async master import, convention profiles, numbering profiles
- Packages and revisions: design packages, immutable revision snapshots, and revision-nomenclature profiles
- Templates and conventions: style templates, DOCX template import, convention profiles
- MCP:
POST /mcp
The Streamable HTTP server at POST /mcp exposes these tools (all stateless, reading or correcting via db/index.js queries, rate-limited by the shared /mcp limiter):
| Tool | Purpose |
|---|---|
search_library |
Full-text search the paragraph library |
list_sections |
List CSI sections with an inDatabase flag |
get_spec |
Full spec tree + reference resolution + style/onboarding status |
get_paragraph |
One paragraph with its ancestor chain |
get_spec_lineage |
Chain of custody for a spec (ADR-015) |
get_spec_diff |
3-way merge diff for a returned DOCX |
get_numbering_profile |
Read a spec's effective structural numbering profile |
parse_document |
Parse and store a base64 DOCX/SEC/TXT/PDF |
generate_docx |
Generate DOCX from a stored spec |
load_files |
Bulk-load specs by glob or paths |
list_projects / get_references |
Project list and per-section cross-references |
coordination_report |
Project errors-and-omissions report |
submittal_register |
Product-driven submittal register for selected specs |
open_comments_report |
Open (unclosed) Word comments in a spec or project |
review_editability |
Per-paragraph editability + confidence + evidence (low-confidence filter) |
get_onboarding_report |
Spec onboarding report (editability summary, style source, status) |
set_editability_override / clear_editability_override |
Apply or remove a human editability override |
reclassify_spec |
Re-run classification; returns the before/after diff |
pnpm install
docker compose up -d postgres
pnpm migrate
pnpm seed
pnpm devThe API starts on the port configured by .env (see .env.example).
Useful commands:
pnpm test
pnpm test:integration
pnpm lint
pnpm build
pnpm load:files 'docs/references/UFGS/**/*.SEC'Development workflow, testing rules, and local Postgres notes live in CONTRIBUTING.md.
The API is unauthenticated until auth lands (#43): both the REST surface and the write-capable MCP tools accept any request, and the server binds all interfaces. Keep it behind a trusted network (localhost, a private LAN, or a VPN) — do not expose it to the public internet. At startup SpecR logs a warn restating this whenever no authentication is configured; the warning goes silent automatically once #43 adds real auth.
The full design is in ARCHITECTURE.md. The short version:
src/ast/owns the canonical CSI AST and schemas.src/parser/converts DOCX,.SEC, and.txtinto the AST.src/generator/renders AST output to DOCX, Markdown, and.SEC.src/merge/performs UUID-anchored 3-way diff and merge.src/db/owns migrations and persistence queries.src/api/exposes REST routes.src/mcp/exposes MCP tools and resources.revit-addin/contains the separate C#/.NET Revit add-in scaffold.
Module boundaries are intentionally strict: import sibling modules through their index.ts barrels, not internal files.
examples/web_ui_demo/ is a standalone reference web client for the REST API, a static front end plus a small proxy server. It lives under examples/ on purpose: it may drift as the API evolves and must never require backend changes. See examples/web_ui_demo/README.md to run it, including Windows/corporate-proxy launch helpers.
docs/references/UFGS/contains public-domain UFGS.SECseed data.docs/references/ARCAT/README.mdanddocs/references/MANUFACTURER_CPI/README.mddescribe fixture acquisition for copyrighted vendor samples that are not stored in this repository.
The .docx reference corpus is gitignored, so its inference safety nets skip in CI.
gold:verify is a local binary veto against a maintainer-blessed baseline
(gold/expectations.json, committed — fingerprints are facts, the docs are not):
pnpm gold:verify # before merging any inference change — non-zero exit on drift
pnpm gold:bless # after confirming parses in the web UI — bless the whole corpus
pnpm gold:bless 'docs/references/ARCAT/**/*.docx' # bless one vendor/sectionBless loop: open a spec in the demo → confirm the parse is correct → gold:bless <glob>.
Only blessed files gate; an un-blessed file is reported, not failed. See ADR-057.