@alaarab/ogrid-mcp 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +68 -0
  2. package/bundled-docs/api/README.md +94 -0
  3. package/bundled-docs/api/column-def.mdx +379 -0
  4. package/bundled-docs/api/components-column-chooser.mdx +310 -0
  5. package/bundled-docs/api/components-column-header-filter.mdx +363 -0
  6. package/bundled-docs/api/components-datagrid-table.mdx +316 -0
  7. package/bundled-docs/api/components-pagination-controls.mdx +344 -0
  8. package/bundled-docs/api/components-sidebar.mdx +427 -0
  9. package/bundled-docs/api/components-status-bar.mdx +309 -0
  10. package/bundled-docs/api/grid-api.mdx +299 -0
  11. package/bundled-docs/api/js-api.mdx +198 -0
  12. package/bundled-docs/api/ogrid-props.mdx +244 -0
  13. package/bundled-docs/api/types.mdx +640 -0
  14. package/bundled-docs/features/cell-references.mdx +225 -0
  15. package/bundled-docs/features/column-chooser.mdx +279 -0
  16. package/bundled-docs/features/column-groups.mdx +290 -0
  17. package/bundled-docs/features/column-pinning.mdx +282 -0
  18. package/bundled-docs/features/column-reordering.mdx +359 -0
  19. package/bundled-docs/features/column-types.mdx +181 -0
  20. package/bundled-docs/features/context-menu.mdx +216 -0
  21. package/bundled-docs/features/csv-export.mdx +227 -0
  22. package/bundled-docs/features/editing.mdx +377 -0
  23. package/bundled-docs/features/filtering.mdx +330 -0
  24. package/bundled-docs/features/formulas.mdx +381 -0
  25. package/bundled-docs/features/grid-api.mdx +311 -0
  26. package/bundled-docs/features/keyboard-navigation.mdx +236 -0
  27. package/bundled-docs/features/pagination.mdx +245 -0
  28. package/bundled-docs/features/performance.mdx +433 -0
  29. package/bundled-docs/features/row-selection.mdx +256 -0
  30. package/bundled-docs/features/server-side-data.mdx +291 -0
  31. package/bundled-docs/features/sidebar.mdx +234 -0
  32. package/bundled-docs/features/sorting.mdx +241 -0
  33. package/bundled-docs/features/spreadsheet-selection.mdx +201 -0
  34. package/bundled-docs/features/status-bar.mdx +205 -0
  35. package/bundled-docs/features/toolbar.mdx +284 -0
  36. package/bundled-docs/features/virtual-scrolling.mdx +624 -0
  37. package/bundled-docs/getting-started/installation.mdx +216 -0
  38. package/bundled-docs/getting-started/overview.mdx +151 -0
  39. package/bundled-docs/getting-started/quick-start.mdx +425 -0
  40. package/bundled-docs/getting-started/vanilla-js.mdx +191 -0
  41. package/bundled-docs/guides/accessibility.mdx +550 -0
  42. package/bundled-docs/guides/controlled-vs-uncontrolled.mdx +153 -0
  43. package/bundled-docs/guides/custom-cell-editors.mdx +201 -0
  44. package/bundled-docs/guides/framework-showcase.mdx +200 -0
  45. package/bundled-docs/guides/mcp-live-testing.mdx +291 -0
  46. package/bundled-docs/guides/mcp.mdx +172 -0
  47. package/bundled-docs/guides/migration-from-ag-grid.mdx +223 -0
  48. package/bundled-docs/guides/theming.mdx +211 -0
  49. package/dist/esm/bridge-client.d.ts +87 -0
  50. package/dist/esm/bridge-client.js +162 -0
  51. package/dist/esm/index.js +1060 -0
  52. package/package.json +43 -0
@@ -0,0 +1,201 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: Custom Cell Editors
4
+ description: Build custom inline and popup cell editors for OGrid columns.
5
+ ---
6
+
7
+ # Custom Cell Editors
8
+
9
+ OGrid includes built-in editors for common types (`text`, `select`, `checkbox`, `richSelect`, `date`), but you can create fully custom editors for any use case. A custom editor is a React component that receives the cell value, update callbacks, and optional params.
10
+
11
+ ## The ICellEditorProps Interface
12
+
13
+ Every custom editor receives these props:
14
+
15
+ ```tsx
16
+ interface ICellEditorProps<T> {
17
+ value: unknown; // Current cell value
18
+ onValueChange: (value: unknown) => void; // Update the value as user types
19
+ onCommit: () => void; // Save and close
20
+ onCancel: () => void; // Discard and close
21
+ item: T; // The full row data
22
+ column: IColumnDef<T>; // The column definition
23
+ cellEditorParams?: CellEditorParams; // Extra config from the column def
24
+ }
25
+ ```
26
+
27
+ ## Popup Editor Example
28
+
29
+ A popup editor renders in a floating overlay above the cell. This is ideal for editors that need more space than an inline cell -- like a textarea, a date picker, or a color picker.
30
+
31
+ ### Step 1: Create the Editor Component
32
+
33
+ ```tsx
34
+
35
+ interface NoteItem {
36
+ id: string;
37
+ title: string;
38
+ notes: string;
39
+ }
40
+
41
+ function NotesEditor({ value, onValueChange, onCommit, onCancel }: ICellEditorProps<NoteItem>) {
42
+ return (
43
+ <div style={{ padding: 12, width: 300 }}>
44
+ <textarea
45
+ autoFocus
46
+ rows={5}
47
+ value={String(value ?? '')}
48
+ onChange={(e) => onValueChange(e.target.value)}
49
+ onKeyDown={(e) => {
50
+ if (e.key === 'Escape') onCancel();
51
+ }}
52
+ style={{ width: '100%', resize: 'vertical', fontFamily: 'inherit', fontSize: 14 }}
53
+ />
54
+ <div style={{ display: 'flex', gap: 8, marginTop: 8, justifyContent: 'flex-end' }}>
55
+ <button onClick={onCancel}>Cancel</button>
56
+ <button onClick={onCommit}>Save</button>
57
+ </div>
58
+ </div>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ### Step 2: Wire It Up in the Column Definition
64
+
65
+ Set `cellEditor` to your component and `cellEditorPopup: true` to render it in a floating overlay:
66
+
67
+ ```tsx
68
+
69
+ const columns: IColumnDef<NoteItem>[] = [
70
+ { columnId: 'title', name: 'Title', editable: true },
71
+ {
72
+ columnId: 'notes',
73
+ name: 'Notes',
74
+ editable: true,
75
+ cellEditor: NotesEditor,
76
+ cellEditorPopup: true,
77
+ },
78
+ ];
79
+ ```
80
+
81
+ ### Step 3: Enable Editing on the Grid
82
+
83
+ ```tsx
84
+ <OGrid
85
+ columns={columns}
86
+ data={items}
87
+ getRowId={(item) => item.id}
88
+ editable
89
+ onCellValueChanged={(event) => {
90
+ console.log(`${event.columnId} changed from`, event.oldValue, 'to', event.newValue);
91
+ }}
92
+ />
93
+ ```
94
+
95
+ When a user double-clicks the Notes cell (or presses Enter on it), the `NotesEditor` appears in a popup. Clicking Save calls `onCommit`, which writes the value back to the grid and fires `onCellValueChanged`.
96
+
97
+ ## Inline Editor Example
98
+
99
+ Without `cellEditorPopup`, the editor replaces the cell content inline. This is the default behavior and works well for small inputs:
100
+
101
+ ```tsx
102
+ function ColorEditor({ value, onValueChange, onCommit, onCancel }: ICellEditorProps<any>) {
103
+ return (
104
+ <input
105
+ type="color"
106
+ autoFocus
107
+ value={String(value ?? '#000000')}
108
+ onChange={(e) => onValueChange(e.target.value)}
109
+ onBlur={onCommit}
110
+ onKeyDown={(e) => {
111
+ if (e.key === 'Escape') onCancel();
112
+ if (e.key === 'Enter') onCommit();
113
+ }}
114
+ />
115
+ );
116
+ }
117
+
118
+ const columns = [
119
+ {
120
+ columnId: 'color',
121
+ name: 'Color',
122
+ editable: true,
123
+ cellEditor: ColorEditor,
124
+ // No cellEditorPopup -- renders inline
125
+ },
126
+ ];
127
+ ```
128
+
129
+ ## Using cellEditorParams
130
+
131
+ Pass extra configuration to your editor through `cellEditorParams`. This keeps your editor component reusable across columns:
132
+
133
+ ```tsx
134
+ function RatingEditor({ value, onValueChange, onCommit, cellEditorParams }: ICellEditorProps<any>) {
135
+ const maxStars = (cellEditorParams?.maxStars as number) ?? 5;
136
+
137
+ return (
138
+ <div style={{ display: 'flex', gap: 4 }}>
139
+ {Array.from({ length: maxStars }, (_, i) => (
140
+ <button
141
+ key={i}
142
+ onClick={() => {
143
+ onValueChange(i + 1);
144
+ // Auto-commit after selection
145
+ setTimeout(onCommit, 0);
146
+ }}
147
+ style={{
148
+ background: 'none',
149
+ border: 'none',
150
+ cursor: 'pointer',
151
+ fontSize: 18,
152
+ opacity: (value as number) >= i + 1 ? 1 : 0.3,
153
+ }}
154
+ >
155
+ *
156
+ </button>
157
+ ))}
158
+ </div>
159
+ );
160
+ }
161
+
162
+ const columns = [
163
+ {
164
+ columnId: 'rating',
165
+ name: 'Rating',
166
+ editable: true,
167
+ cellEditor: RatingEditor,
168
+ cellEditorParams: { maxStars: 10 },
169
+ },
170
+ ];
171
+ ```
172
+
173
+ :::tip
174
+ The `cellEditorParams` object is passed through as-is. You can put any serializable configuration there -- select options, validation rules, format strings, API endpoints, or anything your editor needs.
175
+ :::
176
+
177
+ ## Built-in Editors
178
+
179
+ Before building a custom editor, check if a built-in one fits your needs:
180
+
181
+ | `cellEditor` | Description | `cellEditorParams` |
182
+ |---|---|---|
183
+ | `'text'` | Standard text input (default) | -- |
184
+ | `'select'` | Dropdown select | `{ values: ['Option A', 'Option B'] }` |
185
+ | `'checkbox'` | Boolean toggle | -- |
186
+ | `'richSelect'` | Searchable dropdown with keyboard navigation | `{ values: [...], formatValue: (v) => string }` |
187
+ | `'date'` | Native date picker (`<input type="date">`) | -- |
188
+
189
+ ## Conditional Editability
190
+
191
+ Use a function for `editable` to control which rows allow editing:
192
+
193
+ ```tsx
194
+ {
195
+ columnId: 'status',
196
+ name: 'Status',
197
+ editable: (item) => item.status !== 'locked',
198
+ cellEditor: 'select',
199
+ cellEditorParams: { values: ['Draft', 'Review', 'Published'] },
200
+ }
201
+ ```
@@ -0,0 +1,200 @@
1
+ ---
2
+ sidebar_position: 5
3
+ title: Framework Showcase
4
+ description: See OGrid in action with React, Angular, Vue, and Vanilla JS — 8 UI implementations, one API
5
+ ---
6
+
7
+
8
+ # Framework Showcase
9
+
10
+ OGrid renders with your design system's native components. Same API, same features — different look and feel. Every grid below is **fully interactive**: sort, filter, edit, select cells, copy/paste, and undo/redo.
11
+
12
+ ---
13
+
14
+ ## React
15
+
16
+ Three design-system implementations, all sharing the same hooks and headless logic from `@alaarab/ogrid-react`.
17
+
18
+ ### Radix UI <small>(Default)</small>
19
+
20
+ The lightest option — Radix primitives are bundled with zero peer dependencies beyond React.
21
+
22
+ ```bash
23
+ npm install @alaarab/ogrid-react-radix
24
+ ```
25
+
26
+ <ShowcaseRadixDemo />
27
+
28
+ ### Fluent UI
29
+
30
+ Microsoft's Fluent UI v9 components. Best for **Microsoft 365 and SharePoint** projects.
31
+
32
+ ```bash
33
+ npm install @alaarab/ogrid-react-fluent @fluentui/react-components
34
+ ```
35
+
36
+ <ShowcaseFluentDemo />
37
+
38
+ ### Material UI
39
+
40
+ Google's Material Design via MUI v7. Best for apps already on **Material Design**.
41
+
42
+ ```bash
43
+ npm install @alaarab/ogrid-react-material @mui/material @emotion/react @emotion/styled
44
+ ```
45
+
46
+ <ShowcaseMaterialDemo />
47
+
48
+ ---
49
+
50
+ ## Angular
51
+
52
+ Signals-based reactivity with standalone components. Zone-less by default, no NgModule boilerplate. All three packages share the same services from `@alaarab/ogrid-angular`.
53
+
54
+ ### Radix (Angular CDK) <small>(Default)</small>
55
+
56
+ The lightest option — Angular CDK for overlays with zero heavy UI framework dependencies.
57
+
58
+ ```bash
59
+ npm install @alaarab/ogrid-angular-radix @angular/cdk
60
+ ```
61
+
62
+ ```typescript
63
+
64
+ @Component({
65
+ standalone: true,
66
+ imports: [OGridComponent],
67
+ template: `<ogrid [props]="gridProps" />`
68
+ })
69
+ export class GridComponent {
70
+ gridProps = { columns, data, getRowId: (row) => row.id, defaultPageSize: 10 };
71
+ }
72
+ ```
73
+
74
+ <div style={{ marginTop: '0.75rem' }}>
75
+ </div>
76
+
77
+ ### Angular Material
78
+
79
+ Angular Material v21 components. Best for projects already using **Material Design**.
80
+
81
+ ```bash
82
+ npm install @alaarab/ogrid-angular-material @angular/material @angular/cdk
83
+ ```
84
+
85
+ ```typescript
86
+ // Same API — just change the import
87
+ ```
88
+
89
+ ### PrimeNG
90
+
91
+ PrimeNG v21 components for teams already using the PrimeFaces ecosystem.
92
+
93
+ ```bash
94
+ npm install @alaarab/ogrid-angular-primeng primeng
95
+ ```
96
+
97
+ ```typescript
98
+ // Same API — just change the import
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Vue
104
+
105
+ Composition API composables using `ref()` and `computed()`. All three packages share the same composables from `@alaarab/ogrid-vue`.
106
+
107
+ ### Radix (Headless UI) <small>(Default)</small>
108
+
109
+ The lightest option — Headless UI Vue components are bundled with zero peer dependencies beyond Vue.
110
+
111
+ ```bash
112
+ npm install @alaarab/ogrid-vue-radix
113
+ ```
114
+
115
+ ```vue
116
+ <script setup lang="ts">
117
+
118
+ const gridProps = { columns, data, getRowId: (row) => row.id, defaultPageSize: 10 };
119
+ </script>
120
+
121
+ <template>
122
+ <OGrid :gridProps="gridProps" />
123
+ </template>
124
+ ```
125
+
126
+ <div style={{ marginTop: '0.75rem' }}>
127
+ </div>
128
+
129
+ ### Vuetify
130
+
131
+ Vuetify 3 components. Best for projects already using **Vuetify and Material Design**.
132
+
133
+ ```bash
134
+ npm install @alaarab/ogrid-vue-vuetify vuetify
135
+ ```
136
+
137
+ ```vue
138
+ <script setup lang="ts">
139
+ // Same API — just change the import
140
+ </script>
141
+ ```
142
+
143
+ ### PrimeVue
144
+
145
+ PrimeVue 4 components for teams already using the PrimeFaces ecosystem.
146
+
147
+ ```bash
148
+ npm install @alaarab/ogrid-vue-primevue primevue
149
+ ```
150
+
151
+ ```vue
152
+ <script setup lang="ts">
153
+ // Same API — just change the import
154
+ </script>
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Vanilla JS / TypeScript
160
+
161
+ No framework, no virtual DOM. A class-based imperative API that renders directly to the DOM with a built-in CSS theme supporting light and dark mode.
162
+
163
+ ```bash
164
+ npm install @alaarab/ogrid-js
165
+ ```
166
+
167
+ <VanillaJSDemo />
168
+
169
+ ---
170
+
171
+ ## At a Glance
172
+
173
+ | Framework | Design Systems | Reactivity |
174
+ |-----------|---------------|------------|
175
+ | **React** 17–19 | Radix *(default, bundled)* · Fluent UI v9 · MUI v7 | Hooks |
176
+ | **Angular** 21 | Radix (CDK) *(default)* · Angular Material · PrimeNG | Signals |
177
+ | **Vue** 3.3+ | Radix (Headless UI) *(default, bundled)* · Vuetify 3 · PrimeVue 4 | Composition API |
178
+ | **Vanilla JS/TS** | Built-in CSS theme *(zero deps)* | EventEmitter |
179
+
180
+ All 10 packages share the same **headless core** (`@alaarab/ogrid-core`) and pass the same **2,135 tests**. Switching design systems is a matter of changing imports.
181
+
182
+ ## Choosing a Package
183
+
184
+ - **Starting fresh with React?** → **Radix** — lightest weight, zero peer deps, full feature parity.
185
+ - **Microsoft ecosystem?** → **Fluent** — native look in Teams, SharePoint, Outlook.
186
+ - **Already using MUI?** → **Material** — matches your existing theme and components.
187
+ - **Starting fresh with Angular?** → **Radix (CDK)** — lightest weight with Angular CDK for overlays.
188
+ - **Already using Angular Material?** → **Angular Material** — matches your existing theme.
189
+ - **Already using PrimeNG?** → **PrimeNG** — integrates with PrimeFaces ecosystem.
190
+ - **Starting fresh with Vue?** → **Radix (Headless UI)** — lightest weight, zero peer deps, Composition API.
191
+ - **Already using Vuetify?** → **Vuetify** — matches your existing theme and components.
192
+ - **Already using PrimeVue?** → **PrimeVue** — integrates with PrimeFaces ecosystem.
193
+ - **No framework?** → **Vanilla JS** — works anywhere, class-based API, CSS-only theming.
194
+
195
+ ## Related
196
+
197
+ - [Installation](../getting-started/installation) — install instructions for all packages
198
+ - [Quick Start](../getting-started/quick-start) — build your first grid
199
+ - [Theming Guide](./theming) — customize colors and styling
200
+ - [Vanilla JS Guide](../getting-started/vanilla-js) — full JS API documentation
@@ -0,0 +1,291 @@
1
+ ---
2
+ title: MCP Live Testing Bridge
3
+ description: Connect AI assistants (Claude, Cursor) to a running OGrid instance for real-time testing and inspection.
4
+ ---
5
+
6
+
7
+ # MCP Live Testing Bridge
8
+
9
+ The `@alaarab/ogrid-mcp` package includes a **live testing bridge** that lets AI assistants connected via MCP read your grid's current state, update cell values, apply filters, and navigate pages — all in real time while your dev app is running.
10
+
11
+ ## How it works
12
+
13
+ ```
14
+ Claude (MCP client)
15
+ │ MCP tools
16
+
17
+ ogrid-mcp (stdio process + HTTP bridge on :7890)
18
+ │ HTTP polling every 500ms
19
+
20
+ Your dev app (localhost:3001)
21
+ └── connectGridToBridge() — pushes state + handles commands
22
+ ```
23
+
24
+ The bridge is **opt-in** and **dev-only** — it only runs when you explicitly start the MCP server with the `--bridge` flag or `OGRID_BRIDGE_PORT` env var.
25
+
26
+ ---
27
+
28
+ ## Quick start
29
+
30
+ ### 1. Start the MCP server with bridge enabled
31
+
32
+ ```bash
33
+ # Option A: use --bridge flag (port 7890)
34
+ npx @alaarab/ogrid-mcp --bridge
35
+
36
+ # Option B: use env var (custom port)
37
+ OGRID_BRIDGE_PORT=7890 npx @alaarab/ogrid-mcp
38
+
39
+ # Claude Desktop / claude mcp add
40
+ claude mcp add ogrid -- npx -y @alaarab/ogrid-mcp --bridge
41
+ ```
42
+
43
+ ### 2. Connect your dev app
44
+
45
+ <Tabs groupId="framework">
46
+ <TabItem value="react" label="React">
47
+
48
+ ```tsx
49
+
50
+ export function MyGrid() {
51
+ const [data, setData] = useState(myRows);
52
+ const apiRef = useRef<IOGridApi | null>(null);
53
+
54
+ useEffect(() => {
55
+ // Only connect in development
56
+ if (process.env.NODE_ENV !== 'development') return;
57
+
58
+ const bridge = connectGridToBridge({
59
+ gridId: 'my-grid',
60
+ getData: () => data,
61
+ getColumns: () => columns,
62
+ api: apiRef.current ?? undefined,
63
+ // Handle update_cell commands from Claude
64
+ onCellUpdate: (rowIndex, columnId, value) => {
65
+ setData(prev =>
66
+ prev.map((row, i) => i === rowIndex ? { ...row, [columnId]: value } : row)
67
+ );
68
+ },
69
+ });
70
+
71
+ return () => bridge.disconnect();
72
+ }, [data]);
73
+
74
+ return <OGrid ref={apiRef} data={data} columns={columns} />;
75
+ }
76
+ ```
77
+
78
+ </TabItem>
79
+ <TabItem value="angular" label="Angular">
80
+
81
+ ```typescript
82
+
83
+ @Component({ /* ... */ })
84
+ export class MyGridComponent implements OnInit, OnDestroy {
85
+ data = myRows;
86
+ columns = myColumns;
87
+ service = new OGridService();
88
+ private bridge?: BridgeConnection;
89
+
90
+ ngOnInit() {
91
+ if (!isDevMode()) return;
92
+ this.bridge = connectGridToBridge({
93
+ gridId: 'my-grid',
94
+ getData: () => this.data,
95
+ getColumns: () => this.columns,
96
+ onCellUpdate: (rowIndex, columnId, value) => {
97
+ this.data = this.data.map((row, i) =>
98
+ i === rowIndex ? { ...row, [columnId]: value } : row
99
+ );
100
+ },
101
+ });
102
+ }
103
+
104
+ ngOnDestroy() {
105
+ this.bridge?.disconnect();
106
+ }
107
+ }
108
+ ```
109
+
110
+ </TabItem>
111
+ <TabItem value="vue" label="Vue">
112
+
113
+ ```vue
114
+ <script setup lang="ts">
115
+
116
+ const data = ref(myRows);
117
+ let bridge: ReturnType<typeof connectGridToBridge> | null = null;
118
+
119
+ onMounted(() => {
120
+ if (import.meta.env.DEV) {
121
+ bridge = connectGridToBridge({
122
+ gridId: 'my-grid',
123
+ getData: () => data.value,
124
+ getColumns: () => columns,
125
+ onCellUpdate: (rowIndex, columnId, value) => {
126
+ data.value = data.value.map((row, i) =>
127
+ i === rowIndex ? { ...row, [columnId]: value } : row
128
+ );
129
+ },
130
+ });
131
+ }
132
+ });
133
+
134
+ onUnmounted(() => bridge?.disconnect());
135
+ </script>
136
+ ```
137
+
138
+ </TabItem>
139
+ <TabItem value="js" label="Vanilla JS">
140
+
141
+ ```js
142
+
143
+ const grid = new OGrid(container, { data: myRows, columns });
144
+
145
+ // Only in development
146
+ if (location.hostname === 'localhost') {
147
+ const bridge = connectGridToBridge({
148
+ gridId: 'my-grid',
149
+ getData: () => grid.getApi().getData(),
150
+ getColumns: () => columns,
151
+ onCellUpdate: (rowIndex, columnId, value) => {
152
+ // Update your data source and refresh
153
+ myRows[rowIndex][columnId] = value;
154
+ grid.getApi().refresh();
155
+ },
156
+ });
157
+ }
158
+ ```
159
+
160
+ </TabItem>
161
+ </Tabs>
162
+
163
+ ---
164
+
165
+ ## MCP tools
166
+
167
+ Once connected, these tools are available to your AI assistant:
168
+
169
+ ### `list_grids`
170
+
171
+ Lists all OGrid instances currently connected to the bridge.
172
+
173
+ ```
174
+ > list_grids
175
+
176
+ 2 connected grid(s):
177
+
178
+ **my-grid**
179
+ Rows: 50 displayed / 1247 total
180
+ Page: 1 / 25 (50 per page)
181
+ Columns: id, name, email, department, salary
182
+ Active filters: 0
183
+ Last seen: 0s ago
184
+ ```
185
+
186
+ ### `get_grid_state`
187
+
188
+ Returns the current state of a grid: columns, pagination, sort, filters, selection, and optionally the row data.
189
+
190
+ ```
191
+ > get_grid_state gridId="my-grid" includeData=true maxRows=5
192
+
193
+ # Grid: my-grid
194
+ Last seen: 0s ago
195
+
196
+ ## Pagination
197
+ Page 1 of 25 | 50 rows displayed | 1247 total
198
+
199
+ ## Columns (5)
200
+ id (numeric), name (text), email (text), department (text), salary (numeric)
201
+
202
+ ## Sort
203
+ salary desc
204
+
205
+ ## Data (first 5 of 50 rows)
206
+ [
207
+ { "id": 1, "name": "Alice", "salary": 120000 },
208
+ ...
209
+ ]
210
+ ```
211
+
212
+ ### `send_grid_command`
213
+
214
+ Sends a command to a connected grid and waits for the result.
215
+
216
+ **Update a cell:**
217
+ ```
218
+ > send_grid_command gridId="my-grid" type="update_cell"
219
+ payload={ "rowIndex": 0, "columnId": "salary", "value": 130000 }
220
+
221
+ ✅ Command executed successfully
222
+ Type: update_cell
223
+ Payload: {"rowIndex":0,"columnId":"salary","value":130000}
224
+ ```
225
+
226
+ **Apply a filter:**
227
+ ```
228
+ > send_grid_command gridId="my-grid" type="set_filter"
229
+ payload={ "columnId": "department", "value": "Engineering" }
230
+ ```
231
+
232
+ **Clear all filters:**
233
+ ```
234
+ > send_grid_command gridId="my-grid" type="clear_filters" payload={}
235
+ ```
236
+
237
+ **Change sort:**
238
+ ```
239
+ > send_grid_command gridId="my-grid" type="set_sort"
240
+ payload={ "sortModel": [{ "columnId": "name", "direction": "asc" }] }
241
+ ```
242
+
243
+ **Navigate to page:**
244
+ ```
245
+ > send_grid_command gridId="my-grid" type="go_to_page" payload={ "page": 3 }
246
+ ```
247
+
248
+ ---
249
+
250
+ ## connectGridToBridge() options
251
+
252
+ | Option | Type | Description |
253
+ |--------|------|-------------|
254
+ | `gridId` | `string` | Unique ID shown in `list_grids` |
255
+ | `getData` | `() => unknown[]` | Returns current displayed rows |
256
+ | `getColumns` | `() => BridgeColumnInfo[]` | Returns current columns |
257
+ | `getPagination` | `() => { page, pageSize, totalCount, pageCount }` | (optional) Pagination state |
258
+ | `api` | `BridgeGridApi` | (optional) Grid API for filter/sort/page commands |
259
+ | `onCellUpdate` | `(rowIndex, columnId, value) => void` | (optional) Handle `update_cell` commands |
260
+ | `bridgeUrl` | `string` | Bridge URL (default: `http://localhost:7890`) |
261
+ | `pollIntervalMs` | `number` | Poll frequency in ms (default: `500`) |
262
+
263
+ ---
264
+
265
+ ## Example AI testing session
266
+
267
+ Here's what a typical Claude testing session looks like with the bridge active:
268
+
269
+ ```
270
+ Me: The salary column seems wrong. Can you check?
271
+
272
+ Claude: Let me look at the current grid state.
273
+ [calls get_grid_state gridId="employees" includeData=true maxRows=10]
274
+
275
+ The grid shows salary values like "120" instead of "120000".
276
+ It looks like the values are being divided by 1000 somewhere.
277
+
278
+ Let me update a cell to verify:
279
+ [calls send_grid_command type="update_cell" payload={rowIndex:0, columnId:"salary", value:120000}]
280
+ ✅ Done. Now let me re-read to confirm:
281
+ [calls get_grid_state]
282
+
283
+ The update worked. Row 0 now shows 120000. The issue is in your
284
+ valueGetter — it's dividing by 1000. Here's the fix: ...
285
+ ```
286
+
287
+ ---
288
+
289
+ ## Security note
290
+
291
+ The bridge server only listens on `127.0.0.1` (localhost) and is designed for local development only. **Never run with `--bridge` in production.** The bridge has no authentication — anyone on localhost can read your grid data and send commands.