Skip to Content
Task guidesTechnical: MCP & Workloads

MCP Server Exposure & Workloads

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

Orqestra can expose any flow as an MCP tool, making it callable by external AI agents. It also provides workload runtime interfaces for non-technical users to interact with governed flows directly.

Calling an external MCP server from a workload

External MCP calls use the fixed mcp_client acting identity or the server-owned mcp_client_advisory service identity. These are distinct identities, not a caller-facing authentication switch. Acting calls use the governed delegated path; advisory calls require the independently installed and release-bound connector plus its mcp_server target and auth_token secret slot. Package installation is scoped to a fresh workspace install and never silently binds a release or chooses a connection.

Task inputs contain the target and tool selection only. auth_token and arbitrary request headers are not accepted as callable MCP inputs; the runtime injects an approved connector secret only after the server-owned target, release, and connection pin agree. Readback exposes bounded credential-kind/correlation data and canonical decimal identifiers, never token material. external_as remains fail-closed pending the separately tracked enterprise integration.

MCP Server Exposure

The Model Context Protocol (MCP) allows AI agents to discover and invoke tools. Orqestra acts as an MCP server, exposing your governed flows as tools that external agents can call.

Install-vs-Binding For Package-Shipped MCP Servers

An mcp_server asset can be hand-authored directly (below), or it can ship as a package-local asset inside an official or community plugin package and installed through the package lifecycle (see Plugins & Connectors). Either way, installing an mcp_server asset does not make it usable by a release — an installed package asset is only Available (materialized, runtime-scoped), not Bound. Explicitly bind it to a release role before it is exposed:

orqestractl plugin bind <release_id> \ "pkg:<package_name>@<version>/mcp_server/<package_local_slug>@<asset_version>" \ mcp_server \ --workspace <workspace_id>

See Resolving And Binding Installed Assets for the package-ref grammar and the fail-closed resolve/bind behavior.

How It Works

  1. Register an mcp_server asset that defines which flows are exposed
  2. External agents discover available tools via the MCP protocol
  3. When an agent calls a tool, Orqestra executes the corresponding flow with full governance (policy evaluation, evidence capture, guardrails)
  4. The result is returned to the calling agent

MCP Server Configuration

Create an mcp_server asset to define the exposure:

{ "server_name": "orqestra-tools", "description": "Governed AI tools powered by Orqestra", "tools": [ { "name": "knowledge_search", "description": "Search the company knowledge base with governed RAG", "flow_slug": "knowledge-qa", "input_schema": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string", "description": "The search query" } } } }, { "name": "classify_ticket", "description": "Classify a support ticket by urgency", "flow_slug": "ticket-classifier", "input_schema": { "type": "object", "required": ["ticket_text"], "properties": { "ticket_text": { "type": "string" } } } } ] }

Key Benefits

BenefitDescription
Governed tool callsEvery invocation goes through Orqestra’s policy evaluation and evidence capture
Reuse existing flowsNo separate implementation needed — any flow becomes a tool
DiscoverabilityTools appear in MCP catalogs (Azure Foundry Tools, Vertex AI API Hub, etc.)
Audit trailFull execution trace for every external tool invocation

Pinning Tool Schemas And Reauthorizing Drift

A remote MCP server can change the tools it advertises, and their schemas, at any time — Orqestra does not control it. Pinning turns that from an invisible change into a governed one.

The operator loop

Operator surfaces live under Connect → External systems → MCP servers. Reading them needs asset.view; approving or revoking needs tool_permission.manage. Running discovery needs both tool_permission.manage and connection.read.

  1. Discover. Take a snapshot of what the server currently advertises. Snapshots are immutable and append-only, so the list is an audit trail rather than a current-state view.
  2. Review. Inspect each tool and its schema in the snapshot.
  3. Approve. Authorize either the complete_inventory or a selected_tools subset drawn from that snapshot, with a written reason. The confirmation restates target, version, snapshot, tool count and reason before anything is written.
  4. Watch. Live observations record what the runtime actually saw before each call, and whether it matched the pin.

What happens at call time

Before a workload calls a remote MCP tool, the runtime lists the server’s live inventory and compares it to the approved pin. The comparison result is committed as an observation before any tool call goes out. If the live inventory has drifted from what was approved, the call is denied with no outbound request.

Denials are recorded, not silent. The observation carries the closed reason, the expected and observed digests, and the credential-generation correlation — never provider content, arguments, headers or credentials.

Reauthorizing after drift

Reauthorization is deliberately not a button that re-blesses the current state. It is new discovery followed by a new approval: you take a fresh snapshot of what the server advertises now, read it, and approve that. The previous approval is retained as superseded rather than rewritten, so the history shows what was authorized when.

Rediscovering while an approval is already active is a reauthorization attempt, so the portal asks for confirmation before it runs — a single accidental click on Run discovery never disturbs a live approval basis by itself.

Revocation works the same way — the approval row is marked revoked, never deleted.

Reading observations from the CLI

# Snapshots and approval history for one MCP server asset version orqestractl mcp-tool-schema snapshots <asset-id> <asset-version-id> orqestractl mcp-tool-schema approvals <asset-id> <asset-version-id> # Live observations, optionally narrowed orqestractl mcp-tool-schema observations --state denied orqestractl mcp-tool-schema observations --execution-id <execution-id>

These commands are read-only by design. Approving an inventory is an operator decision that belongs with the confirmation step the portal shows; a scripted approve would skip it.

External-AS OAuth Registration (DCR)

Some remote MCP targets require Orqestra to authenticate as a registered OAuth client of the target’s own authorization server (AS), rather than presenting a static bearer token. For those targets, an operator opts a mcp_server asset into guarded RFC 7591 Dynamic Client Registration (DCR) and manages the resulting client credential’s lifecycle through the control plane.

Concepts

ConceptDescription
dcr_enabledExplicit operator opt-in on the mcp_server asset. Omitted or false means discovery performs no DCR registration.
transport_authMust be oauth for a target to be eligible for registration.
credential_sourceConsumption-side choice: broker (default) uses the existing delegated-identity broker path, unaffected by registration. external_as consumes THIS target’s own DCR-registered client_credentials access token instead, engaged only when an active, usable registration exists — otherwise the target is denied (no silent fallback to the broker).
RegistrationThe persisted outcome of a DCR call: a non-secret client_id plus a Vault credential_ref (the secret’s NAME, never its value).
Token acquisitionA separate, operator-gated action that exchanges the registered credential for a client_credentials access token (RFC 6749 §4.4). Scoped to client_credentials only; Orqestra does not expose an authorization-code/PKCE browser flow.

Lifecycle

# 1. Register — one-time RFC 7591 DCR call against the target's own AS. curl -X POST "http://localhost:8000/v1/mcp-oauth-registrations/?workspace_id=workspace-123" \ -H "Content-Type: application/json" \ -d '{ "mcp_server_asset_id": "asset-id", "redirect_uris": ["https://callback.orqestra.example/oauth/mcp"] }' # 2. Acquire a client_credentials access token for the registration. curl -X POST "http://localhost:8000/v1/mcp-oauth-registrations/{registration_id}/token?workspace_id=workspace-123" # 3. Refresh — re-acquires only if the current token is expired/near-expiry; # a no-op otherwise (client_credentials has no refresh_token, RFC 6749 §4.4). curl -X POST "http://localhost:8000/v1/mcp-oauth-registrations/{registration_id}/refresh?workspace_id=workspace-123" # 4. Rotate — re-runs DCR and supersedes the Vault-stored client secret, # keeping the same registration_id. curl -X POST "http://localhost:8000/v1/mcp-oauth-registrations/{registration_id}/rotate?workspace_id=workspace-123" \ -H "Content-Type: application/json" \ -d '{"redirect_uris": ["https://callback.orqestra.example/oauth/mcp"]}' # 5. Revoke — deletes the Vault-stored secret(s), marks the registration # revoked, and best-effort revokes the access token upstream (RFC 7009). # Local revocation always completes even if the upstream call fails. curl -X POST "http://localhost:8000/v1/mcp-oauth-registrations/{registration_id}/revoke?workspace_id=workspace-123"

The redirect URIs must resolve against the Orqestra OAuth-callback allowlist (ORQESTRA_OAUTH_CALLBACK_HOSTS), a boundary distinct from the remote-MCP egress allowlist. The raw client secret and access token are never returned in any response, logged, or written to audit — only the Vault credential_ref/token_credential_ref (secret names) and token_expires_at are exposed.

Permissions

OperationPermission
Read a registrationmcp_oauth_registration.read
Register, acquire/refresh token, rotate, revokemcp_oauth_registration.manage

Python SDK

from orqestra_sdk import OrqestraClient async with OrqestraClient("http://localhost:8000", workspace_id="workspace-123") as client: registration = await client.mcp_oauth_registrations.register( mcp_server_asset_id="asset-id", redirect_uris=["https://callback.orqestra.example/oauth/mcp"], workspace_id="workspace-123", ) await client.mcp_oauth_registrations.acquire_token( registration["registration_id"], workspace_id="workspace-123" ) await client.mcp_oauth_registrations.refresh_token( registration["registration_id"], workspace_id="workspace-123" ) await client.mcp_oauth_registrations.rotate( registration["registration_id"], redirect_uris=["https://callback.orqestra.example/oauth/mcp"], workspace_id="workspace-123", ) await client.mcp_oauth_registrations.revoke( registration["registration_id"], workspace_id="workspace-123" )

CLI

orqestractl mcp-oauth-registration register \ --mcp-server-asset-id asset-id \ --redirect-uri https://callback.orqestra.example/oauth/mcp \ --workspace-id workspace-123 orqestractl mcp-oauth-registration token <registration_id> --workspace-id workspace-123 orqestractl mcp-oauth-registration refresh <registration_id> --workspace-id workspace-123 orqestractl mcp-oauth-registration rotate <registration_id> \ --redirect-uri https://callback.orqestra.example/oauth/mcp \ --workspace-id workspace-123 orqestractl mcp-oauth-registration revoke <registration_id> --workspace-id workspace-123

Reading Permission Evidence

The read-only list_permission_evidence MCP tool returns one bounded, workspace-scoped page of redacted permission decisions. Call it with workspace_id; pass its opaque next_cursor as cursor to continue. Each page is limited to 100 records and requires policy.view in that workspace. The tool exposes recorded outcome and reason codes, policy/profile/evaluator revisions, freshness, lineage, and any result acknowledgement. Missing records or an absent acknowledgement remain unknown; neither means the operation was never attempted. The reader does not return source content, credentials, or source ACL grants.

Enterprise Outbound Authorization Conformance

For a target whose credential_source is external_as, Orqestra enforces a consolidated enterprise conformance contract: six additional posture fields, each explicit and independently checked by the runtime admission gate before discovery or a tool call reaches the target. Every field is required and denies admission (with its own stable reason code) when absent or unsupported — the pre-existing broker credential-source path is a separate governance axis and does not need (or accept) these fields.

FieldRequired valueWhat it declares
audience_resourceexact_endpointThe credential is bound to the exact resolved call/discovery endpoint, never a bare host.
issuer_validationdiscovery_verifiedThe target’s authorization-server issuer was resolved and https-validated via the OAuth discovery-metadata chain.
scope_capabilityregistration_scopedThe credential’s authority is bounded by that target’s own DCR client registration, never a broader static scope.
refresh_rotationregistration_managedThe registration’s :refresh/:rotate actions (above) manage the credential’s freshness.
revocationregistration_revocableThe registration’s status and :revoke action govern revocation.
credential_provenancevault_secret_referenceThe credential material is referenced by a governed Vault credential_ref (the secret’s NAME), never raw material in code/config.
{ "url": "https://mcp.partner.example.com", "transport_auth": "oauth", "capability_class": "read_only", "credential_source": "external_as", "audience_resource": "exact_endpoint", "issuer_validation": "discovery_verified", "scope_capability": "registration_scoped", "refresh_rotation": "registration_managed", "revocation": "registration_revocable", "credential_provenance": "vault_secret_reference" }

The bounded value sets are contract-owned (scripts/manifests/mcp-authorization-conformance.toml, mirrored in mcp_authorization_conformance_value_sets.schema.json), versioned, and lockstep-gated: a target declaring a value the contract does not enumerate fails closed, never assumed compatible. Denial evidence (v1.governance.mcp_target_admission_decided) records the credential category (broker/external_as) and the closed gap-reason codes, never credential material or a token.

Workload Runtime Interfaces

For non-technical users who need to interact with AI capabilities without understanding flows, Orqestra provides a workload runtime surface.

Workload Interface Configuration

Workloads with the interface_config field define a UI presentation layer:

{ "interface_config": { "title": "Knowledge Assistant", "description": "Ask questions about company policies and procedures", "interface": "chat", "branding": { "icon": "brain", "color": "#2ea97a" }, "input_fields": [ { "name": "query", "type": "text", "label": "Ask a question", "placeholder": "What is our refund policy?" } ] } }

Apps

The portal provides an Apps page where users browse and launch available workload interfaces:

# List available runtime workloads with their configurations curl GET /v1/workloads/runtime-enabled

Response includes each workload’s display name, description, interface type, and status, enabling a self-service experience for consumers.

Interface Types

InterfaceDescription
chatConversational interface with message history
apiProgrammatic interface for system-to-system calls
formStructured input form with defined fields

API Reference

MCP Server Assets

# Create an MCP server asset curl -X POST /v1/assets \ -d '{ "slug": "company-tools", "asset_kind": "mcp_server", "owner_ref": "team:platform" }' # Create a version with tool definitions curl -X POST /v1/assets/{asset_id}/versions \ -d '{ "version_label": "v1", "content": { "server_name": "company-tools", "tools": [...] } }'
# List workloads with runtime interface configs curl GET /v1/workloads/runtime-enabled

Best Practices

Write clear tool descriptions. External agents use the description field to decide when to call your tool. Be specific about what the tool does and what inputs it expects.

Define strict input schemas. Input validation prevents malformed requests from reaching your flows. Use JSON Schema constraints to enforce required fields and types.

Apply guardrails to MCP-exposed flows. External agents may send unexpected content. Ensure flows exposed via MCP have guardrails configured for input validation and content safety.

Monitor MCP tool usage. Track invocation patterns via the observability dashboard to understand how external agents use your tools and identify optimization opportunities.