QC Database MCP Server
The QC Database MCP Server lets an AI assistant perform construction quality control (QC) database work on your behalf, connecting to QCDatabase.AI using your own authenticated session. Here's what it can do:
Authentication & Session Management
Sign in/out via browser-based OAuth, check auth status, and list organizations/tenants.
Project Navigation
List, search, and set the active project; view project members, controlled-vocabulary lists (welders, materials, pipe sizes, etc.), map item schemas, and document folders.
Document & Drawing Management
Upload MTRs, NDE reports, certificates, and other documents; retrieve AI-extracted data or write custom extraction results back; upload isometric PDFs (auto-split into sheets) and large-format drawings (P&IDs, plans).
Map Items (Welds, Flanges, Fittings)
List, create, and manage map items with schema-defined fields; mark items complete or accepted with user-accountable sign-offs; attach photos with captions.
Fillable PDF Forms
Browse, preview, download blank templates (RIRs, inspection checklists), and submit completed forms back as documents.
Inspection Forms & Notes
Create, list, and complete inspection form submissions; create, list, and resolve project notes with severity and assignments.
Inspection & Test Plans (ITP)
List ITP line items and mark them complete or accepted with sign-offs.
Quality Holds (Locks)
Add, unlock, assign, or delete quality hold points on map items or ITP line items to block turnover until resolved.
Turnover Package Management
List and create reference requests (open punch-list items needing proof); list and create references linking source items to proof documents; generate a turnover report tracking completion progress.
Semantic Search & User Manual
Perform natural-language meaning-based searches across project data; search or browse the QC Database user manual.
Utilities
Generate QR codes.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@QC Database MCP ServerUpload this MTR to Mill Test Reports"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
WARNING! Our apologies, but some of the modifications we made to allow remote hosting of this MCP server have broken the stdio tools. We are working on a fix ASAP. Please check back here later.
QC Database MCP Server
A small program that lets an AI assistant (like Claude) do your everyday QC Database work for you — set the project you're working on, upload records, read what the AI pulled off a document, and find and close out the items still needed for a complete, traceable turnover package.
It runs on your own computer. Your AI assistant talks to it; it talks to QCDatabase.AI on your behalf, using your own login.
Built on the official Model Context Protocol
Python library and the QC Database MCP specification — published at
qcdatabase.ai/mcp_server_spec.md and
kept in this repo as mcp_server_spec.md.
What you can ask your assistant to do
Once it's connected, you can talk to it in plain language. For example:
"Connect to QC Database." → signs you in (opens your browser once).
"Work on the Riverside Unit 2 project." → pins that project for the session.
"Upload this MTR to the Mill Test Reports folder."
"What's still missing for turnover on this project?"
"Show me the open reference requests assigned to me."
"Find welds that failed X-ray near line 12." → meaning-based (semantic) search across your project data, ranked by relevance.
"How do I create a test package in QC Database?" → answers from the built-in QC Database user manual, so you can learn the app without leaving your assistant.
"Attach this photo to that weld."
"Mark this inspection complete." (it will remind you that the sign-off is recorded under your name — that's your call, not the AI's).
Related MCP server: JoeMCP
Before you start
You need Python 3.10 or newer on your computer.
Windows: install from the Microsoft Store (search "Python") or from python.org/downloads. During the python.org install, tick "Add Python to PATH."
Mac:
brew install pythonor get it from python.org/downloads.
To check it's installed, open a terminal (PowerShell on Windows, Terminal on Mac) and run:
python --versionYou should see Python 3.10 or higher. (On some Macs the command is python3.)
Install
From a terminal, in this folder:
pip install .That's it. This installs the server and a command called qcdatabase-mcp.
If
pipisn't found, trypython -m pip install .(orpython3 -m pip install .).
Install in Claude Desktop
Claude Desktop launches this server for you and shows its tools in your chats. Set it up once:
1. Install the Claude Desktop app
If you don't have it, download it from claude.ai/download and sign in.
2. Open the config file
In Claude Desktop:
Open Settings (Windows: menu ☰ → File → Settings; Mac: Claude → Settings).
Go to the Developer tab.
Click Edit Config.
This opens (and, if needed, creates) a file named claude_desktop_config.json.
You can also open it directly:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonMac:
~/Library/Application Support/Claude/claude_desktop_config.json
3. Add the QC Database server
Put this in the file. If the file already has other servers, just add the
"qcdatabase" block inside the existing "mcpServers" section.
Windows:
{
"mcpServers": {
"qcdatabase": {
"command": "python",
"args": ["-m", "qcdatabase_mcp"]
}
}
}Mac (Python is usually python3 there):
{
"mcpServers": {
"qcdatabase": {
"command": "python3",
"args": ["-m", "qcdatabase_mcp"]
}
}
}Save the file.
If Claude can't start it (you see "python not found" or the server fails), use the full path to Python instead of just
"python". Find it by runningwhere python(Windows) orwhich python3(Mac) in a terminal, then paste that path as the"command". For example on Windows:{ "mcpServers": { "qcdatabase": { "command": "C:\\Users\\you\\AppData\\Local\\Programs\\Python\\Python312\\python.exe", "args": ["-m", "qcdatabase_mcp"] } } }(Use double backslashes
\\in Windows paths inside JSON.)
4. Restart Claude Desktop
Fully quit and reopen the app (on Windows, also close it from the system tray; on Mac, Quit with Cmd-Q — closing the window isn't enough). The new server only loads on a fresh start.
5. Confirm it loaded
Start a new chat and look for the tools/connector indicator (a slider or tool icon near the message box). Click it and you should see qcdatabase with its tools listed. If you don't, see Troubleshooting.
Then ask Claude to "connect to QC Database" to sign in — see below.
First time you use it
Sign in. Ask the assistant to connect to QC Database (the
logintool). Your web browser opens; log in and pick which company workspace you want to connect. That choice locks the connection to that one organization. You only do this once — it's remembered.Pick your project. Ask it to work on a project by name, or list your projects first. Almost every action happens "inside" a project, so the server asks you to choose one before it will do project work. You can switch projects any time.
Get to work. Upload documents and drawings, check what's missing for turnover, create and close reference requests, add notes and photos, and so on.
What it can do (tool groups)
Session:
login,logout,auth_status,whoamiFind your way around:
list_tenants,list_projects,set_project,get_active_project,list_project_members,list_lists,list_list_items,list_map_item_schemas,list_document_folders,list_form_schemasControlled-vocabulary lists:
create_list_item,update_list_item,delete_list_itemJobs & packages:
list_jobs,create_job,list_packages,create_package,list_line_specs,create_line_specUpload records:
upload_document,upload_document_version,download_document,upload_drawing,upload_large_format_drawing,upload_drawing_to_package,upload_drawing_version,upload_large_format_drawing_version,attach_photoDrawings:
list_drawings,get_drawing(incl. pixel width/height — the HTML5-canvas coordinate space for map items),export_drawing,export_large_format_drawingFillable PDF forms:
list_fillable_templates,get_fillable_template,download_fillable_template,submit_fillable_templateStructured data:
get_document,set_document_extracted_data,list_documents,list_map_items,get_map_item,create_map_item(place welds/flanges by pixel coordinates),bulk_create_map_items,bulk_update_map_items(batch up to 500 items on one drawing/schema). Always calllist_map_item_schemasfirst — see the CAD/PCF/.weldb note belowRepairs:
list_repair_codes,add_map_item_repairInspection forms & notes:
list_form_submissions,create_form_submission,get_form_submission,update_form_submission,complete_form_submission,create_note,list_notes,resolve_notePhotos:
list_photos,attach_photoITP & sign-offs (your call):
list_itp_line_items,get_itp_line_item,create_itp_line_item,update_itp_line_item,mark_map_item_complete,mark_map_item_accepted,mark_itp_complete,mark_itp_acceptedQuality-hold locks (witness/hold points — the user's call):
list_lock_types(read only),list_locks,get_lock,add_lock(place a hold point — fit-up, tack-up, weld-cleanliness, FME, final-closure, boiler-tube FME sponge-in/sponge-out, etc. — on a map item or ITP line item so it can't be turned in until inspected),unlock_lock,assign_lock,delete_lock. A lock is a construction quality gate, not a security control; place or clear one only at the explicit request of its owner/author or an authorized inspector. Creating or editing lock types (the named hold definitions, and who may place/clear each) is intentionally not exposed here — that permission-sensitive setup is done in the web app's Project Admin, and the assistant will point you thereTurnover (the important part):
list_reference_requests,create_reference_request,list_references,create_reference,turnover_reportReceiving:
list_shippers,list_shipper_line_itemsSemantic search (meaning-based, ranked):
semantic_search— natural-language search across the project's documents, drawings, large-format drawings, jobs, packages, list items, map items, form submissions, notes, and shippersHow QC Database works:
search_user_manual(ask "how do I…?" questions and read the product help articles),list_user_manual(browse the help contents)Utilities:
generate_qr_code
A companion to CAD, PCF, and .weldb systems
This server is a natural partner to the systems that already describe your geometry — CAD/CAE exports, PCF piping files, and .weldb boilermaker replacement-panel files. Those sources carry most of what a good map item needs, so the assistant can turn them into accurate weld maps — if it follows two habits:
Fetch the schema first. Always call
list_map_item_schemasbeforecreate_map_item/bulk_create_map_items. That picks the right schema and reveals its exact fields, so source values land where they belong instead of being guessed or free-texted:PCF (piping) files carry most of what a pipe weld needs — joint type, material, weight/sch.
.weldb files carry material, tube wall thickness, and the weld's rectangular position on the drawing — enough to build a weld map automatically.
Match the source's geometry — point vs. rectangular welds. This is the big data-quality lever. A PCF pipe weld is a single point weld (one x/y). A .weldb weld has a rectangular position — give the second point (
x_position_2/y_position_2) as the opposite corner so the extent is preserved. Collapsing a rectangular weld to a bare point (or spreading a point weld into a box) silently corrupts the map. Fetching the schema up front is what makes this distinction obvious before any items are placed.
A note on sign-offs
Marking work complete or accepted is a buy-off — the system records it under your name and the current time. The assistant can do these for you, but every one of those tools tells you plainly that you are responsible for the action. The server never signs anything off silently. Treat those as your decisions, made with your go-ahead.
Privacy & safety
The server runs locally and only talks to
https://qcdatabase.ai.Your login is pinned to one organization (chosen at sign-in) and your session is pinned to one project — so the assistant can't reach into a different workspace or project by accident.
The server only requests the permissions an everyday user needs; admin actions are out of scope by design.
You can disconnect any connected app at any time from your QC Database account.
Your login is stored on your own computer in a per-user folder:
Windows:
%LOCALAPPDATA%\qcdatabase-mcp\store.jsonMac:
~/Library/Application Support/qcdatabase-mcp/store.jsonLinux:
~/.config/qcdatabase-mcp/store.json
Run the logout tool (or delete that file) to forget the login.
Filesystem safety (design invariant)
This is a hard rule the server must always uphold — for its own safety and for anyone contributing to this open-source repo:
The server never modifies its own files. No tool can read from or write to the server's whole installation — its own source, its dependencies (
site-packages), the virtualenv, or (from a checkout) the repo root — whatever path it is given, so the assistant can never edit the server's or a dependency's code (no self-modification). Downloads also refuse to overwrite an existing file; choose a new path.The server never touches its credential store beyond the token flow. No tool can read or write the per-user config directory, so a token can never be exfiltrated or overwritten through a tool, and it can never be committed to the repo (it lives outside any checkout;
store.jsonis also.gitignored).The only local files a tool ever touches are the user's own documents, and only in stdio mode — the upload tools read a file you point them at, and the download/export tools write to a path you choose. In hosted mode the server refuses all local filesystem access, because the disk is the server's, not yours (uploads/downloads there would need a client-side file channel instead).
These rules are enforced in code by _guard_local_path in server.py.
Troubleshooting
"qcdatabase" doesn't show up in Claude Desktop after restarting.
Make sure you fully quit the app (system tray on Windows, Cmd-Q on Mac) and reopened it.
Check the config file is valid JSON — a missing comma or brace stops every server from loading. Paste it into a JSON checker if unsure.
If it still doesn't load, set
"command"to the full path to Python (see the install note above).Look at the Claude Desktop logs for an error: Windows
%APPDATA%\Claude\logs\, Mac~/Library/Logs/Claude/.
"Not logged in." Ask the assistant to connect to QC Database and finish the sign-in in your browser.
"No project is set." Ask it to work on a project, or to list projects.
A newer feature says "Access denied (403)" (e.g. the user manual, or the quality-hold locks). If you first signed in with an older version, your saved app registration predates that feature's permission. Delete your
store.json(see Privacy & safety for its location) and sign in again — that re-registers the app with the current permissions.The browser didn't open during login. The assistant will show you a link — open it manually to finish, then sign in again.
The sign-in page can't connect / port already in use. The login uses a local web address on port
8765. If another program is using it, set a different free port before launching the app by adding an environment variableQCDB_CALLBACK_PORT(for example8766), then sign in again.It can't find
python. Reinstall Python with "Add to PATH" ticked (Windows), or usepython3in the config.
For developers
pip install -e . # editable install
python -m qcdatabase_mcp # run the stdio server directly
pip install -e '.[dev]' # editable install + test deps
pytest # run the test suiteLayout:
src/qcdatabase_mcp/
__main__.py # entry point + CLI (chooses stdio vs. hosted HTTP)
server.py # FastMCP server + all tools + local filesystem guard
hosted.py # multi-user hosting: OAuth resource server, token verify, sessions
client.py # HTTP client: bearer auth, auto-refresh, errors, pagination, path safety
auth.py # OAuth2 (PKCE + dynamic client registration) login & refresh (stdio)
config.py # local token / project storage (stdio)
tests/
test_security.py # guard, token verifier, path safety, pagination, refresh, ...
mcp_server_spec.md # the API + behaviour spec this server implements
CLAUDE.md # contributor invariants (filesystem safety, credential handling)Environment variables (stdio mode):
QCDB_CALLBACK_PORT— local OAuth callback port (default8765).QCDB_CONFIG_DIR— override where tokens/settings are stored.
Hosting it for many users (mcp.qcdatabase.ai)
By default the server speaks MCP over stdio — one local user, sign-in via the
login tool. Pass --http to run the multi-user hosted server instead, which
serves the Streamable HTTP transport at /mcp, plus a public home page
at / (connection instructions for humans) and a health check at /health
(for load balancers and uptime monitors).
Try it on your own machine (creates a .venv, installs, runs on
http://127.0.0.1:8000):
./scripts/run-local.sh # Mac/Linux
.\scripts\run-local.ps1 # Windows (PowerShell)
scripts\run-local.bat # Windows (double-clickable / cmd)Then open http://127.0.0.1:8000/ in a browser.
Deploy it on a server so that git pull + restart is a complete deploy —
the full walkthrough (systemd unit, nginx/Caddy configs, verification
checklist, troubleshooting) is in deploy/README.md:
cp deploy/example.env .env # set QCDB_MCP_RESOURCE_URL=https://mcp.example.com
./scripts/run-server.sh # binds 127.0.0.1:8000; put a TLS proxy in frontBehind nginx you MUST forward the original Host header (
proxy_set_header Host $host;) — the provideddeploy/nginx.confdoes. Without it, the DNS-rebinding protection rejects every authenticated request with421, which looks like "OAuth works but no tool call ever does". Caddy (deploy/Caddyfile) does the right thing by default.
In hosted mode the server is an OAuth 2.0 resource server (per the MCP authorization spec) — there are no shared secrets and nothing is stored on disk:
Each MCP client signs its own user in against QCDatabase.AI (discovered from the
/.well-known/oauth-protected-resourcedocument this server publishes) and sends that user's access token asAuthorization: Bearer …on every request.The server verifies the token against
/api/whoami/, identifies the user, and acts as them. Unauthenticated requests get401with aWWW-Authenticateheader pointing clients at the authorization server, so sign-in is automatic.Per-user session state (the active project) is kept in memory keyed by a globally-unique identity (tenant + user id, never the raw token), so many people share one deployment without ever seeing each other's work. Verification fails closed — a token that doesn't resolve to a user is rejected. (State resets on restart — users just re-run
set_project.)DNS-rebinding protection validates the
Host/Originof every request (forgedHost→421, forgedOrigin→403).
The login / logout tools become no-ops in hosted mode (sign-in is the client's
job); everything else works identically to stdio.
Hosted-mode configuration (flags override env):
QCDB_MCP_HTTP=1— same as--http.--host/QCDB_MCP_HOST,--port/QCDB_MCP_PORT— bind (default127.0.0.1:8000).--resource-url/QCDB_MCP_RESOURCE_URL— this server's public URL and OAuth resource id; required when binding a non-loopback host.--issuer-url/QCDB_MCP_ISSUER_URL— the OAuth authorization server (defaulthttps://qcdatabase.ai).QCDB_MCP_ALLOWED_HOSTS/QCDB_MCP_ALLOWED_ORIGINS— extra allow-list entries (comma-separated), e.g. when fronted by additional hostnames.QCDB_MCP_TOKEN_CACHE_TTL— seconds a verified token is trusted before re-checking/api/whoami/(default60). This is also the window in which a token revoked upstream keeps working here; lower it to shrink that window.QCDB_MCP_TOKEN_NEG_CACHE_TTL— seconds a failed verification is remembered (default5), which blunts garbage-token amplification against the API.QCDB_MCP_STATELESS— serve each request without a server-held MCP session (default1). Leave on: stateful sessions break on restarts, redeploys, and multi-replica setups ("session not found"). Set0only if you need server-initiated messages within a session.QCDB_MCP_JSON_RESPONSE— answer POSTs with plain JSON instead of an SSE stream (default1). Leave on: buffering proxies (nginx's default) stall SSE and the client times out; none of this server's tools stream partial results.
TLS. Terminate TLS at a reverse proxy in front of the server (never expose
plain HTTP publicly) and forward the real Host header.
Resource indicator (kept open). This server accepts any valid QCDatabase-
issued token and takes its resource id from QCDB_MCP_RESOURCE_URL, so anyone can
fork it and host on their own domain without special AS configuration. For strict
RFC 8707 audience binding, an operator may configure their authorization server
to issue tokens bound to their MCP URL — but it is not required.
Scaling across replicas. The only shared state is each user's pinned project —
small, non-secret, and disposable (lost pins just mean re-running set_project).
Pick whichever fits your deployment:
Single instance (default). In-memory store, nothing to run. Best for most self-hosters.
Sticky sessions. Several replicas behind a load balancer that routes each user to the same replica; still in-memory, but a replica restart drops its users' pins.
Shared store (Redis). Set
QCDB_MCP_REDIS_URLand install the extra (pip install 'qcdatabase-mcp[redis]'). All replicas share state and it survives restarts. Pins expire afterQCDB_MCP_SESSION_TTLseconds idle (default 8h). To plug in a different backend, implement the two-method store inhosted.py(get_active_project/set_active_project) and return it frombuild_session_store.
(The token-verification cache is intentionally per-replica — each rebuilds it from
/api/whoami/, so it needs no sharing.)
Licensed under the MIT License (see LICENSE).
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ProcessQualitySolutions/qcdatabase_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server