MCP (Model Context Protocol)¶
MCP integration for AI-Parrot.
MCPEnabledMixin ¶
Mixin to add complete MCP capabilities to agents.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_mcp_server
async
¶
add_local_mcp_server
async
¶
add_local_mcp_server(name: str, script_path: Union[str, Path], interpreter: str = 'python', **kwargs) -> List[str]
Add a local stdio MCP server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_http_mcp_server
async
¶
add_http_mcp_server(name: str, url: str, auth_type: Optional[str] = None, auth_config: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None, **kwargs) -> List[str]
Add an HTTP MCP server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_api_key_mcp_server
async
¶
add_api_key_mcp_server(name: str, url: str, api_key: str, header_name: str = 'X-API-Key', **kwargs) -> List[str]
Add an MCP server with API key auth.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_oauth_mcp_server
async
¶
add_oauth_mcp_server(name: str, url: str, user_id: str, oauth2: Optional[MCPOAuth2Config] = None, client_id: Optional[str] = None, auth_url: Optional[str] = None, token_url: Optional[str] = None, scopes: Optional[List[str]] = None, client_secret: Optional[str] = None, **kwargs) -> List[str]
Add an MCP server with OAuth2 authorization code support.
Accepts either a ready-built :class:~parrot.mcp.oauth2_config.MCPOAuth2Config
(via the oauth2 parameter) or individual parameters for backward
compatibility.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Server name / registry key.
TYPE:
|
url
|
MCP server base URL.
TYPE:
|
user_id
|
User identifier for token storage scoping.
TYPE:
|
oauth2
|
Pre-built OAuth2 configuration.
TYPE:
|
client_id
|
OAuth2 client ID (legacy).
TYPE:
|
auth_url
|
Authorization endpoint (legacy).
TYPE:
|
token_url
|
Token endpoint (legacy).
TYPE:
|
scopes
|
OAuth2 scopes (legacy).
TYPE:
|
client_secret
|
OAuth2 client secret (legacy).
TYPE:
|
**kwargs
|
Extra :class:
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered MCP tool names. |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_perplexity_mcp_server
async
¶
Add a Perplexity MCP server capability.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_fireflies_mcp_server
async
¶
Add Fireflies.ai MCP server capability.
The API key is resolved with the following precedence
- Explicit
api_keyargument. FIREFLIES_API_KEYenvironment variable (vianavconfig.config).ValueErrorif neither is available.
| PARAMETER | DESCRIPTION |
|---|---|
api_key
|
Fireflies API key (optional; falls back to FIREFLIES_API_KEY env var)
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Example
tools = await agent.add_fireflies_mcp_server( ... api_key="your-fireflies-api-key" ... )
Or rely on FIREFLIES_API_KEY env var:¶
tools = await agent.add_fireflies_mcp_server()
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_chrome_devtools_mcp_server
async
¶
add_chrome_devtools_mcp_server(browser_url: str = 'http://127.0.0.1:9222', name: str = 'chrome-devtools', **kwargs) -> List[str]
Add Chrome DevTools MCP server capability.
| PARAMETER | DESCRIPTION |
|---|---|
browser_url
|
URL where Chrome is listening for devtools protocol
TYPE:
|
name
|
Server name
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_google_maps_mcp_server
async
¶
Add Google Maps MCP server capability.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Server name
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_quic_mcp_server
async
¶
add_quic_mcp_server(name: str, host: str, port: int, cert_path: Optional[str] = None, **kwargs) -> List[str]
Add a QUIC/HTTP3 MCP server connection.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_websocket_mcp_server
async
¶
add_websocket_mcp_server(name: str, url: str, auth_type: Optional[str] = None, auth_config: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None, **kwargs) -> List[str]
Add a WebSocket MCP server connection.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Server name
TYPE:
|
url
|
WebSocket URL (ws:// or wss://)
TYPE:
|
auth_type
|
Authentication type ("bearer", "api_key", "oauth")
TYPE:
|
auth_config
|
Authentication configuration
TYPE:
|
headers
|
Additional headers for WebSocket upgrade
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Example
await agent.add_websocket_mcp_server( ... "my-ws-server", ... "ws://localhost:8766/mcp/ws", ... auth_type="bearer", ... auth_config={"token": "my-token"} ... )
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
reconfigure_mcp_server
async
¶
Reconfigure an existing MCP server with new configuration.
| PARAMETER | DESCRIPTION |
|---|---|
config
|
New MCPServerConfig with updated parameters
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
reconfigure_fireflies_mcp_server
async
¶
Reconfigure Fireflies MCP server with a new API key.
This is useful in multi-user scenarios where each user provides their own Fireflies API key. The method will disconnect the existing connection and reconnect with the new credentials.
| PARAMETER | DESCRIPTION |
|---|---|
api_key
|
New Fireflies API key
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Example
Initial setup with user 1's API key¶
await agent.add_fireflies_mcp_server(api_key="user1-api-key")
Later, reconfigure with user 2's API key¶
await agent.reconfigure_fireflies_mcp_server(api_key="user2-api-key")
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
reconfigure_perplexity_mcp_server
async
¶
Reconfigure Perplexity MCP server with a new API key.
Useful for updating the API key without restarting the agent.
| PARAMETER | DESCRIPTION |
|---|---|
api_key
|
New Perplexity API key
TYPE:
|
name
|
Server name (default: "perplexity")
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
get_openai_mcp_tools ¶
Get OpenAI-compatible MCP definitions for registered servers.
| PARAMETER | DESCRIPTION |
|---|---|
server_names
|
Optional list of server names to filter by
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[Dict[str, Any]]
|
List of tool definitions in valid OpenAI MCP format |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_alphavantage_mcp_server
async
¶
add_alphavantage_mcp_server(api_key: Optional[str] = None, name: str = 'alphavantage', **kwargs) -> List[str]
Add AlphaVantage MCP server capability.
| PARAMETER | DESCRIPTION |
|---|---|
api_key
|
AlphaVantage API key
TYPE:
|
name
|
Server name (default: "alphavantage")
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_netsuite_mcp_server
async
¶
Add NetSuite MCP server capability via OAuth2 Authorization Code + PKCE.
Constructs the NetSuite MCP configuration from the given credentials and
registers it with this agent. Scope is fixed to ["mcp"].
| PARAMETER | DESCRIPTION |
|---|---|
account_id
|
NetSuite account ID (e.g.
TYPE:
|
client_id
|
OAuth2 client ID from the NetSuite integration record.
TYPE:
|
user_id
|
Caller's user identifier for token storage scoping.
TYPE:
|
**kwargs
|
Additional keyword arguments forwarded to
:func:
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names from the NetSuite MCP server. |
Example
tools = await agent.add_netsuite_mcp_server( ... account_id="4984231", ... client_id="my-client-id", ... user_id="user@co.com", ... )
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_netsuite_m2m_mcp_server
async
¶
add_netsuite_m2m_mcp_server(account_id: str, client_id: str, certificate_id: str, private_key_path: str, **kwargs) -> List[str]
Add NetSuite MCP server via OAuth2 Client Credentials (M2M) with certificate.
No browser login is needed — the agent authenticates using a JWT signed with the provided private key.
| PARAMETER | DESCRIPTION |
|---|---|
account_id
|
NetSuite account ID (e.g.
TYPE:
|
client_id
|
OAuth2 client ID from the NetSuite integration record.
TYPE:
|
certificate_id
|
Mapping Key from the uploaded certificate in NetSuite.
TYPE:
|
private_key_path
|
Path to a PEM-encoded RSA private key file.
TYPE:
|
**kwargs
|
Forwarded to :func:
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of registered tool names. |
Example
tools = await agent.add_netsuite_m2m_mcp_server( ... account_id="4984231", ... client_id="abc...", ... certificate_id="XYZ123", ... private_key_path="/path/to/private.pem", ... )
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
add_genmedia_mcp_servers
async
¶
Add all Google GenMedia MCP servers.
Available servers: - mcp-avtool-go - mcp-chirp3-go - mcp-gemini-go - mcp-imagen-go - mcp-lyria-go - mcp-veo-go
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
setup_mcp_servers
async
¶
Setup multiple MCP servers during initialization.
This is useful for configuring an agent with multiple MCP servers at once, typically during agent creation or from configuration files.
| PARAMETER | DESCRIPTION |
|---|---|
configurations
|
List of MCPServerConfig objects
TYPE:
|
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
MCPServerConfig
dataclass
¶
MCPServerConfig(name: str, url: Optional[str] = None, command: Optional[str] = None, args: Optional[List[str]] = None, env: Optional[Dict[str, str]] = None, description: Optional[str] = None, auth_credential: Optional[AuthCredential] = None, auth_type: Optional[AuthScheme] = None, auth_config: Dict[str, Any] = dict(), token_supplier: Optional[Callable[[], Optional[str]]] = None, transport: str = 'auto', base_path: Optional[str] = None, events_path: Optional[str] = None, socket_path: Optional[str] = None, headers: Dict[str, str] = dict(), header_provider: Optional[Callable[[ReadonlyContext], Dict[str, str]]] = None, tool_filter: Optional[Union[List[str], Callable[[ToolPredicate], bool]]] = None, allowed_tools: Optional[List[str]] = None, blocked_tools: Optional[List[str]] = None, require_confirmation: Union[bool, Callable[[str, Dict[str, Any]], bool]] = False, tool_name_prefix: Optional[str] = None, timeout: float = 30.0, retry_count: int = 3, startup_delay: float = 0.5, rate_limit_max_retries: int = 2, rate_limit_max_wait: float = 60.0, rate_limit_base_delay: float = 1.0, kill_timeout: float = 5.0, quic_config: Any = None, oauth2: Optional[MCPOAuth2Config] = None, auth_preset: Optional[str] = None, user_id: Optional[str] = None, inject_broker_credential: bool = False)
Complete configuration for external MCP server connection.
Supports both static configuration and dynamic behavior through header_provider and token_supplier callbacks.
Example
Static config¶
config = MCPClientConfig( ... name="my-server", ... url="http://localhost:8080/mcp", ... transport="http", ... headers={"X-API-Key": "secret"} ... )
Dynamic headers based on context¶
def my_header_provider(ctx): ... return {"X-User-ID": ctx.user_id} if ctx else {} config = MCPClientConfig( ... name="my-server", ... url="http://localhost:8080/mcp", ... header_provider=my_header_provider ... )
get_headers
async
¶
Get merged static, auth, and dynamic headers.
Order of precedence (later overrides earlier): 1. Static headers from self.headers 2. Auth headers from auth_credential.get_auth_headers() 3. Dynamic headers from header_provider(context)
| PARAMETER | DESCRIPTION |
|---|---|
context
|
Optional ReadonlyContext for dynamic header generation
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Dict[str, str]
|
Merged dictionary of all headers |
Example
headers = await config.get_headers(ctx)
Returns:¶
Source code in packages/ai-parrot/src/parrot/mcp/client.py
validate_transport ¶
Validate transport-specific configuration.
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If configuration is invalid for the specified transport |
Source code in packages/ai-parrot/src/parrot/mcp/client.py
from_yaml_config
classmethod
¶
Load from YAML configuration with validation.
| PARAMETER | DESCRIPTION |
|---|---|
config_dict
|
Dictionary loaded from YAML file
TYPE:
|
config_abs_path
|
Absolute path to YAML file (for error messages)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
MCPClientConfig
|
MCPClientConfig instance |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If configuration is invalid |
Example
import yaml with open("mcp_servers.yaml") as f: ... config = yaml.safe_load(f) mcp_config = MCPClientConfig.from_yaml_config( ... config['servers']['my-server'], ... "/path/to/mcp_servers.yaml" ... )
Source code in packages/ai-parrot/src/parrot/mcp/client.py
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | |
MCPClient ¶
Complete MCP client with stdio and HTTP transport support.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
connect
async
¶
Connect to MCP server using appropriate transport.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
call_tool
async
¶
Call an MCP tool.
Rate-limit responses (-32429) are retried with the server-suggested
retryAfter delay (or an exponential fallback), up to
rate_limit_max_retries. A suggested wait longer than
rate_limit_max_wait fails fast instead of blocking the agent loop —
the error is surfaced so the caller can move on rather than hammering a
throttled server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
get_available_tools
async
¶
Get raw available tools from server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
get_tools_for_context ¶
Get tools, filtered by context.
If a context is provided, tools will be filtered based on the context's scopes and roles. Tools may specify required scopes in their metadata.
| PARAMETER | DESCRIPTION |
|---|---|
context
|
Optional ReadonlyContext for filtering
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[Dict[str, Any]]
|
List of tool dictionaries accessible to the context |
Example
from parrot.mcp.context import ReadonlyContext ctx = ReadonlyContext( ... agent_id="my-agent", ... scopes=["read:data", "write:data"] ... ) tools = client.get_tools_for_context(ctx)
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
get_tools
async
¶
Get tools filtered by configuration and context.
Filtering precedence: 1. tool_filter (new dynamic filtering) - highest priority 2. allowed_tools / blocked_tools (legacy) - fallback 3. No filter - all tools
| PARAMETER | DESCRIPTION |
|---|---|
context
|
Optional ReadonlyContext for context-aware decisions
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[MCPToolProxy]
|
List of MCPToolProxy objects that are available |
Example
Get all tools¶
tools = await client.get_tools()
Get tools filtered by context¶
ctx = ReadonlyContext(user_id="user123", roles=["admin"]) admin_tools = await client.get_tools(context=ctx)
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
disconnect
async
¶
Disconnect from MCP server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
NetSuiteM2MAuth ¶
NetSuiteM2MAuth(*, client_id: str, certificate_id: str, private_key_path: str, account_id: str, token_url: str | None = None, scopes: list[str] | None = None, token_store: TokenStore | None = None)
OAuth2 Client Credentials (M2M) for NetSuite using certificate-based JWT assertion.
NetSuite M2M requires a signed JWT as the client_assertion when
requesting an access token. The JWT is signed with the private key whose
matching X.509 certificate was uploaded to the NetSuite Integration Record.
| PARAMETER | DESCRIPTION |
|---|---|
client_id
|
OAuth2 client ID from the NetSuite integration record.
TYPE:
|
certificate_id
|
Certificate ID shown in NetSuite after uploading the public certificate.
TYPE:
|
private_key_path
|
Path to the PEM-encoded RSA private key file.
TYPE:
|
account_id
|
NetSuite account ID (e.g.
TYPE:
|
token_url
|
NetSuite token endpoint. Built automatically when
TYPE:
|
scopes
|
OAuth2 scopes (default
TYPE:
|
token_store
|
Optional :class:
TYPE:
|
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
ensure_token
async
¶
Obtain or refresh an access token via Client Credentials grant.
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
token_supplier ¶
Synchronous hook called by the HTTP transport before each request.
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
TokenStore ¶
Abstract token store interface.
InMemoryTokenStore ¶
RedisTokenStore ¶
Bases: TokenStore
Redis-based token store.
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
VaultTokenStore ¶
Bases: TokenStore
Vault-backed token store that encrypts OAuth tokens using AES-GCM.
Persists tokens in the DocumentDB Vault (via vault_utils) so they survive agent restarts. Falls back gracefully when the credential is not found or vault keys are unavailable.
The credential name follows the pattern mcp_oauth_{server_name}_{user_id}.
Example
store = VaultTokenStore() await store.set("user@co.com", "netsuite", token_dict) token = await store.get("user@co.com", "netsuite")
get
async
¶
Retrieve a stored OAuth token from the Vault.
| PARAMETER | DESCRIPTION |
|---|---|
user_id
|
Owner's user identifier.
TYPE:
|
server_name
|
MCP server slug.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[Dict[str, Any]]
|
Decrypted token dict, or |
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
set
async
¶
Encrypt and persist an OAuth token in the Vault.
Degrades gracefully when vault keys are unavailable: logs a warning and returns without raising so the in-memory token remains usable.
| PARAMETER | DESCRIPTION |
|---|---|
user_id
|
Owner's user identifier.
TYPE:
|
server_name
|
MCP server slug.
TYPE:
|
token
|
Token dict to store (e.g. access_token, refresh_token, expires_at).
TYPE:
|
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
delete
async
¶
Remove a stored OAuth token from the Vault.
Tolerates a missing credential (already deleted) and vault unavailability — both are logged at warning level without raising.
| PARAMETER | DESCRIPTION |
|---|---|
user_id
|
Owner's user identifier.
TYPE:
|
server_name
|
MCP server slug.
TYPE:
|
Source code in packages/ai-parrot/src/parrot/mcp/oauth.py
AuthScheme ¶
Bases: str, Enum
Type-safe authentication schemes.
AuthCredential ¶
Bases: BaseModel
Type-safe credential container with validation.
Validates that required fields are present based on the chosen scheme.
Example
Bearer token¶
cred = AuthCredential(scheme=AuthScheme.BEARER, token="my-token")
API Key with custom header¶
cred = AuthCredential( ... scheme=AuthScheme.API_KEY, ... api_key="secret", ... api_key_header="X-Custom-Key" ... )
Get headers¶
headers = cred.get_auth_headers()
validate_scheme_requirements ¶
Validate that required fields are set for chosen scheme.
Source code in packages/ai-parrot/src/parrot/mcp/client.py
get_auth_headers ¶
Generate appropriate auth headers based on scheme.
| RETURNS | DESCRIPTION |
|---|---|
Dict[str, str]
|
Dictionary of authentication headers |
Note
AWS Sig V4 and mTLS require special handling at the transport level and are not returned as simple headers.
Source code in packages/ai-parrot/src/parrot/mcp/client.py
ReadonlyContext ¶
Bases: BaseModel
Immutable context passed to tool operations.
This context provides information about the agent, user, and organizational context for tool execution. It enables: - Tool filtering based on user roles/scopes - Dynamic header generation - Multi-tenant isolation - Rate limiting by user/organization
Example
ctx = ReadonlyContext( ... agent_id="hr-agent", ... user_id="user-123", ... organization_id="acme-corp", ... roles=["admin", "hr"], ... scopes=["read:employees", "write:employees"] ... )
Context is immutable¶
ctx.user_id = "other" # Raises ValidationError
MCPSessionManager ¶
Manages session lifecycle and retry logic for MCP connections.
Features: - Session caching keyed by headers (for multi-user scenarios) - Automatic retry with exponential backoff on transient failures - Configurable max retries
Example
manager = MCPSessionManager(config, max_retries=3) session = await manager.create_session(headers={"X-User-ID": "123"})
Session is cached - same headers return same session¶
same_session = await manager.create_session(headers={"X-User-ID": "123"})
Source code in packages/ai-parrot/src/parrot/mcp/context.py
create_session
async
¶
Create or retrieve cached session with retry.
| PARAMETER | DESCRIPTION |
|---|---|
headers
|
Optional headers that affect session identity
TYPE:
|
force_new
|
If True, create new session even if cached
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Any
|
MCP session object |
Source code in packages/ai-parrot/src/parrot/mcp/context.py
invalidate_session
async
¶
Invalidate a cached session.
Source code in packages/ai-parrot/src/parrot/mcp/context.py
invalidate_all
async
¶
TransientMCPError ¶
Bases: Exception
Transient MCP errors that should be retried.
Use this for errors like connection timeouts, temporary server unavailability, rate limiting, etc. The retry_on_errors decorator will automatically retry operations that raise this exception.
MCPServerRegistry ¶
Catalog of pre-built MCP server helpers available for user activation.
Wraps the module-level _REGISTRY list with lookup and validation
methods. The registry is declarative — all entries are hand-authored
above, not generated by reflection.
Example::
registry = MCPServerRegistry()
desc = registry.get_server("perplexity")
params = registry.validate_params("perplexity", {"api_key": "sk-..."})
list_servers ¶
Return all registered MCP server descriptors.
| RETURNS | DESCRIPTION |
|---|---|
List[MCPServerDescriptor]
|
List of :class: |
get_server ¶
Look up a single server descriptor by its registry slug.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Registry slug (e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[MCPServerDescriptor]
|
The matching :class: |
Source code in packages/ai-parrot/src/parrot/mcp/registry.py
validate_params ¶
Validate user-supplied parameters against the descriptor schema.
Checks that all required parameters are present. Fills in default
values for optional parameters that are absent from params.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Registry slug of the server to validate against.
TYPE:
|
params
|
User-supplied parameter mapping.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Dict[str, Any]
|
Cleaned parameter dict with defaults applied. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the server slug is not found, or if any required
parameter is missing from |
Source code in packages/ai-parrot/src/parrot/mcp/registry.py
MCPServerDescriptor ¶
Bases: BaseModel
Catalog entry describing a single pre-built MCP server helper.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Registry slug used as the identifier in API requests
(e.g.
TYPE:
|
display_name |
Human-friendly label for UI display.
TYPE:
|
description |
What the MCP server does.
TYPE:
|
method_name |
Name of the
TYPE:
|
params |
Ordered list of accepted parameters.
TYPE:
|
category |
Grouping label for the catalog
(e.g.
TYPE:
|
activatable |
Whether the server can be activated via the POST endpoint.
Servers without a
TYPE:
|
MCPServerParam ¶
Bases: BaseModel
Describes a single parameter accepted by an MCP server helper.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Parameter name (matches the Python keyword argument).
TYPE:
|
type |
Expected value type; use
TYPE:
|
required |
Whether the caller must supply a value.
TYPE:
|
default |
Default value used when
TYPE:
|
description |
Human-readable explanation shown in the catalog.
TYPE:
|
MCPParamType ¶
Bases: str, Enum
Type hint for an MCP server parameter.
The SECRET variant signals that the frontend should mask the input
field and that the value must be stored in the Vault rather than
persisted in DocumentDB plaintext.
UserMCPServerConfig ¶
Bases: BaseModel
Persisted configuration for a user-activated MCP server.
This document is stored in the user_mcp_configs DocumentDB collection.
Secret parameters (API keys, tokens) are never stored here — they live
in the Vault; vault_credential_name points to the Vault entry.
| ATTRIBUTE | DESCRIPTION |
|---|---|
server_name |
Registry slug of the activated server.
TYPE:
|
agent_id |
Agent the server is scoped to.
TYPE:
|
user_id |
Owner of this configuration.
TYPE:
|
params |
Non-secret configuration parameters.
TYPE:
|
vault_credential_name |
Name of the Vault credential that holds
any secret values (
TYPE:
|
active |
Soft-delete flag;
TYPE:
|
created_at |
ISO-8601 timestamp of initial creation.
TYPE:
|
updated_at |
ISO-8601 timestamp of last update.
TYPE:
|
ActivateMCPServerRequest ¶
Bases: BaseModel
Request body for the POST (activate) endpoint.
| ATTRIBUTE | DESCRIPTION |
|---|---|
server |
Registry slug of the server to activate
(e.g.
TYPE:
|
params |
All parameters, including secrets. The handler separates secret params before storing them in the Vault.
TYPE:
|
create_local_mcp_server ¶
create_local_mcp_server(name: str, script_path: Union[str, Path], interpreter: str = 'python', **kwargs) -> MCPServerConfig
Create configuration for local stdio MCP server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
create_http_mcp_server ¶
create_http_mcp_server(name: str, url: str, auth_type: Optional[str] = None, auth_config: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None, **kwargs) -> MCPServerConfig
Create configuration for HTTP MCP server.
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
create_api_key_mcp_server ¶
create_api_key_mcp_server(name: str, url: str, api_key: str, header_name: str = 'X-API-Key', use_bearer_prefix: bool = False, **kwargs) -> MCPServerConfig
Create configuration for API key authenticated MCP server.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Unique name for the MCP server
TYPE:
|
url
|
Base URL of the MCP server
TYPE:
|
api_key
|
API key for authentication
TYPE:
|
header_name
|
Header name for the API key (default: "X-API-Key")
TYPE:
|
use_bearer_prefix
|
If True, prepend "Bearer " to the API key value (default: False)
TYPE:
|
**kwargs
|
Additional MCPServerConfig parameters
DEFAULT:
|
| RETURNS | DESCRIPTION |
|---|---|
MCPClientConfig
|
MCPServerConfig instance |
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
create_netsuite_m2m_mcp_server ¶
create_netsuite_m2m_mcp_server(*, account_id: str, client_id: str, certificate_id: str, private_key_path: str, name: str = 'netsuite', token_store: Optional[TokenStore] = None, headers: Optional[Dict[str, Any]] = None) -> MCPServerConfig
Create a NetSuite MCP server using OAuth2 Client Credentials (M2M) with certificate.
This is the machine-to-machine variant — no browser login required.
Authentication uses a JWT client_assertion signed with the private key
whose matching X.509 certificate was uploaded to the NetSuite Integration Record.
| PARAMETER | DESCRIPTION |
|---|---|
account_id
|
NetSuite account ID (e.g.
TYPE:
|
client_id
|
OAuth2 client ID from the NetSuite integration record.
TYPE:
|
certificate_id
|
Certificate ID shown in NetSuite after uploading the public certificate (Mapping Key field).
TYPE:
|
private_key_path
|
Path to a PEM-encoded RSA private key file.
TYPE:
|
name
|
Server name (default
TYPE:
|
token_store
|
Optional :class:
TYPE:
|
headers
|
Extra HTTP headers.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
MCPClientConfig
|
class: |
Example
cfg = create_netsuite_m2m_mcp_server( ... account_id="4984231", ... client_id="abc...", ... certificate_id="XYZ123", ... private_key_path="/path/to/private.pem", ... )
Source code in packages/ai-parrot/src/parrot/mcp/integration.py
retry_on_errors ¶
Decorator for automatic retry on transient errors with exponential backoff.
| PARAMETER | DESCRIPTION |
|---|---|
max_retries
|
Maximum number of retry attempts (default: 3)
TYPE:
|
base_wait
|
Base wait time in seconds for exponential backoff (default: 2.0)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Callable[[F], F]
|
Decorated async function with retry logic |
Example
@retry_on_errors(max_retries=3) ... async def get_tools(self): ... # This will auto-retry on TransientMCPError ... return await self._session.list_tools()
Source code in packages/ai-parrot/src/parrot/mcp/context.py
get_factory_map ¶
Return the dispatch map from registry slug to create_* factory function.
Deferred import to avoid circular dependencies (the factory functions live
in parrot.mcp.integration which may import from this module).