VATBuild's MCP server is directly compatible with the ChatGPT desktop app, ChatGPT
in-browser connectors, and custom GPT Actions. This guide covers all three entry
points, the OAuth 2.1 PKCE flow that ChatGPT uses for user-delegated auth, and a
recommended agent workflow.
Endpoint: POST https://vatbuild.com/mcp
Protocol: Streamable HTTP, JSON-RPC 2.0, stateless
Auth: Authorization: Bearer <api-key> (for Desktop/API) or OAuth 2.1 with PKCE (for Connectors)
3. ChatGPT in-browser connector (Tools panel)
7. Rate limits
8. OAuth 2.1 PKCE — user-delegated auth
Option A — Register via MCP (zero-click):
Call create_account with no auth header. The tool returns a vb_live_... API key
immediately and creates a free VATBuild account. Copy the key and add it to your
ChatGPT config.
Option B — Web dashboard:
Log in at vatbuild.com, navigate to Settings → API Keys,
and create a key. Tick the scopes you need (see Scopes reference).
Keys are shown only once — copy and store them securely.
Option C — Existing account, forgotten key:
Call authenticate_account with your email address. A fresh key is returned and a
sign-in link is sent to your inbox.
The ChatGPT desktop app (macOS and Windows) supports MCP servers through a
shared TOML configuration file used by the ChatGPT desktop app, Codex CLI, and
IDE extension. This is now officially documented by OpenAI
(learn.chatgpt.com/docs/extend/mcp).
> Note: The ChatGPT desktop app MCP feature requires a recent version of
> the app and is rolling out progressively. If you do not see **Settings → MCP
> servers**, update to the latest release.
1. Open Settings in the ChatGPT desktop app, then select MCP servers.
2. Select Add server.
3. Enter a name (e.g. vatbuild), choose Streamable HTTP, and enter the
URL: https://vatbuild.com/mcp
4. Save the server, then select Restart.
In the composer, type /mcp to view connected servers and confirm VATBuild is
listed.
The config file is the same path on both macOS and Windows:
~/.codex/config.toml
Add a [mcp_servers.vatbuild] block:
[mcp_servers.vatbuild]
url = "https://vatbuild.com/mcp"
[mcp_servers.vatbuild.http_headers]
Authorization = "Bearer vb_live_YOUR_API_KEY_HERE"
Alternatively, keep the key out of the file by sourcing it from an environment
variable:
[mcp_servers.vatbuild]
url = "https://vatbuild.com/mcp"
bearer_token_env_var = "VATBUILD_API_KEY"
Set VATBUILD_API_KEY in your shell profile (~/.zshrc, ~/.bashrc, or the
Windows system environment variables), then restart ChatGPT.
Quit and restart ChatGPT after saving config.toml. On next launch, VATBuild
tools appear in the tool picker. Try:
Use the check_line_item tool to classify "Supply and fit underfloor heating" for a
new-build detached house under VAT431NB rules.
The desktop app sends requests server-to-server (no Origin header), which VATBuild
allows by design. No CORS configuration is needed.
check_line_item is public — no API key is required to classify line items without
creating projects or uploading invoices.
For the full workflow — account creation, project setup, invoice submission, line-item
routing — the key needs all five scopes. When creating the key in the dashboard, tick:
projects:readprojects:writeline_items:writejobs:readinvoices:writeChatGPT Plus, Team, and Enterprise users can connect MCP servers from the ChatGPT
web interface without installing the desktop app.
1. Open chatgpt.com and start a new chat.
2. Click the Tools icon (grid/wrench icon) near the message input.
3. Select Connect more tools → Custom connector (or Add MCP server,
depending on your plan tier and rollout).
4. Enter the server URL: https://vatbuild.com/mcp
5. In the Authentication section, choose Bearer token and paste your
vb_live_... API key.
6. Click Connect. ChatGPT discovers the available tools automatically.
> Note: In-browser connectors persist per account but not per conversation. If
> VATBuild tools are missing in a new chat, re-open the Tools panel and re-enable
> the connector for the session.
If you are building a Custom GPT (GPT Builder), you can connect VATBuild as an
Action using the OpenAPI specification.
1. In GPT Builder, go to Configure → Actions
and click Add action.
2. Set the Authentication type to Bearer token and enter your vb_live_...
key, or choose OAuth to use user-delegated auth (see
OAuth 2.1 PKCE below).
3. Import the VATBuild OpenAPI specification from:
```
https://vatbuild.com/docs/openapi.yaml
```
This exposes the REST companion endpoint (POST /api/v1/check-line-item) and
the project/invoice management routes. For the full MCP tool surface, the
Streamable HTTP endpoint (https://vatbuild.com/mcp) is the primary integration
point — use the desktop app or in-browser connector rather than GPT Actions for
multi-tool MCP workflows.
> Tip: Custom GPT Actions work best for focused, single-purpose workflows (e.g.
> "Classify this line item"). For the full VATBuild agent workflow across multiple
> tools, the desktop app MCP connector is a better fit.
The recommended end-to-end flow for a new VATBuild user via a ChatGPT agent:
Step 1 — create_account
Input: { "firstName": "Jane", "email": "jane@example.com" }
Output: { "apiKey": "vb_live_...", "nextStep": "set_up_project" }
→ Store apiKey; use it as the Bearer token for all subsequent calls.
Step 2 — set_up_project
Input: { "claimantRoute": "self_build_431nb", "buildingType": "detached house",
"address": "12 Elm Lane, Bristol" }
Output: { "projectId": "uuid", "profileConfirmed": false, "projectUrl": "..." }
→ Surface projectUrl so the user can confirm their profile in the VATBuild web app.
Profile confirmation is required before invoices can be submitted.
Step 3 — assess_project_eligibility (optional, recommended)
Input: { "projectId": "uuid" }
Output: { "eligibilityStatus": "likely_eligible", "keyFindings": [...] }
→ Surface any "warning" or "blocker" findings to the user before they proceed.
Step 4 — submit_invoice_data (once profile is confirmed in the web app)
Input: { "projectId": "uuid", "imageData": "<base64>", "imageMimeType": "image/jpeg",
"supplierName": "ABC Builders Ltd", "invoiceRef": "INV-042" }
Output: { "documentId": "uuid", "status": "extracting" }
→ VATBuild queues AI extraction in the background.
→ imageMimeType accepts "image/jpeg", "image/png", "image/webp", or "application/pdf".
→ For PDFs, pass the raw PDF bytes as base64 — do not render pages to images first.
Step 5 — Poll list_invoices until extractionStatus = "complete"
Input: { "projectId": "uuid" }
→ Check each item's extractionStatus. Repeat every 5–10 seconds.
→ Once complete, proceed to step 6.
Step 6 — list_line_items
Input: { "projectId": "uuid", "status": "pending" }
Output: array of line items; each has claimRoute and vatComplexType
Step 7a — route_line_item (for items WITHOUT a pending_complex_answer)
Input: { "projectId": "uuid", "lineItemId": "uuid",
"item": { "lineText": "...", "netAmount": "...", "vatCharged": "...",
"supplyType": "labour" } }
Output: { "claimRoute": "zero_at_source", "reclaimAmount": "0.00" }
Step 7b — answer_vat_complex_question (for items WITH claimRoute: "pending_complex_answer")
Use this — not route_line_item — when an item requires a specific complex-VAT
confirmation. It resolves the vatComplexType question and persists the decision.
Input: { "projectId": "uuid", "lineItemId": "uuid", "confirmedAnswer": true }
Output: { "claimRoute": "supplier_correction", "crossItemContextRequired": false }
→ If crossItemContextRequired is true, call reclassify_companion_items next.
Step 8 — reclassify_companion_items (when crossItemContextRequired = true)
Input: { "projectId": "uuid", "documentId": "uuid" }
→ Re-routes sibling items on the same invoice using updated context.
For full details on handling pending_complex_answer items, see
See gemini-integration.md — Scopes reference
for the full scopes table. Quick reference:
| Use case | Scopes |
|---|---|
| Read-only analysis (classify only) | *(none required)* |
| Read-only project access | projects:read |
| Full end-to-end workflow | All five scopes |
See gemini-integration.md — Rate limits for
the full rate-limit table. In summary:
| Request type | Limit |
|---|---|
| All requests per API key or IP | 60 per minute |
| Write tools | 10 per minute |
create_account / authenticate_account | 3 per hour per IP |
HTTP 429 responses include a Retry-After header. Implement exponential back-off
when polling list_invoices after submit_invoice_data.
ChatGPT is the MCP client that most commonly uses OAuth rather than a static API key,
because GPT Actions and the in-browser connector can drive a full browser-based
auth flow for each end-user. This is the recommended approach for multi-tenant GPTs
where each end-user holds their own VATBuild account.
Discovery:
GET https://vatbuild.com/.well-known/oauth-authorization-server
GET https://vatbuild.com/.well-known/oauth-protected-resource
Both endpoints return RFC 8414 / RFC 9728 metadata and are always live.
Authorization server metadata (key fields):
{
"issuer": "https://vatbuild.com",
"authorization_endpoint": "https://vatbuild.com/oauth/authorize",
"token_endpoint": "https://vatbuild.com/oauth/token",
"registration_endpoint": "https://vatbuild.com/oauth/register",
"scopes_supported": ["projects:read", "projects:write", "line_items:write", "jobs:read", "invoices:write"],
"code_challenge_methods_supported": ["S256"],
"pkce_required": true,
"grant_types_supported": ["authorization_code", "refresh_token"]
}
PKCE flow (four steps):
1. Dynamic registration — POST /oauth/register with your client metadata
(redirect_uris, client_name). Receive client_id. In GPT Builder, enter
this client_id in the OAuth configuration panel.
2. Authorization — ChatGPT redirects the user to:
```
https://vatbuild.com/oauth/authorize
?client_id=<your_client_id>
&response_type=code
&scope=projects:read projects:write line_items:write
&redirect_uri=<your_redirect_uri>
&code_challenge=<S256_challenge>
&code_challenge_method=S256
&state=<csrf_state>
```
The user logs in to VATBuild (or creates an account) and grants consent.
3. Token exchange — POST /oauth/token with the auth code and code_verifier.
Receive access_token and refresh_token.
4. MCP calls — ChatGPT uses Authorization: Bearer <access_token> on all /mcp
requests on behalf of the user.
Configuring OAuth in GPT Builder:
| Field | Value |
|---|---|
| Authentication type | OAuth |
| Grant type | Authorization code with PKCE |
| Authorization URL | https://vatbuild.com/oauth/authorize |
| Token URL | https://vatbuild.com/oauth/token |
| Scope | projects:read projects:write line_items:write jobs:read invoices:write |
| Token exchange method | Default (POST body) |
> Prerequisite: The VATBuild deployment must have MCP_OAUTH_ENABLED=true for
> the /oauth/authorize, /oauth/token, and /oauth/register endpoints to be
> active. The discovery endpoints (/.well-known/...) are always live regardless of
> this flag. Contact the VATBuild operator if the OAuth endpoints return 404.
For single-tenant agents where one service account is appropriate, the static API key
approach (Bearer token in headers) is simpler and equally secure.
| Symptom | Cause | Fix |
|---|---|---|
Tool calls return registration_required | Bearer key missing or wrong header name | Confirm the header is Authorization: Bearer vb_live_... (not X-Api-Key) |
| HTTP 429 on tool calls | Rate limit exceeded | Wait for Retry-After seconds; reduce polling frequency |
| HTTP 403 on a specific tool | API key lacks the required scope | Regenerate the key with the missing scope ticked |
| OAuth redirect returns 404 | MCP_OAUTH_ENABLED not set | Contact the VATBuild operator to enable the OAuth endpoints |
submit_invoice_data returns ASSESSMENT_NOT_CONFIRMED | Profile wizard not completed | User must visit projectUrl in the VATBuild web app and confirm their profile |
| Tools panel shows "Connection failed" | ChatGPT cannot reach the MCP endpoint | Verify the URL is exactly https://vatbuild.com/mcp (no trailing slash) |
| GPT Action always returns an error schema | OpenAPI import issue | Re-import from https://vatbuild.com/docs/openapi.yaml and check the schema validates |
| Connector does not appear after setup | ChatGPT session not refreshed | Reload the ChatGPT page and start a new conversation |
| OAuth authorisation page returns 404 | OAuth not enabled on the VATBuild deployment | Contact the VATBuild operator to enable MCP_OAUTH_ENABLED=true |