
acikpoz
io.github.gulmezeren2-bytePublished by GitHub account gulmezeren2-bytev0.2.0Updated Nov 3, 2026
Turkish public construction unit-price (birim fiyat) catalog PDFs into structured pozes
Overview
Parses Turkish public construction unit-price (birim fiyat) catalog PDFs into structured pozes, and lets an assistant diff catalog years and validate parses.
- What you can do
- Parse a catalog PDF into structured pozes with priced, group-header and gap counts
- Compare two catalog years by poz code, reporting price moves, added and removed pozes and unit changes
- Validate a parse for duplicate or malformed codes, non-positive prices and missing or unknown units
- Return structured data rather than prose, with per-parse price parse rate and a confidence grade
- When to use it
- Useful when an assistant has to work with ÇŞB birim fiyat catalogs: building cost estimates, preparing tenders, auditing rates, or tracking how this year's prices moved from last year's.
- Requirements
- Runs locally over stdio as a Python package; install with pip including the mcp extra and start the acikpoz-mcp command. No accounts, API keys or environment variables are declared. You must supply your own official catalog PDF, since the parser ships no data.
Installation
In SourceWeft
- Open acikpoz in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
acikpoz
Turkish public construction unit prices, turned from a PDF into data you can compute with.
Every public construction job in Turkey is priced against a government catalog: the ÇŞB (Çevre, Şehircilik ve İklim Değişikliği Bakanlığı) birim fiyat books — thousands of unit prices (a poz: a code, a description, a unit, a price) that estimators, contractors and auditors all read. They ship as long PDFs. acikpoz turns those pages back into structured records, deterministically, so a cost estimate or a tender preparation can be computed instead of copied by hand.
It is disciplined geometry, not a language model: it groups the words on a page into visual rows and reads the price column's position from the page header rather than guessing a fixed spot. That one decision is what makes it trustworthy — some sections (Sıhhi Tesisat, say) print two numbers per row, the real Birim Fiyat and a separate Montaj Bedeli, and a naive parser silently reads the wrong one. acikpoz reads the header, so it reads the right column.
Paired with ihalent (which structures tender results), acikpoz covers the other half of Turkey's public construction economy: the prices the results are measured against.
The one rule it never breaks
A price is only ever a number the catalog actually printed in the price column. It never coerces, never borrows a neighbour's figure, never guesses. Two consequences, both on purpose:
- A group-header poz — a category title like
EVİYELER:whose sub-items carry the real prices — has no price of its own. acikpoz leaves itsfiyatasNoneand flagsis_group_header. It does not invent a zero. - A poz the catalog left without a printed price is a gap, surfaced and counted, not hidden. Every result reports its coverage: how many pozes were priced, how many were headers, how many were genuine gaps.
Half the value of a cost tool is refusing to make up the numbers the source did not print. That is the same honesty discipline as andon and ihalent.
Install
Quick start
Point it at an official catalog PDF you have (acikpoz ships the parser, not the data):
The table view — this is a real run against the published 2026 catalog, not a mock-up:
Two things in that picture are the whole point:
- Three rows carry
-in the price column. The catalog printed no price for them, so acikpoz prints none either — they are counted as gaps, not filled in from a neighbour. validatethen flags what the parse is not sure about: on this page five units (+2000,azami,Yapı,-30°C,2,5) are fragments of description text that landed in the unit column. The extraction is imperfect on some layouts, and the tool reports that itself rather than handing you a clean-looking table with wrong units in it.
Reproduce it — the page is chosen, nothing else is:
The catalog is the ministry's own file, published here. The image is
regenerated by scripts/make_demo_svg.py, which
downloads that PDF and runs the same code the CLI runs.
The grade (excellent/good/fair/poor) is a glanceable confidence signal, the
way camelot exposes accuracy: below good, review the pages before trusting the
output. --json includes price_parse_rate and grade per parse.
Or from Python:
How it works
- Rows. Words are grouped into visual rows by vertical position (a few points of tolerance), then sorted left-to-right.
- Price column, from the header. The
Fiyatheader word on the right (x > 400) gives the price column's x. A stray "fiyat" in a left-column description can't be mistaken for it. - Cells. For each poz row: the leftmost cell is the poz code; the price is the number-shaped token nearest the price-column x; the unit sits just left of it; the rest is the description. Indented continuation lines extend the running description (and can carry a price that spilled over).
- Group headers. A price-less poz whose description ends in
:is a category title — flagged, not treated as a gap.
Compare two catalog years
Catalogs are reissued regularly; the question estimators and auditors track by hand is how
did this year's rates move from last year's? acikpoz diff answers it — it joins two years
by poz code and classifies each change:
It reports price moves (with Δ and %Δ), added and removed pozes, unit changes, and pozes that gained or lost a printed price — plus the mean price %-change for the year. As far as the research found, no other open tool does year-over-year diffing for ÇŞB catalogs.
Validate a parse
Before a parsed catalog feeds a cost estimate, it helps to know it is clean. acikpoz validate runs deterministic quality rules over the pozes — no ML, no fixing, only surfacing:
It flags duplicate poz codes, malformed codes, non-positive prices (errors), and priced
pozes with no unit or a unit outside the known set (warnings). It exits non-zero on any
error, so it can gate a pipeline (acikpoz validate … && build-estimate). This is also how
acikpoz stays honest about its own limits: in sections that print the unit once on a group
header and let the rows inherit it (Sıhhi Tesisat), per-row unit detection is weak, and
validate says so rather than hiding it. Price, poz code and description stay reliable.
Using acikpoz with AI agents
An MCP server (pip install 'acikpoz[mcp]', then acikpoz-mcp) exposes three tools:
parse_catalog (a PDF → structured pozes with honest coverage), diff (two catalog years
→ classified changes), and validate (a PDF → quality findings). The agent gets structured
data back, not prose it has to parse. Pair it with ihalent and an agent can reason across
both a tender's result and the unit prices it was measured against.
Scope, honestly
- It reads the standard catalog layout. The header-driven column detection handles the common single- and two-price-column pages well; an unusual layout may leave more gaps — which it reports rather than papering over. If a section parses badly, that's a bug worth a sample.
- It is a parser, not a price database. It does not bundle or redistribute the catalog. You bring the official PDF; acikpoz turns your copy into data.
- Prices are nominal, as printed. No inflation adjustment is baked in — that's an analysis choice the caller makes knowing the year.
Data, and why the PDFs aren't here
The ÇŞB catalogs are official public documents, but this repository does not redistribute
them: it ships the parser and nothing else, and .gitignore keeps *.pdf out. Point acikpoz
at the catalog you obtained from the official source. This is the same line ihalent draws —
own the tool, not the data.
How this project is built
I'm an industrial engineer working in construction; I read these catalogs. I designed the parsing approach — geometry over machine learning, honest gaps over invented numbers — and I review every line; I use AI agents heavily for implementation speed, and the commit trailers say so. The contract is the tests: they encode the exact word geometry a real page emits, including the two-column Sıhhi Tesisat trap and the group-header rule, so green tests mean the parser handles the real thing.
Related
- ihalent — the other half of the Turkish public-procurement picture.
acikpozreads the unit-price catalogs that say what work should cost;ihalentreads the tender result notices that say what it was awarded for, and at what discount. Same discipline: every figure traceable to its source, nothing invented.
More tools by Eren Gülmez.
License
MIT — see LICENSE.
Source: README.md at commit 5c74e1e
Tools
0Version history
1- v0.2.0LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts