Skip to main content
UniversalBench exposes three MCP tools. ub_read handles read-only work using your own credentials. ub_write handles code execution and state-modifying operations. ub_ai handles AI and live web capabilities. Set one or more fields per call within each tool.

ub_read

Read-only operations using your own credentials. Includes database queries, file access, repository reads, and source validation. UniversalBench can connect to any PostgreSQL-compatible database. Provide your database URL and key via the secrets vault and the database inputs auto-inject them.

db_select

Structured query with filters, ordering, and limit. The idiomatic read API.
Filter operators include eq, neq, gt, gte, lt, lte, like, ilike, in_. Order strings prefix - for descending. Select picks specific columns or * for all.

db_query

Best effort SQL parse for SELECT ... FROM tbl [WHERE ...] [ORDER BY ...] [LIMIT N]. Convenient when your AI already wrote the SQL.
For anything beyond plain SELECT, prefer db_select for filters and ub_write code for joins or aggregations. Case insensitive keyword search across one or more text columns.

file_read

Read a file from the workbench filesystem. Returns the file content as text.
Files must be under /tmp. Files written by ub_write code calls in the same session persist for that session.

git_read

Read a file from a GitHub repository. Returns content and the file SHA. Works on private repositories.
Provide GITHUB_TOKEN via the secrets vault and it auto-injects into every git_read call.

validate_file

Static check on Python source. Returns an issues list and, where possible, a fixed version.

session_id

Pass a session identifier to share warm session state with ub_write calls using the same ID.
Read a connected Google Ads account: keyword ideas with monthly search volume and competition, whether your live ads are approved, performance reports (per campaign, per search term, per keyword), the structure of your campaigns and ad groups, and your conversion actions. Pass a plain keyword string for quick ideas, or an object with an operation. Operations: keyword_research, status, accounts, report_campaigns, report_search_terms, report_keywords, structure, conversion_actions. Reports accept a date_range such as LAST_7_DAYS or LAST_30_DAYS, or explicit start_date and end_date. Quick keyword ideas:
Read the account structure to get campaign, ad group, and keyword resource names:
A last-7-days campaign performance report:
If the account has not connected Google Ads access yet, the reply returns a connect link.

ub_write

Code execution and state-modifying operations. Runs in an isolated sandbox. Includes compute, file writes, database writes, GitHub operations, secrets management, and outbound HTTP.

code

Run Python in a sandboxed environment. Returns stdout, stderr, and execution time.
The sandbox includes the Python standard library, common scientific packages (requests, pandas, numpy, etc.), and any packages you install via install_packages. The execution timeout is 60 seconds.

bash

Run a shell command. Returns stdout and stderr.
The working directory is /tmp. Most standard Linux utilities are available. The execution timeout is 60 seconds.

parallel_blocks

Run up to eight code blocks concurrently in one call. Returns a list of results in input order.
Three blocks that each sleep one second take one second total, not three. Useful for independent fetches, parallel data analysis, or fan out queries.

install_packages

Install Python packages before the call. Returns the install log.
Installed packages persist for the duration of the session. Common packages are already preinstalled and do not need to be listed.

file_write

Write a file to the workbench filesystem.
Paths must be under /tmp. Combine with session_id to keep written files available for the next call in the same session.

db_write

Insert one row, or update rows matching a filter.

db_upsert

Upsert one row using one or more conflict columns.

git_push

Push a file to GitHub. Returns the commit SHA on success.
For .py files, Python is validated before the push lands. Files that would crash at runtime are rejected before they reach your repository. Your AI cannot ship broken Python through UniversalBench.

code_diff

Run two code blocks and compare their outputs. Useful for verifying that a refactor did not change behaviour.
Returns the output diff if the two diverge on the same inputs.

code_edit

Single anchor find and replace on a file. Pass the old text and the new text. Ambiguous matches are rejected.
When the anchor appears more than once, the edit is rejected with the count rather than silently editing the wrong place.

safe_deploy

Push a file and run a smoke test against a URL after the push lands. If the smoke test fails, the push is rolled back automatically.

proxy_http

Make an outbound HTTP call from the workbench. Returns status, headers, body, and bytes received.
Only http and https schemes are accepted. Internal network addresses and cloud metadata endpoints are blocked to prevent server side request forgery. Response bodies above a fixed cap are truncated and flagged in the response.

secrets_vault

Encrypted per customer secret storage. Values are encrypted at rest. Your AI references secrets by name, never by value.
The action is save (not set or store), the name field is secret_name (not key or name), and the value field is secret_value (not value). Getting one of these wrong is the most common vault error. See Troubleshooting.
Save a secret:
List secret names (values are never returned):
Retrieve a secret value:
Delete a secret permanently:
Secrets are scoped to your account. Other customers cannot read them. Common credentials like SUPABASE_URL, SUPABASE_KEY, and GITHUB_TOKEN are auto-injected into matching tools so your AI never needs to read the value.

session_id and clear_session

Pass session_id to keep Python variables, imports, and connections warm across calls:
Subsequent calls with the same session_id can reference df and pd without redoing the work. Sessions expire after a period of inactivity. Pass clear_session: true to wipe all state before processing the call:

task

Optional. A natural-language description of what this call is doing. Used for telemetry and adaptive timeout tuning only. Has no effect on execution.

Combining inputs

You can set multiple input fields in one ub_write call:
This installs yfinance and runs the code in one call, billed as one call. Manage a connected Google Ads account end to end. Build campaigns, ad groups, keywords, and responsive search ads, upload image assets, and add a video ad. Set targeting: locations and proximity, ad schedules, languages, device bid adjustments, and audiences. Set bidding (manual CPC, maximize conversions, maximize conversion value, target CPA, target ROAS, maximize clicks) and budgets. Add ad extensions: sitelinks, callouts, structured snippets, call extensions, promotions, and prices. Set up conversion tracking, which returns the tracking snippet to install on your site. Edit a live account: pause or launch campaigns, ad groups, and keywords, change budgets and bids, add negative keywords, and remove items.
New entities are created paused, so nothing spends until you launch it. Any change that can spend money or remove something (launching or enabling anything, raising a budget, changing the bidding strategy, removing an item) returns a short approval request describing the exact change. Relay it to the user, then call again with confirm set to once to do it this time, or always to allow that kind of change for this account from now on. Every change is recorded.
Pass an object with an operation. Build: create_campaign, create_ad_group, add_keywords, create_rsa, upload_image_asset, create_video_ad. Targeting: add_geo_target, add_ad_schedule, set_language_target, set_device_bid_modifier, add_audience. Bidding and budget: set_bidding_strategy, update_campaign_budget. Extensions: create_sitelink, create_callout, create_structured_snippet, create_call_extension, create_promotion, create_price. Conversion tracking: create_conversion_action. Manage: update_campaign_status, update_ad_group_status, update_ad_group_bid, update_keyword_status, update_keyword_bid, add_negative_keywords, remove_campaign, remove_ad_group, remove_keyword, remove_ad.
All money is in micros: multiply the currency amount by 1,000,000, so 50 units is 50000000. Get campaign, ad group, and keyword resource names from google_ads_research with the structure operation first. If a change is rejected, the reply tells you exactly what to fix and what to read, so relay that and retry. For the exact fields of any operation, call how_to on ub_read with the name google_ads.
Create a campaign (created paused, nothing spends):
Launch a campaign (spend-affecting, needs approval):
Set a bidding strategy:
Set up conversion tracking (returns the snippet to install on your site):

ub_ai

AI and live web capabilities. Each ub_ai call incurs an additional provider cost on top of the base per-call rate. Search the web for live results. Returns the top five results with title, snippet, and URL.
Results are real time and include source URLs.

invoke_llm

Call any major LLM. A prompt string goes in, the completion string comes out.
The default model is a cost-efficient one. To route to a specific model, prefix your prompt with model=<name>;, for example model=claude-3-5-sonnet; Write a haiku.... Your AI platform’s tool description lists available model identifiers.

Database setup

Connect to any PostgreSQL-compatible database. Save your database URL and key as named secrets via secrets_vault. Name them SUPABASE_URL and SUPABASE_KEY and they auto-inject on every call.

GitHub setup

Save a personal access token in secrets_vault under the name GITHUB_TOKEN. The git_read, git_push, code_edit, and safe_deploy fields auto-inject it on every call.
The name must be GITHUB_TOKEN. If you save the token under another name such as GIT_PAT or with a typo, the GitHub fields cannot find it and every git_* call fails. If that happens, see Troubleshooting.