Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
Small-business accounting with a first-class API and MCP server, built for teams of humans and AI agents.
FinanceJavaScript · TypeScriptGitHub @Tbriggs776OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Small-business accounting (a QuickBooks Online replacement) built for teams of people and AI agents. Real double-entry books with an immutable ledger, plus a first-class REST API and MCP server so Claude, Cursor, or any agent can do the bookkeeping, with humans approving what posts.
Books
Sales
Expenses: vendors (1099 flags), bills with amount-tiered approval routing, bill payments with discounts
Inventory
Banking
Moving from QuickBooks Online
Workspaces: one sign-in, many companies
Security (built for SOC 2)
People and agents
gwk_…) is shown once with copy-paste setup.# Claude Code
claude mcp add --transport http groundworks https://YOUR-APP/api/mcp \
--header "Authorization: Bearer gwk_…"
// Any MCP client config (Cursor, Claude Desktop via mcp-remote)
{
"mcpServers": {
"groundworks": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://YOUR-APP/api/mcp",
"--header", "Authorization: Bearer gwk_…"]
}
}
}
# Plain REST
curl https://YOUR-APP/api/v1/me -H "Authorization: Bearer gwk_…"
| MCP | POST /api/mcp, Streamable HTTP, stateless JSON; protocol 2024-11-05 → 2025-11-25 |
| REST | /api/v1/…; spec at /api/v1/openapi.json |
| Auth | Authorization: Bearer gwk_… (or x-api-key) |
| Tools | 240 operations: QuickBooks import status and tie-out, accounts, journals, customers, items, estimates, invoices, recurring invoices, payments, sales receipts, credit memos and credits, refunds, sales tax, vendors, purchase orders, bills, recurring bills, bill payments, vendor credits and refunds, printed checks, banking (transactions, bank feeds, statement import, For review with splits, rules, reconciliation, receipts and attachments), month-end close (checklist, close and reopen, checklist items), inventory (costing method, lots, item stock, adjustments, valuation, valuation detail, stock status), email (documents and payment reminders with PDFs, send history, settings), reports (P&L by month, class, and budget; cash flow; sales by customer and item; expenses by vendor; open invoices and unpaid bills; 1099s; audit trail; changes after close; any report as CSV or PDF), review queue, activity |
| Money / dates | decimal strings ("1250.00"), YYYY-MM-DD |
| Dry run | X-Dry-Run: true / dry_run: true: the whole operation runs, GL posting included, then rolls back |
| Retries | Idempotency-Key header / idempotency_key arg: a create runs once per key |
| Errors | { error: { code, message, details, requestId } }; in MCP, isError results starting Error (<code>) |
| Rate limit | 600 requests a minute per key (API_RATE_LIMIT_PER_MINUTE); over it: 429 with Retry-After |
| Review | post: true on a create posts when allowed, otherwise keeps the draft and returns a review notice |
The REST routes, MCP tools, and OpenAPI spec are all generated from one
registry: src/lib/api/operations.ts.
npm install
cp .env.example .env.local # fill in Supabase + database values
npm run db:migrate # apply migrations
npm run dev
You need a Supabase project for auth. In the Supabase dashboard:
src/lib/security/password.ts)http://localhost:3000/** to
the redirect URLs (password-reset links come back through /auth/callback)NEXT_PUBLIC_AUTH_PROVIDERS=google,azure; SAML SSO with
NEXT_PUBLIC_AUTH_SSO=1Open /signup to create your workspace and first company.
The e2e suites run against any Postgres. A Supabase auth stub is included, so a throwaway local database works:
export TEST_DATABASE_URL=postgresql://[email protected]:5432/gw_test
npm run test:db:reset # drop, recreate, migrate
DATABASE_URL=$TEST_DATABASE_URL npm run test:e2e
32 suites: receipts and attachments (against a fake Claude: file types
by their bytes, reading and cleaning what comes back, failures, duplicates,
suggestions, receipts following bank lines through add, split, match,
exclude, and undo, expenses from receipts, deleting, the daily upkeep,
another company and the database guard), bank feeds (against a fake Plaid: who may connect, sealed
tokens, start dates, posted only, signs, rules, no duplicates, the bank's
edits and removals, paging and restarts, sign-in again, signed webhooks,
the daily run, agents, another company, disconnecting), QuickBooks import (against a fake QuickBooks: sign-in state,
sealed tokens, resumable batches through failures, throttling, expired
tokens, paging, and a full company's history tied out by hand: tax,
payments and credits, deposits, bill payments, inventory, reconciliations,
estimates and purchase orders, stock on hand, and the monthly tie-out),
posting engine,
inventory (FIFO and average, backdating, negative stock, voids, closed
periods, adjustments, opening stock, purchase orders, valuation tie-out),
lots (specific identification, expiring lots, vendor credits of stock,
purchase orders by quantity, stock status, valuation detail), recurring/allocations/budgets, reports,
email (every document type, templates, who may send where, failed sends,
scheduled reminders, signed delivery events),
month-end close (checklist, soft and hard close, closing password,
adjusting and override entries, reopen, changes after close, year end),
financial statements (P&L columns, budget vs actual, cash flow, contra
accounts, exports), detail reports (sales by customer and item, expenses by
vendor, open invoices, unpaid bills, audit trail), FX,
parties, bills, bill payments, vendor credits and refunds (plus card
payments and printed checks), purchase orders (approval, partial
billing), recurring bills, 1099s, invoices and payments, sales (tax, receipts,
credit memos, credits, refunds, the liability report), estimates and
recurring invoices (progress invoicing, the daily run), documents (company
profile and logo, PDFs, statements), banking (transactions, statement
import, For review, rules, reconciliation), agents + keys, REST + MCP, RLS,
workspaces (sign-up, invites, access, policy, access reviews), session
security (timeouts, MFA, revocation, rate limits), workspace isolation
(every API operation attacked from a second workspace, plus the database
guards), and support access. CI runs them all on every
pull request (.github/workflows/ci.yml).
scripts/dev/seed-demo.ts creates a demo workspace and company and prints
owner and agent keys for poking at the API. scripts/dev/ui-smoke.mjs
drives every page and the main flows in Chromium, including two-step
verification, against a fake Supabase Auth (see the file headers).
Environment variables (Production + Preview):
| Key | Notes |
|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase → Settings → API |
SUPABASE_SERVICE_ROLE_KEY | mark Sensitive; also stores attachments (private bucket attachments) |
DATABASE_URL | pooled connection (port 6543); the client uses prepare: false |
NEXT_PUBLIC_APP_URL | public URL; used in invite links and connection snippets |
CRON_SECRET | required for the daily job (recurring entries, auto-reversals, pruning) |
RESEND_API_KEY, EMAIL_FROM | invitation emails; without them, invites show a link to copy |
NEXT_PUBLIC_AUTH_PROVIDERS, NEXT_PUBLIC_AUTH_SSO | optional extra sign-in methods |
API_RATE_LIMIT_PER_MINUTE | optional, default 600 |
GROUNDWORKS_SUPPORT_USER_IDS | optional; your support team's user ids (see Support access) |
QBO_CLIENT_ID, QBO_CLIENT_SECRET, QBO_ENVIRONMENT | QuickBooks import: your Intuit app's keys (mark the secret Sensitive); sandbox or production |
APP_ENCRYPTION_KEY | 32 random bytes, base64 (openssl rand -base64 32); seals QuickBooks and bank feed tokens. Mark Sensitive; changing it disconnects every QuickBooks connection and bank feed |
PLAID_CLIENT_ID, PLAID_SECRET, PLAID_ENV | Bank feeds: your Plaid team's keys (mark the secret Sensitive); sandbox or production |
PLAID_REDIRECT_URI | optional: https://<your app>/banking/feeds, for banks that sign in with OAuth (register it in Plaid) |
ANTHROPIC_API_KEY | Receipts: Claude reads uploaded receipts (mark Sensitive). Without it, receipts are kept and filled in by hand |
RECEIPT_READER_MODEL | optional; default claude-opus-5-5 (about 1 to 2 cents a receipt); costs a fraction of a cent |
Migrations run from your machine against the direct (port 5432) connection:
DATABASE_URL_MIGRATE=… npm run db:migrate. Add your production URL to
Supabase's redirect URLs. Point an uptime monitor at /api/health.
https://<your app>/api/qbo/callback (exactly NEXT_PUBLIC_APP_URL +
/api/qbo/callback) under its Development and Production settings.QBO_CLIENT_ID, QBO_CLIENT_SECRET, QBO_ENVIRONMENT (sandbox
until Intuit approves production keys), and APP_ENCRYPTION_KEY.PLAID_CLIENT_ID, PLAID_SECRET, PLAID_ENV (sandbox to try it
with Plaid's test banks; production once Plaid approves you), and
APP_ENCRYPTION_KEY.https://<your app>/banking/feeds under Allowed redirect
URIs in Plaid and set PLAID_REDIRECT_URI to it.NEXT_PUBLIC_APP_URL + /api/webhooks/plaid
(set on each connection; nothing to register). The daily job also syncs
every feed, so a missed webhook only delays lines a day.attachments, made by
migration 0039 (no storage policies: only the server reaches it, with
SUPABASE_SERVICE_ROLE_KEY). People open them through /files/<id>
after the app's own checks.ANTHROPIC_API_KEY for Claude to read receipts. Readings use
server-side fallbacks, so a declined read retries on another model.Nobody at Groundworks can see inside a customer's workspace by default.
GROUNDWORKS_SUPPORT_USER_IDS.
They need two-step verification, then find granted workspaces at
/support. Access is read-only (viewer) and ends on expiry.invoice.paid…), per-type approval
policiesSee CLAUDE.md for architecture and conventions.
Proprietary. All rights reserved.
claude-haiku-5-5