Home-page Webview API
@ambleloft/extension-sdk/webview serves extension home pages. Custom in-chat UI uses the separate MCP Apps protocol.
Browse contracts, signatures, fields and examples. Unspecified defaults are not inferred.
On this page
01Initialize and invoke
Create the client in the browser entry and await initialize. Replace the operation ID with your own declared operation. Result uses ok to distinguish success and failure. unwrap throws ExtensionError for failures and never retries.
import { createClient, unwrap } from '@ambleloft/extension-sdk/webview';
const client = createClient();
const host = await client.initialize();
const result = await client.invoke('samples.hello-operation.count', { text: 'Hello' });
const output = unwrap(result);
console.log(host.locale, output);02WebviewClient methods
A page click is not host consent. The host confirms the exact write request for invoke. Pages cannot manufacture grant tokens.
| Field / API | Contract |
|---|---|
| initialize(): Promise<HostContext> | Handshake: protocol, theme, locale and supported methods. |
| invoke(operationId,input,{signal?}?): Promise<Result<JsonObject>> | Invoke a declared operation; signal is AbortSignal. |
| selectProject({capabilities}): Promise<Result<Project|null>> | Cancellation returns the successful value null. |
| requestGrant({projectId,capabilities}): Promise<Result<boolean>> | Cancellation returns false. |
| requestSecretInput({key,title}): Promise<Result<{saved:boolean}>> | Returns only saved status, never the secret value. |
| onHostContextChanged(listener): Disposable | Observe context changes and dispose the listener. |
03HostContext and capabilities
Do not assume all methods exist on older hosts. supportedMethods can drive UI fallbacks; the host still enforces declarations and grants.
interface HostContext {
protocolVersion: '1';
extensionId: string;
pageInstanceId: string;
locale: string;
theme: 'light' | 'dark';
supportedMethods: string[];
}
type Capability = 'projects.read' | 'projects.path.read'
| 'conversations.create' | 'conversations.open'
| 'storage' | 'configuration' | 'secrets';04Failure object
Preserve code, requestId and effectStatus for diagnostics. unknown means the effect may have occurred; a UI timeout is not permission to retry a write.
type Result<T> = { ok: true; value: T } | { ok: false; error: Failure };
interface Failure {
code: ErrorCode;
message: string;
requestId: string;
effectStatus: 'notStarted' | 'unknown' | 'completed';
details?: JsonObject;
}