# ConveRact open-agent interoperability — P0

The workspace administrator manages this capability at **AI & channels → Interoperability**.
Both the frontend and the separate `ChatBEV1` backend must be released together.

## Supported contract

| Capability       | P0 behavior                                                                                                                                                                         |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP client       | HTTPS Streamable HTTP, protocol `2025-11-25`; initialization, session headers, tool discovery and invocation; JSON or finite SSE responses.                                         |
| MCP server       | Stateless Streamable HTTP at `/api/v1/interop/mcp`; initialize, ping, tools/list and tools/call. One scoped `ask_agent` tool per credential.                                        |
| A2A              | Version `0.3.0`, JSON-RPC `message/send`, synchronous text input and Message output. This is an explicitly versioned implementation, not a claim of support for newer A2A versions. |
| External callers | Expiring, revocable, hashed bearer credentials scoped to one tenant and one published agent; OAuth credentials scoped to the MCP resource.                                          |
| Outbound agents  | `invokeOutbound(tenantId, agentId, targetId, input)` and the administrator invocation console enforce per-agent grants to an A2A peer or an individual MCP tool.                    |
| Registries       | Tenant-local external connections, discovered tools, local agents, publications, permissions and OAuth clients.                                                                     |
| AI surfaces      | OAuth authorization code + PKCE S256, explicit administrator consent, exact registered redirect URI and resource binding. Manual public-client registration.                        |

## Connect external tools or agents

1. Register an MCP or A2A HTTPS endpoint in Registry. Enter a bearer credential if required.
2. For MCP, discover tools and review the descriptions and input schemas. Tools start disabled. Enable only the tools you approve.
3. In Permissions, grant a local agent outbound access to a specific discovered tool or A2A peer, with an expiry no later than 90 days away.
4. In Activity, select that agent and target and run an explicit call. MCP takes a JSON object; A2A takes text. These are real remote executions and may incur charges or change external data.

Discovery never grants access. Rediscovering MCP tools disables them for review, including unchanged tools. Removed tools are removed from the registry and their grants are revoked. Input arguments are validated locally against the reviewed JSON Schema before execution.

A2A card discovery expects the authenticated card at `<registered-endpoint>/.well-known/agent-card.json` and requires its advertised URL to match the registered endpoint exactly. The peer must use the pinned protocol version. Registering a peer does not certify it as trusted.

Outbound network requests use ConveRact's existing safe HTTPS transport: public hosts only, DNS answers checked and pinned, TLS hostname verification, no redirects, no embedded credentials, bounded responses and deadlines. Tokens are encrypted at rest and are sent only to the configured peer. An external client's inbound token is never forwarded upstream.

## Publish a local agent

1. Activate and review the local agent and the workspace knowledge it can disclose.
2. In Publishing, select the agent, enter a description, acknowledge review, and publish the endpoint.
3. For a bearer-capable MCP/A2A client, create an inbound permission for that agent. Save the token shown once. Send it in the `Authorization: Bearer …` header on every request.
4. Use the exact MCP URL, A2A URL, and authenticated agent-card URL shown in Publishing.

An inbound credential cannot access another tenant or another publication. Disabling a publication, pausing the agent, revoking the grant, or allowing it to expire prevents new executions. Calls that have already reached the remote service may finish.

Example MCP request after initialization:

```json
{
  "jsonrpc": "2.0",
  "id": "request-1",
  "method": "tools/call",
  "params": {
    "name": "ask_agent",
    "arguments": { "message": "What services can you offer?" }
  }
}
```

Example A2A request:

```json
{
  "jsonrpc": "2.0",
  "id": "request-1",
  "method": "message/send",
  "params": {
    "message": {
      "kind": "message",
      "messageId": "message-1",
      "role": "user",
      "parts": [{ "kind": "text", "text": "What services can you offer?" }]
    }
  }
}
```

Published agents use the configured provider and existing guarded response-generation pipeline with the agent's current configuration and workspace product knowledge. They produce answers without executing customer transactions. An unconfigured AI provider returns an execution error; there are no fabricated success responses.

## Connect ChatGPT or another OAuth-capable MCP surface

1. Deploy the backend on public HTTPS. `API_PUBLIC_URL` must be its canonical origin. `FRONTEND_URL` must include the actual dashboard origin; its first origin receives consent redirects. Configure production persistence, encryption and the AI provider through existing backend configuration.
2. Publish the agent. In the AI surface's MCP connection settings, enter the displayed MCP URL and select OAuth with a predefined public client.
3. Copy the exact callback URI displayed by that surface. In ConveRact, register an OAuth client for the chosen agent and that callback. Enter the resulting client ID in the surface; this implementation uses PKCE and no client secret.
4. Start the connection. Sign into ConveRact as that workspace's administrator, review the named client, agent and callback, and explicitly authorize.
5. Test discovery and an invocation from the actual surface. This repository's automated tests do not establish live ChatGPT acceptance or account availability.

OAuth discovery:

- `/.well-known/oauth-protected-resource/api/v1/interop/mcp`
- `/.well-known/oauth-authorization-server`
- Authorization: `/api/v1/interop/oauth/authorize`
- Token exchange: `/api/v1/interop/oauth/token`
- Scope: `agent:invoke`
- Resource: the exact canonical MCP URL, required in both authorization and token exchange.

Codes expire after five minutes and can be exchanged only once with the correct PKCE verifier, client, redirect and resource. Opaque access tokens expire after one hour and require reauthorization. They cannot authenticate against the A2A resource. Disable the OAuth client or revoke its issued permission to block future access.

Public directory distribution is a separate platform submission and review process. The dashboard's readiness indicator means local endpoint configuration is present; it is not a deployment, compatibility certification, or directory approval.

See [OpenAI authentication requirements](https://developers.openai.com/plugins/build/auth) and [connection testing](https://developers.openai.com/plugins/deploy/connect-chatgpt).

## API and operational limits

Administrator routes are under `/api/v1/interop`, require a tenant-administrator session, and retain the existing CSRF and tenant service checks:

| Method | Relative route                                                       | Purpose                                                                                                         |
| ------ | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| GET    | `/`                                                                  | Tenant-scoped registry, permissions, publication endpoints and latest calls; no credential values or hashes.    |
| POST   | `/peers`                                                             | `{name, protocol: "MCP" or "A2A", url, secret?}`                                                                |
| POST   | `/peers/:id/discover`                                                | Discover MCP tools or fetch an A2A card.                                                                        |
| PATCH  | `/peers/:id`, `/tools/:id`, `/publications/:id`, `/oauthClients/:id` | `{enabled: boolean}`                                                                                            |
| POST   | `/grants`                                                            | `{name, agentId, targetId, direction: "INBOUND" or "OUTBOUND", expiresAt}`; inbound target must equal agent ID. |
| POST   | `/grants/:id/revoke`                                                 | Revoke permission.                                                                                              |
| POST   | `/publications`                                                      | `{agentId, description, reviewed: true}`                                                                        |
| POST   | `/invoke`                                                            | `{agentId, targetId, input}`; explicitly execute outbound work.                                                 |
| POST   | `/oauth/clients`                                                     | `{name, agentId, redirectUri}`                                                                                  |

- Limits: 100 peers, 200 tools in one discovery page per peer, 500 grants, 50 OAuth clients, four concurrent calls and 60 admitted calls/minute per tenant. Calls retain the latest 500 outcome records; the dashboard shows the latest 100.
- Remote responses are capped at 512 KB and each network request at 20 seconds. Tool schemas are JSON Schema 2020-12 object schemas up to 32 KB and 24 nesting levels. Remote schema references are not fetched. Message input is capped at 2,000 characters.
- MCP P0 excludes stdio, legacy SSE transport, long-running streams, server-initiated sampling/elicitation, remote OAuth negotiation, and paginated tool catalogs. Configure a scoped bearer credential for authenticated outbound peers.
- A2A P0 excludes task lifecycle, streaming, push notifications, attachments and context continuation. Cards advertise streaming and push notifications as unsupported. `message/send` does not automatically launch a multi-agent planner.
- There is no automatic retry of remote executions. If a network or persistence failure occurs after dispatch, the remote operation may have completed; reconcile its outcome before manually retrying a write tool.
- Invocation records store identifiers, direction, timestamps and outcomes, not prompt/response bodies. Tenant persistence is shared with the existing single-writer runtime; interrupted executions are marked interrupted after restart.
- OAuth P0 excludes refresh tokens, dynamic client registration, CIMD, OIDC and workspace email-domain restrictions. Use surfaces that accept the predefined public-client PKCE flow.

Protocol references: [MCP 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25/basic) and [A2A 0.3.0](https://a2a-protocol.org/v0.3.0/specification/).
