MCP App Store
by KeenEthics
PracticPro icon

PracticPro

By PracticPro LLC

Get New App Alerts

Overview

PracticPro is the CRM and operations platform contractors and service businesses use to run their full workflow: clients and leads, estimates, contracts with electronic signatures, invoices and payments, phone calls, SMS, email, scheduling, and custom reports. Inside ChatGPT, every part of that workflow runs in plain English. Examples: "send the Carmichael estimate for signature", "record a $5,000 deposit from Rachel Kim", "text Tony Vasquez to confirm tomorrow's install", "draft a $4,200 invoice for the kitchen demo", or "show jobs with unpaid balances over $10K". Every action executes against your live PracticPro account with your existing permissions.

Tools

practicpro_bulk_submit

ChatGPT
Execute many POST submissions in ONE tool call. Use this AFTER you have already done a successful single practicpro_submit to the same endpoint shape in this conversation - the system tracks proven endpoint patterns and bulk fires only when every item targets a proven pattern. This is the right tool for batch work like "create 50 invoices", "import these 30 expenses", "assign 20 contractors" - one round-trip instead of fifty, dramatically cheaper and faster. The flow is always: (1) do ONE item via practicpro_submit, (2) read its response - if it carries [VERIFIED: ...], the endpoint shape is now proven, (3) bulk_submit the remaining N items. The gate is per-endpoint-shape: a successful POST to /job/12345/vendor/67890/new_invoice unlocks bulk for /job/{N}/vendor/{N}/new_invoice (numeric IDs are normalized). Different endpoints need different proofs. Sequential by default - items run one after another, the next one starts when the previous returns. Items execute sequentially. Parallel mutation is not supported. Rejected items are reported individually. An unknown write outcome stops the remaining batch; reconcile it before retrying. Cap: 50 items per call.

practicpro_column_overlap

ChatGPT
On a custom page (/cp/<page>): which records are counted in MORE THAN ONE column, and in which columns - worked out from every column's own breakdowns (the lists behind its numbers), in code. Use it for "which contacts show up in more than one column", "why do the columns add up to more than the total", "who is counted twice". Read-only.

practicpro_connection_status

ChatGPT
Check the current OAuth connection and accessible companies without switching company or disconnecting.

practicpro_document_editor

ChatGPT
Work with PracticPro document pages (estimates, proposals, contracts, change orders). Actions: "view_page" (see the PDF page as an image to analyze layout), "add_fields" (add fillable inputs like signature, date, text fields for the recipient to fill). The "File layout" section on a document page shows row IDs for each page.

practicpro_get_help

ChatGPT
Fetch specialized PracticPro knowledge on a specific topic. Use this ONLY when you actually need guidance — it is a reference book, not a preface. Available topics: entity_model, create, billing, files, custom_pages, scheduling, phone, email, lifecycle, glossary. Call with no topic to see the list.

practicpro_get_record

ChatGPT
Read authoritative, permission-scoped contact, project or CLIENT invoice fields and financial values. Amounts are exact decimal strings. Returns a revision where supported for safe edits. Prefer this tool for a record summary or client invoice balance. An assignee invoice (a bill from an assignee, a deduction, a credit note) is not an entity here - it is read on its sheet: /job/<job_id>/vendor/<job_vendor_id>/invoice/<id>/sheet.

practicpro_grep

ChatGPT
Search the current page's JavaScript source for a pattern. Returns matching lines with context. Use to locate where a specific symbol is set, find an error code in code, or trace an unfamiliar identifier. Reads from the last page you navigated to.

practicpro_inspect

ChatGPT
Inspect the current page. Three modes: 1. Page sections: pass "forms", "actions", "navigation", "uploads", or "ui_actions" to see that section from the current page. 2. Full content: pass "full_content" to read the complete page body text without truncation. Use when practicpro_navigate says "(body truncated)". Pass offset to read from a specific character position. 3. JS code: pass a button label (e.g. "Save Invoice") or function name to see the code it triggers. Reads from the last page you navigated to. Use when you need details beyond the navigate summary.

practicpro_line_items

ChatGPT
Read or edit the line items (and adjustments) on a proposal/estimate/contract file OR a client invoice. Users call these "line items", "items", "the items table", "prices", or interchangeably "the invoice" - this tool handles both cases. Pick target by the record being edited: a /files/id/N dynamicfile -> target={file_id:N}; a /job/X/invoice/Y client invoice -> target={job_id:X, invoice_id:Y}. When the amount or any field on an existing line item is wrong (wrong amount, missing decimal, off by a factor), use update with that row's index and only the keys you're changing - e.g. changes:{price: 1000}. Other fields on the row are preserved automatically. Five actions: list (read, no change), add (append item or items), update (modify one row at index, merging only the fields in changes), remove (delete one row at index), replace_all (wipe everything and set the whole list - pass items:[] to clear). scope defaults to "items"; pass scope="adjustments" to edit discounts/fees/surcharges instead. Always prefer this tool over raw POSTs to lineitems_update or /invoice/.../update - those are full-replace foot-guns that wipe everything you forget to include.

practicpro_login

ChatGPT
Connect to, disconnect from, or check your PracticPro connection. Actions: "connect" (start login with username), "confirm" (submit the PIN from SMS/email), "disconnect" (log out), "status" (check connection).

practicpro_navigate

ChatGPT
Read a PracticPro page (GET). By default this reads SILENTLY — the user's screen is NOT affected. Pass show_user=true ONLY on the LAST navigation when you want the user to see the result page. To find an entity by name, use /search?search=<term> — do NOT browse list pages and scroll.

practicpro_operation_status

ChatGPT
Check backend receipts for an earlier operation before retrying an uncertain action. Results distinguish completed, rejected, pending and unknown dispatches.

practicpro_preview_action

ChatGPT
Read the resolved recipients, content and attachments for an email send or retry without sending. Review the result and pass its revision as expected_action_revision to the subsequent navigate/submit action. Scheduled campaigns require the PracticPro interface.

practicpro_query

ChatGPT
Run a filtered list query on PracticPro. Use this for every "show me ...", "list all ...", "how many ...", "what is due/overdue/pending ..." question - replaces manual /cp_filters URL construction. The tool validates your entity_type and filter shape against the live company schema BEFORE the query runs and returns clear errors with valid options on any mismatch. Available entity_types and filter_blocks are discovered at runtime from GET /filters/schema; you do NOT need to know them in advance, just pick the obvious entity_type for the user noun (e.g. "invoices" -> job_invoice, "photos" -> uploaded_media, "proposals" / "contracts" / "documents" -> dynamicfile) and the tool will tell you if it is wrong. filters is a dict of filter_blocks; one or many can be stacked in the same call (invoices_filter + jobs_filter scopes invoices to a specific project type). Inner keys of each filter_block must match GET /filters/schema?filter_category=<category>. action="view" (default) navigates to the rendered /cp_filters page, whose header states the TOTAL as "Filtered Results (N)"; action="data" calls /cp_filters/load_data and returns the rows themselves. FOR A "HOW MANY" QUESTION USE action="view" AND READ THAT TOTAL - do NOT count rows by hand. Measured 2026-08-22: asked to count 25 overdue invoices from a data response, the agent answered 24 on one run and 21 on the next, from the same unfiltered-by-nothing result set. The rows were all there; counting them was the unreliable step. Use action="data" when you need the rows (to name them, open one, or read a field), not when you need their number.

practicpro_read

ChatGPT
Read a verified PracticPro page without performing business actions. Use for reading records, search results and navigation lists. Use action tools for requested changes.

practicpro_remember

ChatGPT
Save a fact about the user for future conversations. Use this when the user tells you something worth remembering - their role, preferences, responsibilities, patterns, or important context. This memory persists across sessions and is loaded automatically in future conversations.

practicpro_report_gap

ChatGPT
Reflect on why you are stuck and tell us what is structurally missing. Call this after 2-3 failed attempts on the same operation, or when you realize you are guessing instead of reading. This is NOT a bug report or a "please fix it" request. It is a postmortem: step outside your current attempt, look at yourself, and describe the gap between how you are approaching this and how a real human user would. A good report reads like a researcher reflecting on their own experience, not a stack trace. Shallow reports ("button unclear") waste the slot — we are trying to learn what is invisible to you that a user sees.

practicpro_submit

ChatGPT
Submit a form/action in PracticPro (POST request). Only use URLs from the "Buttons on this page" section that say "use practicpro_submit". NEVER guess POST URLs. IMPORTANT: if the system message at the start of your turn says "BRIDGE ACTIVE", and you are editing a record the user has open in their workspace (updating a route, invoice, job, etc.), use practicpro_fill_input + practicpro_click to drive the form in the user's own browser instead. Direct POSTs via this tool often clobber fields you did not include — many PracticPro save endpoints are full-replace. practicpro_submit is still the right choice for creates, one-shot actions (send, officialize), JSON API endpoints, and anything outside a record edit.

practicpro_update_contact_notes

ChatGPT
Update only a contact’s notes while preserving all other fields. Read practicpro_get_record first and pass its exact revision; a concurrent edit causes a conflict instead of overwriting newer data.

practicpro_upload_file

ChatGPT
Upload a file to PracticPro and attach it to an entity. IMPORTANT: Before uploading, navigate to the target entity page first - the "Upload targets" section at the bottom shows the exact for_type, for_id, and job_id values to use. Never guess these values.

practicpro_view_rendered

ChatGPT
Fetch a PracticPro page as a real user sees it (after JavaScript runs). Use this ONLY when practicpro_navigate returns empty containers or missing form values because the page loads its content dynamically. Slower and more expensive than practicpro_navigate - always try practicpro_navigate FIRST and only fall back to this when the data you need clearly is not in the raw HTML. Returns the fully rendered page text including all input values the user currently sees.

practicpro_website

ChatGPT
Operate a website the user's own company hosts with PracticPro: WordPress content, WP-CLI, the site database, files under that site's web root, and its logs. Scope is the websites on this company's account - website_id is checked against them on every call - plus read-only server health. Changes are real and visitors see them immediately, so work the way you would on any live site: read the current state before you change it, and get the user's approval before anything destructive. Credentials are out of scope: the three change_*_password server actions are refused, since reaching them would mean a secret travelling through this conversation. If the user needs one rotated, tell them to do it in the hosting control panel. Never ask for one, and never invent one for them. You can BUILD a site with this. Pages, posts, menus, plugins, themes, options, theme files, redirects, DNS, SSL. Never tell the user to go do it in WordPress themselves, and never hand them a to-do list of things to click in wp-admin - you have the same reach they do, and more. WORK IN THIS ORDER, every time: 1. LOOK FIRST. action:'info' for what the site is (WP version, PHP, plugin counts, disk, DB size). action:'wp_cli' with "plugin list --format=json" / "theme list --format=json" / "post list --post_type=page --format=json" to see what is actually there. Never assume a theme, plugin or page builder is installed - check. 2. CHANGE. Prefer the highest-level tool that does the job: 'wp_cli' or 'wp_rest' for anything WordPress models (pages, posts, menus, options, plugins). Drop to 'write_file' only for theme/template files WordPress has no command for, and to 'sql' only when neither can express it. 3. VERIFY - this is not optional and you do not get to skip it. "Saved" and "working" are different claims and you must prove the second one: a. Re-read the object: 'wp_rest' GET the page id, or 'wp_cli' "post list --post_type=page --format=json". b. action:'fetch_page' on the real URL. This is the only check that proves a visitor sees the page - a page can exist in the database and still 404 on stale rewrite rules, white-screen from a theme fatal, or be served stale from cache, and every other check says success through all three. Read the verdict line it returns FIRST. c. action:'error_log' for PHP errors your change introduced. A change you have not fetched back is a change you cannot claim. Say what you verified and how. If fetch_page comes back BROKEN, fix it or roll back - never report success. Actions: - info: site facts. Cheap, start here. - fetch_page: GET one of this site's own public URLs and see exactly what a visitor gets - status code, redirects, and the HTML, plus a verdict flagging 404s, PHP fatals, DB errors and maintenance mode. Use it after every change, and before one when you need a baseline. - wp_rest: WordPress REST API. {endpoint:'/wp/v2/pages', method:'POST', data:{title, content, status}}. Best for creating/updating content with real HTML bodies. - wp_cli: WP-CLI over SSH, run as the site's own user. PAGE AND POST BODIES GO IN content, NOT in command: put "-" where the body argument belongs and pass the HTML in content. Prose in the command breaks on the first apostrophe, and there is no length limit worth fighting - content is a separate channel for exactly this reason. Judge the RESULT, not the absence of an error: a command that returns empty data or carries "warnings" did not do what you asked, even when the call itself came back fine. {command:'plugin install classic-editor --activate'}. Allowed top-level: post, page, media, plugin, theme, option, menu, widget, search-replace, user, core, site, comment, term, taxonomy, rewrite, cache, transient, cron, sidebar. Blocked: eval, shell, config get/set, db drop, user create/delete/role. No shell metacharacters (; && || | ` $( ) - one command, no pipes. Add --format=json when you want parseable output. - sql: MySQL on the site DB. Read-only unless you pass allow_write:true. DROP/TRUNCATE/GRANT/INFORMATION_SCHEMA are blocked outright. Use wp_cli first - it keeps caches and hooks correct w…

Capabilities

WritesInteractive

Example Prompts

Click any prompt to copy it.

Similar Apps