Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 100 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,113 @@ That makes the MCP surface much higher-signal for copilots, IDE agents, and desk

## Current slice

This initial repo setup ships:
This repo currently ships:

- `createAskableMcpSnapshot()` — serialize an `AskableContext` into an MCP-friendly session snapshot
- `createAskableMcpBridge()` — send snapshot updates through an injected transport
- `AskableMcpServer` — in-memory session/resource/tool state
- `createAskableMcpSdkServer()` — MCP SDK adapter exposing askable resources and the `select_element` tool
- `askable-mcp` CLI — runnable stdio MCP server with a local bridge HTTP sidecar

## Install

```bash
npm install @askable-ui/mcp @askable-ui/core
```

## Example
## Run the local stdio server

```bash
npm run build
npm run start
```

By default this starts:

- an MCP stdio server on `stdin` / `stdout` for Claude Desktop, Cursor, or other process-spawned MCP clients
- a local bridge server on `http://127.0.0.1:4318`

Available local bridge endpoints:

- `POST /bridge` — ingest serialized snapshot messages from the browser/app bridge
- `GET /sessions` — inspect known askable sessions
- `GET /commands?sessionId=...` — drain queued `select_element` commands for a browser session
- `GET /health` — basic health check

You can change the bridge listener with CLI flags:

```bash
node dist/cli.js --host 127.0.0.1 --bridge-port 4318
```

## Claude Desktop configuration

Build the package, then point Claude Desktop at the stdio entrypoint:

```json
{
"mcpServers": {
"askable": {
"command": "node",
"args": [
"/absolute/path/to/askable-mcp/dist/cli.js",
"--bridge-port",
"4318"
]
}
}
}
```

After Claude Desktop launches the server, `ui_context`, `ui_history`, `ui_viewport`, and `select_element` become available once your app starts posting snapshots to the local bridge.

## Browser / app bridge example

```ts
import { createAskableContext } from '@askable-ui/core';
import { createAskableMcpBridge } from '@askable-ui/mcp';

const ctx = createAskableContext({ viewport: true });
const sessionId = 'dashboard-tab';

createAskableMcpBridge({
ctx,
sessionId,
pageUrl: window.location.href,
pageTitle: document.title,
includeViewport: true,
transport: {
send(message) {
void fetch('http://127.0.0.1:4318/bridge', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: message,
});
},
},
});

async function pollCommands() {
const response = await fetch(
`http://127.0.0.1:4318/commands?sessionId=${encodeURIComponent(sessionId)}`
);
const payload = (await response.json()) as {
commands: Array<{ type: 'select_element'; elementId: string }>;
};

for (const command of payload.commands) {
if (command.type === 'select_element') {
console.log('focus element in app', command.elementId);
}
}
}

setInterval(() => {
void pollCommands();
}, 500);
```

## Library example

```ts
import { createAskableContext } from '@askable-ui/core';
Expand Down Expand Up @@ -87,11 +180,11 @@ const mcpServer = createAskableMcpSdkServer(state, {

## Planned follow-up work

- stdio runner for Claude Desktop / Cursor local usage
- Streamable HTTP / WebSocket deployment story
- browser-side command handling for `select_element`
- multi-session routing and active-session selection
- setup docs for Claude Desktop and Cursor
- browser-side helpers for handling `select_element` automatically
- streamable HTTP deployment story
- multi-session routing and active-session selection UX
- richer Claude Desktop / Cursor setup docs
- optional auth / origin controls for the local bridge endpoint

## Development

Expand Down
51 changes: 21 additions & 30 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"bin": {
"askable-mcp": "./dist/cli.js"
},
"exports": {
".": {
"import": "./dist/index.js",
Expand All @@ -21,6 +24,7 @@
},
"scripts": {
"build": "tsc",
"start": "node ./dist/cli.js",
"test": "vitest run"
},
"keywords": [
Expand All @@ -38,6 +42,7 @@
"zod": "^4.3.6"
},
"devDependencies": {
"@types/node": "^24.5.2",
"typescript": "^6.0.2",
"vitest": "^4.1.2"
}
Expand Down
Loading
Loading