MCP tools
Pie’s MCP server gives your AI agent the core tools to set up an app, write and run tests, read results, triage issues and scan merged changes. You can call any tool by describing what you want in plain language.
To connect an agent, see Connect your agent. For more example prompts, see Prompt Pie. To hand an issue to an agent and get a fix back, see Fix bugs with your agent.
Connection details
- Server:
https://mcp.pie.inc - Transport: Streamable HTTP
- Authentication: Your API key in the
X-API-Keyheader.
How the tools fit together
An app has builds (uploaded mobile binaries), test cases identified by numeric IDs, optional test suites, and key features. Key features are also called groups, and a test case’s groupId holds a key feature ID. A run executes test cases against a build (mobile) or a URL (web) and produces per-test results plus findings. Findings deduplicate across runs into app-level issues.
A typical flow is get_testcases to find IDs, run_specific_testcases to execute them, get_run_progress to poll, get_results to read the outcome, and then the triage tools. To edit a test and run it again, call update_testcase and, once that call returns, run_specific_testcases.
Test-case steps and prompts accept two kinds of reference. Write #{script-name} to run an execution script, and @{credential-name} to use a stored login.
ID parameters use lowerCamelCase, such as runId, testCaseId and buildId. The server also accepts legacy spellings such as runID. List parameters accept a JSON array or a comma-separated string.
Tools that return lists paginate with a cursor. When more results are available, the response includes a nextCursor value. Pass it as cursor in your next call, and omit cursor for the first page.
Setup and builds
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_app | Fetches the app’s configuration: ID, name, platform and settings. | None | |
health_check | Confirms your agent is connected to Pie’s MCP server. | None | Pie checks your API key when the agent connects, not in this tool. |
get_available_icons | Lists the icons you can give a key feature. | None | Use a returned name as icon in manage_key_features. |
get_builds | Lists uploaded builds with IDs, file types, sizes, upload dates and download URLs. | cursor | Use it to find a buildId for a run. Paginated. |
Try asking:
- “Show me my app details.”
- “Check if Pie is connected.”
Credentials and scripts
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_credentials | Lists the app’s credentials with ID, name, username and default status. | None | Passwords are never returned. |
create_credential | Creates a login credential. | name, username, password (all required); isDefault (boolean) | Marking a credential as default removes the default flag from the others. Reference it in steps as @{name}. |
update_credential | Updates part of a credential. It keeps its ID, so every test case and @{name} step keeps working. | credentialId (required); name (not blank, unique); username; password; isDefault | Renaming changes the @{name} reference key. Use this to rotate a password instead of creating a second credential. |
get_scripts | Lists execution scripts with ID, name and shell command. | None | Scripts are shell commands that Pie runs during a test. |
create_script | Creates an execution script. | name, instructions (both required; instructions holds the shell commands) | Reference it in steps as #{name}. |
update_script | Updates part of a script. It keeps its ID. | scriptId (required); name; instructions (not blank) | #{name} references resolve fresh at run time, so edits apply on the next run. |
delete_script | Deletes a script. | scriptId (required) | Refuses while test cases still reference the script through #{name} and lists them. There is no force flag. |
Try asking:
- “Show me all saved credentials.”
- “Create a default credential for the test account.”
- “Show me all available scripts.”
For script parameters, see Script parameterization.
Discovery and key features
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
trigger_rediscovery | Re-runs one test case with awareness of UI changes and updates it if needed. | testCaseId (integer, required); rediscoveryInstructions (what changed, for example “The navigation menu was redesigned”) | More context gives better results. |
manage_key_features | Lists, adds, updates or deletes key features. | action (required: get, add, update or delete); keyFeatures (array of objects, required for add, update and delete) | Each object takes id, name, description, icon, prompts, sortIndex and star. id is required for update and delete, and name for add and update. The id becomes groupId on test cases. |
Try asking:
- “List the key features and provide an overview.”
- “Rediscover test case 42, because the navigation menu has been redesigned.”
Test cases
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_testcases | Lists test cases with ID, title and description. | detailed (boolean); testCaseIds (comma-separated); archived (true or false); status (comma-separated from active, in-creation, archived, issue-linked); testSuiteId; groupId (key feature); createdAfter and createdBefore (YYYY-MM-DD or RFC 3339); createdBy (pie-pr-bot returns the test cases Pie PR Bot created); inbox (true lists proposed tests still waiting in the PR scan inbox); loopId (narrows the inbox to one Loop); cursor | By default it returns only active test cases. Use detailed with testCaseIds only, to avoid large responses. inbox can’t be combined with testSuiteId. |
create_custom_testcase | Creates a test case from a plain-English prompt, then queues and runs it. | prompt (required); runId; credentialId; suiteIds (suites to add the new test case to); buildId (mobile); bypassPrep (true runs the prompt exactly as written); bundleId (legacy override URL for web app tests); mobileActionsEnabled (Phone controls for iOS: lock or unlock the phone, quit the app, install a build, use Siri); watchActionsEnabled (Watch controls for iOS: open and use the app’s Apple Watch app) | runId defaults to the most recent default run. Use get_credentials to find a credentialId. On a mobile app, if the run’s build is older than your newest upload and you omit buildId, the tool asks which build to use instead of creating the test case. Pass a prompt from draft_testcase_prompt unchanged, with bypassPrep set to true. Phone and Watch controls are experimental and off by default. Watch controls need an iOS build that includes its Watch app. |
draft_testcase_prompt | Turns plain-English intent into a ready-to-run test-case prompt, with the app’s credentials (@{name}) and scripts (#{name}) filled in. It reuses the setup of the most similar test cases. | prompts (array of up to 50 strings, required; a single string is accepted) | Read-only: it creates nothing. It flags when a test case already covers the same ground. Use it before create_custom_testcase when you do not know the credential and script names. It draws on the app’s 500 most recent test cases. |
update_testcase | Updates a test case’s title, description, steps, assertions, key feature or credential. | testCaseId (integer, required); title; description; steps (string array); assertions (string array); groupId; credentialId; bundleId (an empty string clears it) | Supports partial updates. Use manage_key_features with action=get to list groupId values. |
archive_testcases | Archives test cases. | testCaseIds (integer array, required) | Archived test cases do not run. |
unarchive_testcases | Restores archived test cases. | testCaseIds (integer array, required) | |
add_testcase_to_suite | Adds a custom test case to the main suite and takes it out of in-creation status. | testCaseId (integer, required) | After this, the test case runs in normal executions. |
Try asking:
- “List all my test cases.”
- “Create a test case that verifies the checkout flow: add an item to the cart, proceed to checkout, and confirm the order.”
- “Update test case 42: change the title to ‘Login with SSO’ and add an assertion that the user sees the dashboard.”
- “Archive test cases 5, 8 and 12.”
Test suites
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
create_test_suite | Creates a suite to group test cases. | name (required); testCaseIds (integer array); suiteInstructions (custom instructions that override app-level instructions); suiteURL (browser platforms only); osVersion (Android OS version, for example 34 or 36) | |
get_test_suites | Lists suites with names, IDs and test case counts. | None | |
update_test_suite | Updates a suite. | testSuiteId (required); name; addTestCaseIds; removeTestCaseIds; suiteInstructions; suiteURL; osVersion | Supports partial updates. |
delete_test_suite | Deletes a suite. | testSuiteId (required) | The test cases are not deleted, only unlinked from the suite. |
Try asking:
- “Show me all test suites.”
- “Create a test suite called ‘Smoke Tests’ with test cases 1, 5, 12 and 20.”
- “Add test cases 25 and 30 to the Smoke Tests suite.”
Runs
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
create_run | Creates a new run for a suite or for selected test cases. | testSuiteId (required unless you pass testCaseIds); testCaseIds (integer array); buildId; osVersion (for example 18.2 for iOS or 34 for Android); url (browser URL override) | Pass testSuiteId or testCaseIds. Without either, the call fails, because the default library cannot run as a suite. To rerun tests inside a run you already have, use run_specific_testcases instead. |
run_specific_testcases | Executes test cases by ID. | testCaseIds (integer array, required); runId | runId defaults to the most recent run. If you have a description and no IDs, call get_testcases first. |
run_tests_on_target | Creates a run that bundles test cases you already have and new test cases generated from plain-English prompts under one runId. | existingTestCaseIds (positive integers); newTestCasePrompts (each creates a new custom test case); buildId; url; osVersion; bypassPrep (true passes prompts through as written) | Mobile apps need buildId and web apps need url. At least one of the two test lists is required. Invalid or archived IDs come back in invalidTCIDs and are skipped. It returns the runId immediately, so poll with get_runs and get_results. |
get_runs | Lists the app’s runs with IDs, build info, status and timestamps. | cursor | Paginated. |
get_run | Fetches one run: build, status, scope, timestamps, selected test case IDs and creator, plus two configuration blocks. | runId (required) | “Executed With” is frozen when the run is created (OS version, device variant and start URL) and is authoritative for what the run used. “Test Suite (current state)” is the suite as it is now, and can differ if the suite was edited after the run started. The response says so. |
get_run_progress | Checks whether a run is still executing. It returns counts of pending, in-progress and done work items plus an isRunning boolean. | runId (required) | Use it to poll for completion after you start a run, then fetch the outcome with get_results. |
generate_tests_on_local | Produces a command template to run in your terminal, for exploring test cases against a localhost URL. | prompts (string array); localhostUrl | Both parameters are optional. Your agent fills in the template and runs it. |
get_local_test_results | Fetches results and findings for a completed local test execution. | testCaseId (integer, required); runId | Call it only after the execution has finished with a Pass or Fail status. It was renamed from start_test_monitoring, and the old name is still accepted. |
Try asking:
- “Show me all test runs.”
- “Run the Smoke Tests suite on build release-42.”
- “Run test cases 12, 15 and 23.”
- “Is run 8321 still going?”
Results and evidence
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_results | Fetches test results with Test ID, title, pass or fail, reasoning and findings. | detailed (boolean); runId; testCaseIds (comma-separated); status (Pass or Fail); withImages (true adds image URLs to steps); cursor | runId defaults to the most recent run. Use detailed with testCaseIds only, to avoid large responses. |
get_findings | Fetches findings for one run. | runId; status (pending, approved or rejected); testCaseId; cursor | Findings belong to one run. Issues are the deduplicated, app-level version of findings. |
approve_findings | Confirms findings as valid, moving them from pending to approved. | findingIds (required); runId | |
reject_findings | Marks findings as false positives. | findingIds (required); rejectReason; runId | |
get_step_doms | Fetches the page content (HTML) recorded at each step of a test case execution, a page at a time. | testCaseId (integer, required); runId; sequenceId (one exact attempt; needs runId); stepIds (up to 30); limit (1 to 50, default 10); cursor (needs runId) | Content can be large, so limit it with stepIds. Large pages are marked as truncated, and a step with no capture is marked domAvailable=false. |
get_sequences | Lists the execution attempts in one run, optionally for one test case, including superseded attempts and each attempt’s recorded verdict. | runId (required); testCaseId; limit (1 to 50, default 10); cursor | Returns metadata only, with no steps. Use get_sequence to read one attempt. |
get_sequence | Reads one exact execution attempt and a page of its steps. It returns that attempt’s own recorded verdict, never a newer rerun’s. | runId, sequenceId (both required); testCaseId; stepIds (up to 30); limit (1 to 50); cursor; withImages (short-lived signed screenshot URLs) | Pair it with get_step_doms for page-content evidence. |
Try asking:
- “Show me the results from the most recent test run.”
- “List all failed tests from run 8321.”
- “Show me the detailed execution steps for test case 42.”
- “Show me the content for steps 1 and 3 of test case 42.”
Issues
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_issues | Lists issues with ID, title and description. | detailed (boolean); resolution (comma-separated from active, resolved, rejected; defaults to active); triage (comma-separated from approved, pending); testSuiteId; runId (the run where the issue was first found); cursor | Use detailed for resolution status, test case info, steps and assertions. Use active,resolved,rejected to see everything. |
get_issue | Fetches one issue. | issueId (required); detailed (boolean) | detailed adds test case info, steps, assertions and comments. |
reject_issues | Closes issues as false positives. | issueIds (required); rejectReason; undo (boolean) | undo reverses a rejection back to pending and ignores rejectReason. A member key can’t change an issue that Pie staff already rejected. |
resolve_issues | Closes issues as fixed, moving them from active to resolved. | issueIds (required); dismissedReason | |
get_issue_repro_history | Summarizes whether a fix holds. For tracked issues, Pie uses the generated repro test case as the signal: a pass means the issue is likely resolved, and a failure means it is still reproducing. For untracked issues, Pie infers it from the affected test cases’ history. | issueId (required) | Returns a verdict, the evidence source, the most recent signal and the recent trend. |
investigate_app_issue | Asks Pie to investigate a problem you observed. It creates an issue immediately, then tries to reproduce it in the background. | description (required: what you expected and what happened); credentialId; attachments (array of {kind, gcsPath, mimeType, originalFileName, sizeBytes} where kind is image, video, log or file); externalTicket ({provider, externalId, url} where provider is jira, linear or asana) | Matches the Investigate an app issue sheet in the app. Attachments must already be uploaded to the app’s reported-issue upload area. |
Try asking:
- “List the issues.”
- “Show me the details for issue 123.”
- “Reject issue 103 as a false positive, because the expected behavior changed in the most recent release.”
- “Resolve issues 104 and 105. They are fixed in the most recent build.”
Coverage scans
A coverage scan reads the changes merged in a window, generates tests for the product behavior those changes could have broken, and folds the resulting runs into one review. Any member can start a scan. Pie reviews and publishes it. See Run a coverage scan.
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
trigger_coverage_scan | Starts a repository-backed coverage scan for the active app. | days (1 to 90, default 7); since and until (an exact RFC 3339 pair, not combined with days); commitSha (7 to 40 hex characters); branch; includePaths (path globs); regressionSuiteIds (up to 20 suite IDs); buildId; idempotencyKey | The scan is asynchronous: the tool returns once the request is accepted, not when the scan finishes. commitSha pins the analysis to that commit, so only changes reachable at it are scanned. branch defaults to the connected repository’s default branch. Browser apps omit buildId. iOS and Android apps need the buildId of a verified build: upload the build through POST /v1/app/builds/coverage-scan, or pick one already uploaded with get_builds. Reuse idempotencyKey when you retry the same request. Any member can start a scan. |
Try asking:
- “Run a coverage scan over the last 7 days.”
Bounding-box correction
| Tool | What it does | Parameters | Notes |
|---|---|---|---|
get_bbox_evaluations | Fetches bounding-box evaluations that need a human correction. | isProcessed (true or false); isVerified (true for verified, false for pending); limit (1 to 100, default 50) | |
submit_bbox_correction | Submits a corrected bounding box for a test case step. | testCaseId, runId, seqId, stepId and correctedBBox (all required; correctedBBox is a JSON array [x, y, width, height]) |
Combine tools for reports
Some prompts chain several tools:
- “Create a testing summary including total tests, pass rates, new issues and critical blockers” reads runs, results and issues.
- “Compare the last 3 test runs and identify trends in failure rates” compares recent runs and highlights improvements or regressions.