persona.mcps (sync) / await persona.mcps (async) wraps /api/v1/developer/mcps, plus the
.oauth sub-surface (/api/v1/developer/mcps/{id}/oauth/*).
MCP servers are Project-owned, or — when this client asserts an external user — owned by that
end user. A registered MCP server exposes tools and resources Agents can call.
Methods
Async: identical methods with
await.
create(input)
Required: name, transport, url. Optional (with defaults where noted): description,
authType (default 'none'), authMode (default 'owner'), oauth (required when
authType: 'oauth' and no dynamic registration), apiKey (required when authType: 'apiKey'),
useDynamicRegistration (default False), isEnabled (default True).
transport:"http" | "sse".authType:"none" | "oauth" | "apiKey".authMode:"owner" | "user"—ownershares one connection for the whole Project;usergives each external user their own. AnapiKey-authed server is always owner-shared, regardless ofauthMode.oauth: McpOAuthInput—{"clientId": str, "clientSecret": str, "scopes"?: list[str]}.useDynamicRegistration— RFC 7591 Dynamic Client Registration instead of a manualoauthblock.
Creating an
authType: "oauth" MCP synchronously probes the target URL’s OAuth
discovery endpoints — pointing it at a URL that doesn’t actually implement
OAuth discovery will fail the create() call itself, not just a later
connection test.Mcp in raw _id shape, with secrets stripped (see
Types — MCP types).
test_connection(mcp_id)
Connects to the MCP server right now, lists its tools/resources/resource templates, and persists
that summary onto the stored MCP document — so get()/list() reflect it afterward. Returns
McpTestConnectionResult: {"tools": list[McpTool], "resources": list[McpResourceSummary], "resourceTemplates": list[McpResourceTemplate]}. Until test_connection() has been called at
least once, tools/resources/resourceTemplates on the Mcp are empty.
call_tool(mcp_id, name, arguments=None)
Invokes one tool exposed by this MCP server. name comes from mcp["tools"]; arguments should
match that tool’s own input schema. The return shape is whatever the underlying MCP tool returns —
inherently dynamic (Any).
read_resource(mcp_id, uri)
Reads one MCP resource by URI (as opposed to calling a tool). uri comes from
mcp["resources"]/resourceTemplates (after filling any template params). Returns
McpReadResourceResult: {"text": str, "mimeType": str}.
get_usage(mcp_id) and delete(mcp_id)
delete() raises PersonaApiError if any Agent still references the MCP server — call
get_usage() first to check. bulk_delete(ids) is best-effort — partial failures (e.g. an MCP
still referenced by an Agent) don’t raise or abort the rest of the batch; check failed. Up to 100
ids per call.
OAuth connection flows (mcps.oauth)
For authType: "oauth" MCPs, mcps.oauth drives the owner- and user-mode authorization flows:
Owner-mode authorizes the MCP itself, shared by every user of your Project — call
get_owner_authorize_url() from a control-plane client and redirect your admin through it once.
User-mode authorizes one specific end user’s own token — call get_user_authorize_url() from a
runtime-plane client (external_user_id set) and redirect that user through it; return_to
is an optional client-chosen URL to send them back to once the flow completes.
The full redirect flow — for both modes — is in Workflows.
Types
See Types — MCP types for the full field reference:Mcp,
McpTransport, McpAuthType, McpAuthMode, McpTool, McpResourceSummary,
McpResourceTemplate, McpOAuthConfig, McpOAuthInput, PartialMcpOAuthInput, CreateMcpInput,
UpdateMcpInput, DiscoverMcpsParams, McpTestConnectionResult, McpReadResourceResult,
McpUserConnectionStatus, McpAuthorizeUrl.