MCP And Tools
Voxos exposes two broad tool families to agents: built-in internal tools and user-owned remote MCP tools. Tool access is policy-driven and audited.
Voxos uses MCP Python SDK 2 for remote transports and exposed internal servers. Streamable HTTP clients use an explicit HTTPX 2 client with bounded timeouts; redirect responses are rejected before another request is sent. Broker assertions are minted for each outbound HTTP request.
Internal Tools
Section titled “Internal Tools”Internal tools operate on Voxos-owned agent data for the authenticated user. Current internal tools include:
| Tool | Risk | Kind |
|---|---|---|
search_agent_history |
Medium | Account evidence search |
read_agent_history |
Medium | Bounded cited context |
record_agent_improvement |
Medium | Policy-assessed knowledge candidate |
list_agent_memories |
Low | Read-only |
list_agent_skills |
Low | Read-only |
get_agent_skill |
Low | Read-only |
list_task_plans |
Low | Read-only |
search_contacts |
Low | Read-only, denied by default |
delegate_agent_task |
Medium | Queues a durable child run with a user-allowed model |
create_agent_memory |
Medium | Mutating |
propose_agent_memory |
Medium | Mutating |
archive_agent_memory |
Medium | Mutating |
create_user_skill |
Medium | Mutating |
update_user_skill |
Medium | Mutating |
archive_user_skill |
Medium | Mutating |
create_task_plan |
Medium | Mutating |
create_agent_schedule |
Medium | Schedules a future turn in the current chat |
update_task_step |
Medium | Mutating |
complete_task_plan |
Medium | Mutating |
The docs index adds read-only product documentation tools. Those tools are safe to grant because they read global product docs rather than user secrets.
search_contacts searches only the authenticated user’s saved contacts and
returns a typed not_found, unique, or ambiguous resolution with contact
IDs, display names, and full phone numbers. It does not return notes, email
addresses, or admin flags. Agents are instructed to search first for a named
person, proceed with a unique match, ask the user to choose between ambiguous
matches, and ask for a number or contact creation only when no match exists.
Access remains controlled by the authenticated tenant and agent grant. Connecting a call-capable Twilio or Telnyx resource adds this low-risk prerequisite to the default agent only when no explicit contact-search decision exists. Migration backfill follows the same rule for existing allowed place-call grants. An explicit denial is never replaced; while denied, the dependent place-call integration tool is not advertised to that agent.
An approved phone integration tool resolves the returned contact ID inside the same tenant and requires a complete bounded caller-safe objective. The initiating run ID comes from trusted execution context rather than model arguments. The objective becomes durable phone-session context but does not expand caller access, MCP trust, or the effective tool-policy snapshot.
delegate_agent_task is denied by default and requires an explicit internal
tool grant. It accepts a scoped task, isolated or summary context, and an
optional model from the user’s provider-specific subagent allowlist. It does
not accept user, agent, run, session, provider, credential, URL, or token
authority in model arguments. The parent run and target agent are derived from
trusted execution context, and the child cannot expand the parent’s tool
permissions. A child does not inherit delegate_agent_task; nested
self-delegation therefore cannot recursively requeue the same unavailable
capability. Delegation is intended for independent multi-step work, not as a
way to reach a tool that is already available in the current run. Agents should
call a direct tool, or use the run’s tool catalog, for ordinary single-action
lookups.
create_agent_schedule is available only during an interactive authenticated
text-chat turn and only for explicit reminders, future checks, monitoring, and
follow-ups. It creates a one-shot or fixed-interval schedule whose future
responses return to the current chat. The authenticated run context supplies
the owner, agent, run, and chat authority; the model supplies only the task
name, future instruction, timing, and timezone. The tool does not accept
another chat or a Browser Account, and scheduled runs, webhooks, manual worker
runs, and subagents cannot use it. create_task_plan remains a planning record
and does not schedule execution or notifications.
Default Web Search
Section titled “Default Web Search”Each new account starts with the canonical keyless Exa MCP endpoint enabled,
trusted, and connected for web_search_exa and web_fetch_exa. A data
migration adds the same server for existing accounts that do not already have
an Exa endpoint. Existing Exa records are left unchanged so a previous opt-out
or custom API-key setup is not replaced.
The platform default stores a versioned snapshot of the two low-risk tool schemas, so normal chat and voice startup do not need a discovery request. An explicit MCP connection test refreshes that cached discovery data from Exa. If an older or incomplete server record is missing a schema for an allowed tool, the runtime performs one live capability discovery, uses the returned schema for the current run, and repairs the bounded cache for later runs. Allowed tools are stored first when a server exposes more definitions than the cache limit. Only tools returned by cache or live discovery are exposed; the runtime does not invent an empty schema for a missing definition. Only the exact canonical keyless preset identity, transport, URL, and auth mode qualify for platform-default access.
Every agent receives low-risk default grants for those two tools while the server remains enabled, trusted, connected, and allowlisted. A persisted denied grant overrides the default for that agent. Users can also disable the Exa server from MCP settings, which removes it from newly created text runs and voice sessions; enabling it again follows the normal test-and-grant flow. Keyless access is subject to Exa’s free-plan limits, and users can configure the API-key preset when they need higher limits.
Tool Approval Flow
Section titled “Tool Approval Flow”- Open Tools.
- Toggle each internal tool that the default agent may use.
- Start a text run or voice session.
- The run receives an effective tool policy snapshot.
- Tool execution checks that snapshot or the persisted grant.
- An audit event records allow/deny decisions.
The Tools page also configures action-level provider routing. A route groups
equivalent implementations without grouping unrelated tools from the same
server. For example, web.search includes Exa web_search_exa, Tavily
tavily-search, Firecrawl firecrawl_search, and Browserless
browserless_search. Automatic mode selects the lowest-priority authorized
implementation: Exa is the current default, followed by Tavily, Firecrawl, and
Browserless. Browserless scrape, map, performance, export, agent, and other
browser capabilities remain separate tools and are unaffected by the web-search
route.
A pinned route names an exact tool and server. If that implementation becomes unavailable or loses its grant, the route exposes no substitute until the user changes it; pinned routes never silently fall back. Automatic routes can select the next authorized implementation. The resolved choice is stored in the same effective policy snapshot as the grants, so it cannot change during an active run or voice session.
Browser Use And Saved Profiles
Section titled “Browser Use And Saved Profiles”The recommended Voxos Local Browser is a built-in Browser Account provider and does not use MCP. Browserless and Browser Use Cloud remain optional hosted connections configured under MCP, while reusable website identity is managed separately under Browser Accounts. A hosted Browser Account references one exact enabled, trusted, connected provider connection and reuses its encrypted provider token rather than duplicating it.
Browserless stored-credential accounts require static bearer authentication and
an explicit browserless_agent allowlist/grant. Browser Use managed-profile
accounts require API-key-header authentication and run_session. Both tools
are high risk and disabled by default in their presets.
Web chat and authenticated in-app voice expose one general use_browser
capability. It accepts an agent-authored instruction plus either a public HTTPS
start URL or an opaque saved-profile handle. The tool description lists only
the safe labels, primary origins, and handles for profiles assigned to that
exact agent after intersecting hosted profiles with their underlying MCP grant.
Execution performs the same checks again. Phone callers and subagents do not
receive saved-profile authority.
A scheduled task can instead reference one ready assigned stored-credential local or Browserless account; that binding is validated at schedule creation and again from the persisted scheduled root run. Voxos resolves provider and website credentials, profile origins, and budgets server-side. Public browsing accepts validated HTTPS URLs; saved profiles cannot override or broaden their configured origins. Ordinary generic MCP arguments cannot supply raw account IDs, provider sessions, or credentials. See Browser Accounts for setup, provider trust, action policy, threat model, and incident response.
Large Tool Catalogs
Section titled “Large Tool Catalogs”Voxos resolves grants and action routes before composing the model’s tool view. Small catalogs continue to attach their tool schemas directly. When the authorized external catalog reaches ten tools or roughly 10,000 schema tokens, text runs keep internal tools and the selected implementation of each preferred action direct. Only the remaining long-tail external tools move behind three catalog tools:
tool_searchsearches only the run’s authorized, route-resolved catalog.tool_describereturns the full schema for one opaque result ID.tool_callvalidates the target arguments and delegates to the original authorized provider.
Catalog IDs are scoped to the current run view. Searching, describing, or calling a result cannot add a grant, select a filtered provider, supply a user or server identity, or bypass the target tool’s existing argument validation and authorization audit. The run builds this registry once from tool definitions cached by the server’s explicit connection test; it does not rediscover every MCP server while preparing a chat or again before dispatching a tool call. Execution still uses the live authenticated MCP connection. Voice keeps direct LiveKit tools to avoid adding a search round to realtime conversations, but it applies the same snapshotted action route before composing those tools.
LiveKit voice sessions persist the same kind of effective policy snapshot before
tools are composed. Provider phone calls add a caller-access intersection:
limited callers can receive web_search_exa only through a qualifying Exa
server identity, while admin contacts and authenticated browser sessions retain
the channel’s normal approved policy. A qualifying server must belong to the
same tenant, use a canonical URL from the current exa preset, retain
preset_id=exa in its safe metadata, be enabled, trusted, and connected, and
explicitly allow web_search_exa. The selected agent’s base policy must also
already grant that exact server ID and tool. A custom server or gateway that
merely advertises a tool with the same name does not qualify. The restriction
applies to both tool enumeration and execution.
Inbound SMS and WhatsApp peers have a separate channel intersection because
receiving a message does not authenticate the sender as the tenant owner. The
reply run keeps only granted low-risk current-time/product-doc tools plus
granted web_search_exa from the tenant’s enabled, trusted, connected
canonical Exa preset server. When the exact normalized sender number matches a
saved Admin contact, the intersection may also retain an existing
search_contacts grant. Unknown and non-admin senders cannot receive contact
access. Contact results remain limited to IDs, display names, and phone-number
endings.
Admin caller status on either messaging medium does not expose
create_task_plan, create_agent_schedule, integration delivery, private
memories, credentials, other mutating tools, or arbitrary outbound actions.
create_task_plan stores a plan but does not schedule execution or send
communications. The authenticated text-chat scheduling tool can only target
its current chat; it cannot address an inbound messaging sender. The
communications adapter, not an LLM tool call, delivers the reply to the
persisted verified sender.
Location-Aware Tool Calls
Section titled “Location-Aware Tool Calls”For a foreground text turn or owner in-app voice session with a fresh shared location, the agent instructions provide WGS84 latitude, longitude, horizontal accuracy, and capture time. The model uses the location only when it materially helps the request, such as nearby place search, maps, travel, or local weather.
The discovered tool schema remains authoritative. Voxos does not inject one global coordinate field into every MCP call. The agent translates the snapshot to the tool’s required latitude/longitude, lat/lon, location-bias, or structured location shape. GeoJSON coordinate arrays use longitude then latitude. A street address or place name must be resolved by a suitable map or geocoding tool; it must not be inferred from coordinates. Curated preset normalization still applies after the model produces schema-valid arguments, including Google Maps Grounding Lite’s camelCase location contracts.
Google Maps Grounding Lite search_places has a typed presentation adapter.
Successful structured results are validated into place cards from the returned
Place ID, attribution title, exact place and directions URLs, and optional
coordinates. Invalid cards are skipped independently without inventing missing
fields. Google URLs must resolve to supported Maps destinations and cannot use
credential-like query fields, fragments, or nonstandard ports. The full result
remains available to the model and the current response stream, while durable
tool and runtime events store only a completion or failure marker and the
assistant transcript text. The completed answer receives at most six cards,
preferring places it names or cites and otherwise using the most recent search.
This prevents Google Maps place content from being retained in chat history.
Other MCP place tools continue to render their ordinary answer links until they
have a provider-specific result contract and attribution adapter.
Remote MCP Servers
Section titled “Remote MCP Servers”MCP servers are user-owned and remote-only. Voxos accepts Streamable HTTP and SSE MCP transports. Local stdio commands are intentionally rejected by the frontend because they would let browser users register commands on the worker host.
Supported auth modes:
- No auth.
- Static bearer token.
- API key header.
- OAuth authorization code.
- OAuth client credentials.
- Private-key JWT.
Browser OAuth requires a persistent deployment-level
MCP_OAUTH_STATE_SIGNING_SECRET. This is a Voxos callback-integrity secret, not
a provider credential and not a per-user secret. Keep it identical across API
replicas. OAuth client details, the PKCE verifier, tokens, and refresh tokens
remain encrypted in the user secret vault.
For providers with OAuth metadata and dynamic client registration, the catalog does not ask the user for a client ID or client secret. OpenBnB follows this path: select Start sign-in, approve access on the hosted OpenBnB page, then return to Voxos. The page tests the authenticated server and discovers tools when focus returns; Finalize connection provides a manual retry if needed.
The MCP page supports a catalog of common remote MCPs and a custom server form. After creating a server, authenticate it if required, test discovery, set explicit allowed tools, and approve grants for agents.
Curated MCP Example Skills
Section titled “Curated MCP Example Skills”Operators can copy useful MCP-backed example workflows into one user’s editable
skills without loading every available example. The catalog, Markdown bodies,
and dedicated loader scripts live under examples/skills/:
make example-skills-listmake example-skills-load USER_ID=<local-voxos-user-id> MCP=github DRY_RUN=1make example-skills-load USER_ID=<local-voxos-user-id> MCP=githubThe loader matches servers by canonical preset and optional variant metadata, not by a user-editable label or database ID. Before any skill write, it verifies that every dependency belongs to the selected tenant, is enabled and trusted, and still advertises and allows every required upstream tool. A server that needs authentication or remains untested can produce an editable installed skill with a visible readiness warning; reconnect or test it before trying to run the workflow. Disabled, untrusted, failed, missing, undiscovered, or unallowed dependencies block only the affected skill.
Installing an example does not authenticate an MCP server, test a connection, change an allowlist, create an agent tool grant, or expose credentials. Runtime use still requires an enabled, trusted, connected server and an exact server-specific grant for the selected agent. Existing skill slugs are never overwritten, so user edits and archived copies are preserved.
The OpenBnB accommodation-shortlist example requires airbnb_search,
airbnb_listing, maps_distance_matrix, maps_search_places, and
maps_place_details to remain both discovered and allowed. It compares a
bounded set of date- and guest-specific listings against travel anchors and
nearby essentials. It does not book accommodation, and users must verify
current price, availability, rules, and cancellation terms on the provider
site.
Google Workspace Setup
Section titled “Google Workspace Setup”Google Workspace MCP is currently available through the Google Workspace Developer Preview Program. Google hosts a separate MCP endpoint for each Workspace product, so Voxos creates one server connection for each selected product. The Voxos catalog currently includes Gmail, Google Drive, Google Calendar, Google Chat, and People. You can reuse the same Google OAuth web client ID and client secret for each connection, but you must authorize and test each server separately.
Follow Google’s Google Workspace MCP configuration guide for the current provider requirements. The shortest setup path is:
-
Join the Google Workspace Developer Preview Program.
-
In the Google Cloud console, create or select a project.
-
In APIs & Services, enable both the standard API and the matching MCP API for each product you want to connect:
Voxos product Standard API MCP API Gmail Gmail API Gmail MCP API Google Drive Google Drive API Google Drive MCP API Google Calendar Google Calendar API Google Calendar MCP API Google Chat Google Chat API Google Chat MCP API People People API People MCP API -
In Google Auth Platform, configure:
- Branding: give the OAuth app a recognizable name such as
Voxos. - Audience: choose Internal when available. Otherwise choose External and add each permitted Google account as a test user.
- Data Access: add only the scopes for the products you intend to use. Copy the current scope list from the OAuth consent section of Google’s guide.
- Branding: give the OAuth app a recognizable name such as
-
Under Google Auth Platform → Clients, create a Web application OAuth client. Add the exact OAuth redirect URI displayed by the Voxos MCP form under Authorized redirect URIs. A default local installation normally displays:
http://localhost:7100/api/mcp/auth/callbackUse the value shown by your running Voxos installation if it differs. Google requires an exact match.
-
Create the client and copy its client ID and client secret. Keep the secret private.
Then connect each product in Voxos:
- Open MCP, select Google Workspace, and choose one product under Variant.
- Paste the Google OAuth client ID and client secret.
- Select Connect Google Workspace, approve the requested Google access, and return to Voxos.
- Finalize or test the connection, review the discovered tools, and grant only the tools the agent needs. Prefer read-only tools until a workflow requires a write action.
- Repeat for each additional Workspace product. Reuse the same OAuth client ID and secret; do not create another Google Cloud project or OAuth client.
For Google Chat, complete the additional Chat app configuration described in Google’s guide before connecting it. If Google reports a redirect mismatch, compare the URI in the Voxos form with the OAuth client’s authorized redirect URI character for character. If an External OAuth app rejects the account, confirm that account is listed under Audience → Test users.
The Auth panel can replace a stored OAuth client by submitting both the client ID and client secret with Save client & start sign-in. Voxos stores the replacement in the encrypted vault before opening the provider. Leaving both fields blank reconnects with the existing client. Delete server is available in Auth and Advanced and removes the server together with its stored MCP credentials.
Flightradar24 has two catalog choices. Local Compose appears only when the
API registry contains the exact http://flightradar24-mcp:8000/mcp URL for the
mcp purpose; select it after starting the root Voxos stack and
make mcp-stack-up. It does not require a custom server entry or Voxos bearer
token. Deployed HTTPS endpoint accepts the complete public HTTPS URL of a
separately deployed instance, including a custom hostname and path. Arbitrary
unregistered private or loopback URLs remain blocked.
Monzo has one Local Compose choice. Voxos stores the separate MCP endpoint bearer plus each user’s confidential-client OAuth data and rotating Monzo tokens. The sibling container stores no provider credentials. Voxos sends its endpoint bearer and a short-lived, user-and-server-bound delegation; the container exchanges that assertion at the private Voxos broker for only the current access token.
The stateless container can serve multiple Voxos users. Local Compose is
available only when http://monzo-mcp:8000/mcp is registered for the mcp
purpose. The preset exposes no starter tool grants and runs with financial
writes disabled. Grant read tools explicitly.
Balance and transaction results enter model context and may be retained in
chats, runs, transcripts, and tool events. Do not expose the local endpoint
publicly or expose the private broker route through untrusted ingress.
Only enabled, trusted servers with cached tested or platform-curated tool definitions and explicit allowed tools should reach agent sessions.
Voxos validates each model-produced MCP argument object against the server’s discovered JSON Schema before sending it. Invalid nested objects, missing required fields, and values that violate referenced definitions are recorded as tool failures and returned to the model for a bounded correction attempt; the invalid request is not sent to the MCP server. If a server still returns HTTP 400 or 422, Voxos reports an argument rejection rather than a connection failure and allows the same bounded tool loop to correct it. Validation errors name only schema paths and constraints, not rejected argument values.
Built-in and MCP tool failures are continuation results rather than fatal chat errors. The failed call remains visible in tool activity, and the model is told that it did not produce a usable result so it can still answer with any successful results and clearly state what was not completed or verified. A chat run fails only when the surrounding provider, persistence, or run-control path cannot continue safely.
Curated presets may tighten an incomplete provider schema or normalize a
provider-specific resource identifier when the upstream tools expose
incompatible contracts. Google Maps Grounding Lite weather is handled this way:
the runtime enforces exactly one camelCase location.address,
location.placeId, or location.latLng, requires complete structured dates,
rejects extra fields locally, and removes the places/ resource-name prefix
returned by Google name resolution before sending a Place ID to weather.
Weather guidance prefers calling lookup_weather directly with a specific
address, which avoids unnecessary name resolution.
Read-only MCP calls are executed concurrently in bounded waves of eight when a curated preset marks the tool read-only or the MCP tool publishes a read-only annotation. Unknown and potentially mutating MCP tools remain serial. A seven-day forecast therefore runs in one wave, while results are returned to the model in date/call order.
If local validation finds invalid arguments, later calls to the same tool in that model response are not sent. If an MCP server rejects a locally valid call with HTTP 400 or 422, calls already active in that bounded wave may also finish or fail, but later waves for the same tool are skipped. The model receives an output for every call ID and is asked to correct one request before batching more. An exact rejected request is also skipped if repeated in a later tool round. This bounds malformed provider traffic while retaining parallel valid lookups.
MCP connection setup, discovery, and tool requests use bounded read deadlines at both the HTTP/SSE transport and MCP session layers. SSE keepalive traffic does not make an unanswered tool request unbounded. Cancelling the owning text run also cancels every MCP coroutine in the active wave and closes their transport contexts.
See also:
Account History And Knowledge Writes
Section titled “Account History And Knowledge Writes”The internal search_agent_history and read_agent_history tools expose bounded
retained evidence to authenticated owner conversations. The separately revocable
record_agent_improvement tool submits memory, skill, or diagnostic candidates.
Per-agent grants and persisted run/session policy govern these tools; account
automatic-saving consent governs whether an eligible new learning becomes active.
Model-facing legacy memory and skill write tools submit candidates for the same policy. Confirmation tools cannot confer owner approval; owners use authenticated Knowledge review. Standalone Memory MCP writes create inferred proposals, and Skill MCP creation produces drafts; owner confirmation and active-skill revisions use Knowledge. Model-supplied provenance is discarded. See Agent Knowledge And Persistence.