RPC (Remote Procedure Call)
In the official SDK, recent new features are supported through auto-generated code fromapi.schema.json.
In the Laravel version, the same features are implemented by following generated SDKs for other languages.
ServerRpc
An RPC class bound to the Client.Connection, models, tools, and accounts
Useping() and connect() to check and start the connection, and registerExtensionLaunchProvider() to register an extension launch provider. You can get the model list, token price units, and built-in catalog from models(), and the list of available tools from tools(). account() handles quota, authentication status, the list of logged-in users, login, and logout, while accounts() acquires Microsoft Entra ID tokens.
MCP, connectors, and secrets
mcp() lets you list, add, update, and remove MCP configurations, enable them, discover servers, search the registry, and plan and apply installations. connectors() lets you check connector capabilities, accounts, and the catalog. Server-side connector operations mainly consist of listing and updating per account. The experimental secrets()->addFilterValues() registers dynamic secrets generated by your host with the CLI’s redaction filter. The CLI then masks those values in session logs and exports.
Skills, plugins, agents, instructions, and extensions
Each group lets you discover items, get available paths, change settings, and reload.commands() provides the list of built-in commands, and hooks() provides hook discovery before a session starts. Skills and plugins support enabling, disabling, and installation management, and agents can also return built-in agent information. Extensions discovers, enables, and disables persisted extensions.
Catalog and installation
Usecatalog() to search for candidates, get official product recommendations, make selections, and get feeds. The Skills, Plugins, and MCP APIs let you review installation plans, apply them, query their status, and cancel them. Planning and applying are separate operations. See the later sections for actual installation examples.
Sessions, host, and runtime
sessions() handles searching persisted sessions, reading events, checking sizes, deleting and pruning, and forking. You can also create and load workspaces and use remote control. host() starts the host, publishes, lists, and unpublishes sessions, handles authentication, changes the session admission policy, and disposes of the host. These host RPCs back the SDK’s high-level AHP (Agent Host Protocol) host API. runtime() handles the runtime lifecycle.
Cloud agent tasks (experimental)
cloudTasks() creates, deletes, and gets cloud coding agent tasks, retrieves session logs and replays, changes sharing state, and resolves the session to open from a task ID. Each method accepts the matching Params type or an array and returns a typed DTO. When ok on a create result is false, check reason and message for why the service declined the request, and statusCode, errorMessage, and errorPayloadJson for a failed HTTP request.
Git, environments, sandbox, and policies
Get branch, working directory, and Git remote information fromgit(), and discover GitHub repositories and owners with gitHubRepository() and gitHubOwners(). environments() handles Mission Control environments, sandbox() and sandboxProxyCa() handle sandbox support and the Proxy CA, contentExclusion() validates exclusion policies, and managedSettings() and userSettings() handle settings. Use settings() to remove individual keys from a settings file and to redact values for display.
gitHubRepository()->getById() resolves an owner and name from a GitHub repository ID, and lookupBranchPullRequest() searches the given repositories, in priority order, for a pull request from the given head owner and branch. Both take authInfo as is. The getById() result contains the owner and name in repository, or null when the repository isn’t found. The pull request lookup status is one of found, no-token, no-pr, or lookup-failed. Unknown values are kept as strings, so they don’t throw. pullRequest is an associative array when a pull request is found, otherwise null.
gitHubFetch() provides authenticated GitHub API requests and named operations. gitHubRelease() provides release lookup, snapshots, asset downloads, and progress checks. In Fetch, sessionId selects a session’s authentication; when omitted, the process authentication is used. Set authOwnerId to use a host-managed authentication binding. In Release, authInfo selects runtime-managed credentials, and public releases can be looked up and downloaded anonymously. Delete the downloaded path yourself after use.
Fetch’s allocateRequestId(), request(), and executeOperation(), and Release’s abandonRequest(), getSnapshot(), and downloadAsset() can’t be called from Extensions. The Laravel SDK doesn’t currently expose the cancel RPC of either group, so you can’t cancel an in-flight operation from the SDK. abandonRequest() discards an unused Release request ID; it doesn’t stop an in-flight operation.
Local models, HTTP inference, and file system
azureMl() provides the local model catalog, resolution, and download, as well as status checks, cancellation, and deletion. llmInference() is an experimental API that relays model-layer HTTP requests to the client side. sessionFs() registers a file system/SQLite callback provider for sessions.
Network callbacks (experimental)
network()->setProvider() tells the runtime about the proxy resolution and Kerberos authentication callbacks registered on the client. The network option on the Client registers them automatically, so you normally do not need to call this RPC directly. The callback fields of NetworkSetProviderRequest indicate that the matching handler is registered. The RPC returns no value. The runtime must support the network.setProvider RPC. If it does not, the client throws an exception at startup that asks you to update the runtime. See Authentication for details.
scope defaults to connection. runtime also covers shared background traffic, but only one connection at a time can register with this scope.
Internal and experimental RPCs
The following RPCs are marked internal in the official SDK, but Laravel exposes them as@experimental. They may change or be removed in the future, and the runtime’s caller restrictions still apply. Use them to create, list, and remove agent registry entries, open an authentication URL in the browser, clean up expired large tool outputs, and get sandbox path grant warnings. List results don’t include connection credentials.
Basic call example
Usage examples by feature
The following are representative call examples for the features above.Agent Plugin catalog candidates
Requireagent-plugin-discovery in catalog.search and specify plugin in the search kinds to get Agent Plugin candidates. To receive application/vnd.anthropic.claude-plugin+json and application/agent-plugin+json in addition to the standard format application/vnd.github.copilot-plugin, require agent-plugin-formats in addition to agent-plugin-discovery.
agent-plugin-confirmed-installation is a capability that returns installability and a plan for review. Require it together with agent-plugin-discovery as well. When granted, candidates include installability, whose value is one of installable, install-data-unavailable, feature-disabled, or not-installable-kind. installPlan is included only when installability is installable. The plan is data for review, and this catalog RPC never performs the installation.
The plan’s sources contains materialization, marketplace, and repository candidates in priority order. A marketplace records its name and repository, and a direct repository records the repository and an optional path. In a materialization-only plan, pluginName is omitted and components is empty. Check the name and what will actually be installed in the review returned by plugins.planInstall().
For a selected candidate, plugins.planInstall() creates a validated plan with no side effects. plugins.applyInstall() asks the user for explicit confirmation and applies the plan if allowed. The plugin is registered in a disabled state after it’s applied.
The review’s mcpServers shows the server names, transport, and, for remote servers, the host declared by the validated files. This isn’t a safety guarantee, so have the user review the contents before giving explicit confirmation. An installed plugin’s description comes from the manifest. verifiedSource shows the GitHub repository and pinned commit, and exists only for direct installs pinned to a commit. iconUrl is external, untrusted content, so don’t send credentials or GitHub credentials when fetching it. Credentials themselves are never returned as refusal reasons.
For a network-failure installation result, you can check the CatalogNetworkFailureReason, the HTTP statusCode, an optional retryAfterSeconds, and a message that’s safe to display.
catalog.planInstallFromReference(). The result’s outcome->kind is one of plugin-install-planned, skill-install-planned, or refused. Pass plugin plans to plugins.applyInstall() and skill plans to skills.applyInstall().
contentExclusion
You can validate content exclusion policy JSON before creating a session.policiesJson is passed to the CLI as an unparsed JSON string. If JSON parsing or schema validation fails, the CLI raises an RPC error (JsonRpcException).
This is a server-scoped RPC that validates the policies themselves. To check paths in the session’s working directory against the actual exclusion policies, use the session-scoped contentExclusion()->checkPaths().
managedSettings (experimental: managed settings)
Read managed settings, resolve policies, get the schema, validate, preview composition, and clear the cache.settings (experimental: settings file operations)
Remove a specific key from a settings file and redact secret values for display.removeRawKey() removes keys as-is, including keys that aren’t canonical settings paths, such as keys that failed to load. If the file can’t be parsed, the CLI doesn’t overwrite it and status is invalid. redactValueForDisplay() replaces secret values with placeholders based on the position in the settings tree given by basePath, so you can safely show the value to users or write it to logs.
Runtime and host lifecycle (experimental)
host.unpublishSession() withdraws an application publication from a running host you own. Unpublishing doesn’t delete or stop the original session history, worktree, or running work. If the session is already unpublished, unpublished is false, and publications other than application raise an error.
host.dispose() disposes of a host listener by hostId.
host.setSessionCreationPolicy() toggles whether a running host accepts new remote sessions. The change doesn’t disconnect existing clients and applies only to later admissions.
Client::stop() calls runtime.shutdown after disconnecting sessions and before closing the JSON-RPC connection and the process. Session detaches (session.detach) share a single 10-second deadline across all sessions; a detach that misses the deadline is included in the return value as an error, and shutdown continues. It also waits up to 10 seconds for runtime cleanup to finish; on failure, it includes the error in the return value and continues with the rest of the shutdown. For connections to an external runtime such as cli_url, this RPC isn’t called so the shared runtime isn’t terminated.
If the CLI can’t identify the matching request and returns a JSON-RPC error with id: null, every in-flight request fails with a JsonRpcException. The exception includes a diagnostic message with quoted values removed and its length capped. The connection stays open. Because the CLI may already have processed the request, don’t retry automatically without confirming that it’s safe. The SDK rejects outgoing requests nested deeper than 127 levels, which the CLI can’t read, before sending them. It replaces handler responses that are nested too deeply with a JSON-RPC error.
SessionRpc
An RPC class bound to the Session. You can also use features that weren’t possible in earlier SDKs, such as plan mode.Model, mode, name, and plan
Usemodel() to check or switch the current model and to set reasoning effort, the Auto tier, and allowed models. mode() handles the mode, name() the session name, and plan() reads and writes the plan body and SQLite todos.
Workspaces, instructions, and LSP
workspaces() lets you list, read, write, move, and delete files and work with directories. Use instructions() to get, reload, and discover instructions, and lsp() to initialize language server settings.
Autopilot objective
autopilotObjective()->getState() returns the session’s current Autopilot objective state as a typed object. If no objective exists, state is null. This API differs from workspaces()->autopilotObjectiveExists(), which checks whether an objective is saved in the workspace.
setStayInAutopilot() suppresses requests to return to interactive mode when an objective completes or pauses. The setting is kept in client memory and defaults to true. Pass false as value to stop suppressing. Set it again after you reconnect.
Agents, Fleet, and background tasks
Useagent() to list, select, and reload agents, and fleet() to start Fleet. tasks() handles registering background agents and client-owned tasks, getting and updating progress, promotion, sending messages, cancellation, and removal.
MCP, plugins, extensions, and workflow
mcp() handles listing, starting, stopping, and reloading servers, tools, prompts, resources, OAuth, sampling, and updating dynamic headers. plugins() and extensions() manage in-session state, and customizations() reloads customizations. Use workflow() to run and query workflows, and diagnostics() and connectors() to get diagnostics and connectors.
Tools, permissions, commands, and UI
tools() and permissions() handle responses to pending requests delivered via events, as well as settings. permissions()->clearResumeEscalation() clears, in memory, the permission escalation restored from history on resume, and returns a typed success result. commands() provides listing commands, running them, and responding to events, and ui() responds to requests such as user input, elicitation, and plan approval. completions() gets input completions.
Accounts, authentication, and providers
accounts() handles enumerating accounts, providers, and logged-in accounts with enumerate(), get() and set(), and interactive login with begin(), advance(), and cancel(). gitHubAuth() handles the session’s authentication status and credentials, provider() and providers() handle model endpoints and provider adapters, and connectors() handles the session’s connector connections.
History, queue, logs, and usage
history() provides conversation compaction (including compaction settings), aborting, handoff summaries, and truncation, and queue() provides inserting, moving, editing, removing, and immediately sending pending items. Use log(), eventLog(), usage(), quota(), and limitPrediction() to work with logs, events, usage, and limit information. schedule() lets you view and stop scheduled prompts.
Lifecycle, remote, and host integration
sendMessages() runs multiple messages in a single turn, and suspend() and shutdown() stop the session. interruptMainTurn() controls the main turn, and cancelAllBackgroundAgents() controls background agents separately. remote() and visibility() handle remote publication and sharing state, sandbox() the session’s sandbox, managedSettings() session-scoped managed settings, contentExclusion() path checks, metadata() client-owned metadata, and canvas() Canvas integration.
debug (experimental)
Usedebug()->collectLogs() to collect a session’s event logs, process logs, and shell logs into a .tgz archive or a directory. Logs are redacted for sensitive information by default. You can add files or directories with additionalEntries, and set redaction to plain-text, events-jsonl, or none. With none, nothing is redacted, so be careful about what you add.
DebugCollectLogsDestination::directory('/tmp/copilot-debug') to output to a staging directory. With include, you can individually specify which logs and reference paths to collect, and you can check what was collected from entries and skippedEntries in the result. Destination and additional entry paths are paths on the CLI server side. In the standard setup where the CLI is started over stdio, that’s the same host as your app, but if you connect over TCP to a CLI server on another host, specify paths on the server side, not on the calling machine.
contentExclusion (experimental)
You can check whether local absolute paths in the session’s working directory are subject to content exclusion policies. Call this before reading or attaching file contents.checkPaths() accepts only absolute paths, and the paths must be inside the session’s working directory. checks are returned in the same order as the input, and duplicate paths are kept as-is. If the path, file system, or policy evaluation isn’t supported or available, you get available: false and an empty checks. In that case, isExcluded() always returns true, so treat all paths as excluded. Even with available: true, paths missing from the result are conservatively treated as excluded.
MCP Apps (experimental)
You can call MCP Apps RPCs from$session->rpc()->mcp()->apps(). listTools() and callTool() require originServerName, the name of the calling MCP server. The result of callTool() is returned as a free-form MCP result.
readResource() returns resource data such as HTML. The SDK doesn’t render in a browser or manipulate iframes, so rendering the retrieved content is the responsibility of the calling application.
Usage examples by feature
The following are representative call examples for the features above.remote (experimental: remote session support)
sandbox (experimental: sandbox control)
$request['sandboxPathGrant'] is present, call this with the requestId of the pending request. Because this RPC itself responds to the permission request, return PermissionDecision::noResult() on success so that no normal response is sent.
metadata (experimental: session information)
Local session management (experimental)
Use$session->rpc()->management() to configure, list, create, message, and close local sessions that opted in to management in the same configuration directory. Register a host callback with setSessionCreationHandler() to receive the reverse RPC from create(). The callback must create the child session with newSessionId, keep its permission and model restrictions, and return a SessionManagementCreateResult.
In the following example, $sessionCreationHandler is a closure that receives a SessionManagementCreateHostRequest, creates the child session on the host, and returns a SessionManagementCreateResult.
accepted from message() means the message was accepted for delivery, not that the target replied or finished its task. After you confirm separately that a child session finished its work, use close() to close only the children you created. Saved history isn’t deleted.
Session canvas
Call the Canvas RPCs from$session->rpc()->canvas(). list() returns the list in
canvases of a CanvasList, and listOpen() returns it in openCanvases of a
CanvasListOpenResult. open() returns an OpenCanvasInstance, and
action invocations return a CanvasActionInvokeResult. close() has no
return value.
canvas.open / canvas.close /
canvas.action.invoke) are handled by canvasHandler in SessionConfig /
ResumeSessionConfig. Rendering the canvas is the responsibility of the host UI.
workflow
The experimental RPC APIs for workflows, connectors, diagnostics, and more added in the Copilot CLI 1.0.89 series are also available fromSessionRpc. Pass these variable protocol payloads as JSON-compatible arrays; responses are also returned as arrays. The current sessionId is added to each call automatically.
workflow() calls the low-level RPCs provided by the CLI. A high-level API for registering and running PHP closures as workflows, like the Node.js SDK has, wasn’t added in this sync. These new RPC groups depend on the CLI version and are experimental, so use them only with a compatible CLI.
SessionFS callback types
Callback types (Request/Result) are defined for session-scoped file system operations. These are the request/response types used when the Copilot CLI calls back to the client.SessionFsStatResult, SessionFsReaddirResult, and SessionFsReaddirWithTypesResult have an optional error (SessionFsError) used on failure.
SessionFs handlers
The Client routessessionFs.readFile / readFileBytes / writeFile / writeFileBytes requests, as well as appendFile, exists, stat, mkdir, readdir, readdirWithTypes, rm, rename, sqliteQuery, sqliteTransaction, and sqliteExists, to the Session’s provider. File operation failures are returned as an error of ENOENT (ENOENT or errno 2) or UNKNOWN. exists returns false on exception, and stat returns zero values plus an error on failure. Operations the provider doesn’t support result in an UNKNOWN error (a JSON-RPC error for SQLite operations). Exceptions from sqliteQuery/sqliteExists become JSON-RPC errors, and sqliteTransaction failures are returned as an error in the result (with errorClass).
The provider-side interfaces (SessionFsFilesystemProvider, SessionFsSqliteCapableProvider, SessionFsSqliteProvider, SessionFsSqliteTransactionProvider) were added as separate interfaces so they don’t break the existing SessionFsProvider (two methods).
SQLite callback types
To enable SQLite support, pass
SessionFsSetProviderCapabilities(sqlite: true) to capabilities of SessionFsSetProviderRequest.
sessionFs (or session_fs in config/copilot.php), Client::start() sends sessionFs.setProvider only once. Sessions need createSessionFsProvider (see SessionConfig).
The SessionFsSqliteQueryType enum (src/Enums/) represents the query type:
Exec: DDL/multiple statements (no result)Query: SELECT (returns rows)Run: INSERT/UPDATE/DELETE (returns rowsAffected)
src/Types/Rpc/.
Using arrays for arguments
Dedicated classes are used for both arguments and return values, but you can also pass arguments as arrays.Testing
Copilot::fake() mocks are not available, so mock with Copilot::expects('client') or Copilot::expects('start').
For the latest updates, see the GitHub repository.