Claude Desktop · Cursor · CopilotKit · any LLM

Your model knows what the user means.

Your AI copilot can't tell which metric the user is looking at, which row triggered the question, or what they highlighted. askable-ui fixes that with one attribute — no screenshots, no stale system prompts, no guessing. The AI gets the exact data the user sees, updated on every interaction.

Click Ask AI button Region Square Circle Lasso Selected text
See it live Documentation
Element + visual context Zero framework lock-in MCP-ready packets React · Vue · Svelte · Vanilla JS
live focus lens
MRR
$128,400
+12.4% this month
Churn
3.2%
improving
NPS
67
industry avg 44
Upsell
Umbrella
starter → business
Acme$8.4khealthy
Globex$5.2kat risk
Umbrella$2.1kexpanding
The assistant can read the element, area, or text the user explicitly selected.
What should I do about this circled account?
Globex is at risk. No login in 14 days, $5.2k MRR exposed.
<tr data-askable='{"company":"Globex Inc","status":"at_risk","last_login":"14 days ago"}'> ... </tr> User is focused on: company: Globex Inc, status: at_risk, last_login: 14 days ago

Not every question starts with a click.

Askable gives users more ways to say “this is what I mean” without sending the entire page to the model.

Context becomes an intentional user action.

Use DOM focus for the common path, then add explicit tools for visual ambiguity: draw over a chart, square off a fixed area, circle an outlier, lasso an irregular area, or send the text the user highlighted.

region.start({ shape: 'lasso' });
text.captureNow();
ctx.push(meta, text);

Element focus

Click, hover, keyboard focus, and Ask AI buttons bind context to existing widgets.

Region capture

Drag a rectangular page area when the answer depends on a visible section.

Square capture

Constrain the selected area when the target should keep an equal width and height.

Circle capture

Circle an anomaly, data point, product defect, chart spike, or object on screen.

Lasso capture

Freehand select irregular content that does not fit cleanly into a box.

T

Selected text

Send highlighted copy without asking the model to infer which words matter.

Context packets

Move structured context through MCP bridges, browser surfaces, and agent runtimes.

No page scraping

Context follows intent, not the whole DOM

Other approaches serialize the entire page or guess what matters. askable captures exactly what the user marked: an element, area, shape, or text selection.

App-owned sources

Use real state, not just visible DOM

Register redacted, timeout-safe resolvers for paginated tables, documents, maps, charts, calendars, or custom state so selected context resolves the right backing data.

Any stack

Dashboards, forms, tables, support tools

Works anywhere a user points, clicks, draws, circles, lassos, highlights, or hovers. React, Vue, Svelte, or plain HTML.

Select the UI. Watch the prompt tighten.

Click a KPI, draw a region, circle a row, lasso a panel, or highlight text. The context panel updates in real time.

Interaction pattern Click
Element metadata + text
Click an annotated KPI or account row to load its context.
Format:
Prompt text:
Top Accounts same data drives UI + AI context
CompanyMRRPlanStatus
context source element metadata or explicit selection packet
select context above…
askable.toPromptContext() ready to inject at the model boundary
waiting for focus…

Three simple steps.

No giant framework. No invasive serialization. Let the model borrow the user's explicit context.

1

Annotate or capture

Add data-askable wherever your UI already has meaning, then add tools for regions, circles, lasso selections, and highlighted text.

<div data-askable='{"metric":"MRR","value":"$128K"}'>
  ...
</div>
2

Observe intent

Call askable.observe(document) once. askable tracks click, hover, focus, explicit selection, and semantic app events.

askable.observe(document, {
  events: ['click']
});
3

Inject

At the AI boundary, package the user's question with prompt context, the selected packet, and app-owned sources. The assistant now knows what the user actually meant.

const request = await askable.toAgentRequest(question, {
  packet: selectedPacket,
  contextFromPacket: true,
  selectionFromPacket: true,
  sources: ['accounts']
});
// → { question, context, packet, focus, timestamp }

Pick your stack. Keep the idea.

One core library. Thin adapters for every framework. Same mental model everywhere.

Plugs into your AI layer.

toPromptContext() returns a plain string. Pass it to any LLM framework or API — no adapter needed.

MCP client
Claude Desktop
Claude sees exactly what the user sees. Ask about the focused element without screenshots.
MCP client
Cursor
Your IDE agent reads live UI context via the askable MCP server. Accurate, no manual description.
Framework
CopilotKit
Pass context via useCopilotReadable(). The LLM sees what the user selected.
Framework
Vercel AI SDK
Inject into the system message or tool context for streaming chat UIs.
Any LLM API
OpenAI · Anthropic
Append the string to your system or user message. Works with any provider.

Put Askable context on the page, then let MCP clients read it.

WebMCP is the browser-local path: a page widget connects to a local MCP server and exposes approved page tools, prompts, and resources. Hosted MCP is the separate HTTPS endpoint path for remote MCP clients.

page widget ↔ local MCP client

WebMCP page

Add a page-side bridge that exposes the current Askable packet, prompt text, and approved app sources as page-owned context.

createAskableMcpPageBridge({
  provider,
  allowedOrigins: [
    window.location.origin
  ]
});

Local client

The user runs a local WebMCP MCP server in their client, creates a token, then connects the page widget with that token.

{
  "mcpServers": {
    "webmcp": {
      "command": "npx",
      "args": [
        "-y",
        "@jason.today/webmcp@latest",
        "--mcp"
      ]
    }
  }
}

Page resources

Askable can provide the selected element, lassoed region, highlighted text, viewport, or app-owned source as an askable://current page resource.

window.postMessage({
  type: "read_current_resource",
  options: {
    resource: { uri: "askable://current" }
  }
});

Hosted MCP

For server-side use, expose the same provider through a secure HTTPS MCP route with auth, CORS, request limits, and tenancy checks.

createAskableMcpWebHandler({
  authorize,
  provider,
  maxRequestBodyBytes: 256 * 1024
});

Give Claude Desktop eyes into your app.

Expose your app's live UI context as an MCP server. Claude, Cursor, and any MCP client can call get_current_context to see exactly what the user is looking at — no screenshots, no description needed.

Three lines to an MCP server.

Any page annotated with data-askable instantly becomes queryable by AI agents. The MCP bridge translates live DOM state into structured Context packets that agents can read and reason about.

import { createAskableMcpServer } from '@askable-ui/mcp';

const server = createAskableMcpServer({ provider });
server.connect(transport); // stdio, SSE, or WebSocket

get_current_context

Returns the focused element's structured metadata, surrounding context, and interaction history as a typed JSON packet.

T

format_context_for_prompt

Returns a prompt-ready text rendering of the current context — drop it directly into any system message.

🔒

Privacy gate built in

Set requireRedacted: true to block unredacted packets from leaving the page. PII stays in your app.

Schema resource

The MCP server exposes the full Context packet JSON Schema so agents can self-document and validate responses.

claude_desktop_config.json

{
  "mcpServers": {
    "my-app": {
      "command": "node",
      "args": ["./mcp-server.js"]
    }
  }
}

Full MCP integration guide

Your AI. Your UI. Finally connected.

Drop data-askable on your most important element. Working context in under five minutes — or scaffold a full copilot app in one command.