Skip to main content
Every tool handler receives a PluginContext as its first argument. It provides authentication, authorization context, approval requests, and logging.

Properties

ctx.userId

userId: string
The authenticated user’s ID. Use this to scope operations to the current user.

ctx.role

role: Role  // { id: string, name: string, patterns: string[] }
The user’s role, including the glob patterns that determine which tools they can access.

ctx.auth

auth: AuthResolver  // { getToken(provider: string): Promise<string> }
Retrieve an OAuth access token for a provider. The token is automatically vended and refreshed by the server.
const token = await ctx.auth.getToken("github");
const res = await fetch("https://api.github.com/user", {
  headers: { Authorization: `Bearer ${token}` },
});

ctx.elicit

elicit: (request: {
  toolPath: string;
  message: string;
  args?: Record<string, unknown>;
  type?: "approval" | "form";  // default: "approval"
}) => Promise<{
  executionId: string;
  approved: boolean;
  data?: Record<string, unknown>;
}>
Request user approval before performing a destructive action. See Elicitation Guide.
const approval = await ctx.elicit({
  toolPath: "github.issues.create",
  message: `Create issue "${input.title}"?`,
  args: input,
  type: "approval",
});

if (!approval.approved) {
  throw new Error("Denied by user");
}

ctx.logger

logger: {
  info(message: string, meta?: Record<string, unknown>): void;
  warn(message: string, meta?: Record<string, unknown>): void;
  error(message: string, meta?: Record<string, unknown>): void;
}
Structured logging with optional metadata.
ctx.logger.info("Fetching issues", { owner: "org", repo: "repo" });
ctx.logger.error("GitHub API returned 403", { status: 403 });