Skip to content

Commit 33000f4

Browse files
updating docs (#161)
1 parent 295ed04 commit 33000f4

4 files changed

Lines changed: 124 additions & 18 deletions

File tree

content/agents/workspace-mcp-quickstart.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,24 @@ http://127.0.0.1:8787/mcp
6868

6969
The script installs `uv` if needed, then runs `workspace-mcp` from the OpenBB Workspace MCP source archive.
7070

71-
For advanced options (custom host/port, forks, branches, or local checkouts), see the [Workspace MCP repository](https://github.com/OpenBB-finance/workspace-mcp).
71+
### Passing options to the installer
72+
73+
The one-line installers forward any arguments after `--` straight to `workspace-mcp`, so you can set options like `--cors-allow`, `--host`, or `--port` without installing the binary separately.
74+
75+
**macOS, Linux, WSL, and Git Bash** — add `-s --` after `sh`, then the flags:
76+
77+
```bash
78+
curl -LsSf https://raw.githubusercontent.com/OpenBB-finance/workspace-mcp/main/scripts/run.sh \
79+
| sh -s -- --cors-allow https://your-origin.openbb.co
80+
```
81+
82+
**Windows PowerShell** — append the flags to the run command:
83+
84+
```powershell
85+
powershell -ExecutionPolicy Bypass -Command "Invoke-RestMethod https://raw.githubusercontent.com/OpenBB-finance/workspace-mcp/main/scripts/run.ps1 | Invoke-Expression" -- --cors-allow https://your-origin.openbb.co
86+
```
87+
88+
See the [configuration reference](#configuration-reference) for the full list of options you can pass this way. For other advanced options (forks, branches, or local checkouts), see the [Workspace MCP repository](https://github.com/OpenBB-finance/workspace-mcp).
7289

7390
## 2. Check sidecar health
7491

@@ -124,7 +141,14 @@ Open OpenBB Workspace in your browser and connect the local companion:
124141

125142
By default, the sidecar allows CORS requests from `https://pro.openbb.co` and loopback origins such as `http://localhost:1420` and `http://127.0.0.1:1420`.
126143

127-
For a different Workspace origin, pass `--cors-allow`:
144+
For a different Workspace origin, pass `--cors-allow`. If you started the sidecar with the one-line installer, forward the flag through `sh -s --`:
145+
146+
```bash
147+
curl -LsSf https://raw.githubusercontent.com/OpenBB-finance/workspace-mcp/main/scripts/run.sh \
148+
| sh -s -- --cors-allow https://example.openbb.dev
149+
```
150+
151+
If you run the binary directly, pass it the same way:
128152

129153
```bash
130154
workspace-mcp --cors-allow https://example.openbb.dev

content/workspace/developers/json-specs/apps-json-reference.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ For example:
5959
]
6060
```
6161

62+
#### Tagging widgets and tabs in prompts
63+
64+
A prompt can reference a specific widget so the agent knows exactly which data to use. Use the `@[id:WIDGET_ID]` mention syntax inside the prompt string, where `WIDGET_ID` is the backend widget's id. When the prompt is rendered in OpenBB Workspace, the mention resolves to a chip showing the widget's name (for example, `@Peer Comparison`).
65+
66+
For example, to tag a backend widget called "Peer Comparison" with the id `peer_comparison`:
67+
68+
```json
69+
"prompts": [
70+
"Compare $SYMBOL to its peers using @[id:peer_comparison] — which fundamentals stand out?"
71+
]
72+
```
73+
74+
When rendered, `@[id:peer_comparison]` resolves to a `@Peer Comparison` chip. If the referenced widget is not available — for example, the backend is not connected — the mention falls through and displays as the raw `@[id:...]` string.
75+
6276
Each MCP server entry contains:
6377
- `name`: Display name for the MCP server
6478
- `description`: Short description of what the server provides

content/workspace/developers/widget-types/html.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ import HeadTitle from '@site/src/components/General/HeadTitle.tsx';
1919

2020
<HeadTitle title="HTML | OpenBB Workspace Docs" />
2121

22-
HTML widgets provide control over visualization design through server-rendered HTML, enabling the creation of custom styled dashboards and data displays.
22+
HTML widgets provide control over visualization design through server-rendered HTML, enabling the creation of custom styled dashboards and data displays.
2323

24-
:::warning Security Note
25-
HTML widgets render static HTML content only. JavaScript code within the HTML will not be executed for security reasons. All interactivity must be achieved through server-side logic and HTML/CSS features only.
24+
JavaScript inside the returned HTML **does execute**, so you can build interactive controls — buttons, inputs, event handlers — directly in the widget. To push a parameter value from an HtmlViewer widget back to Workspace (for example, to drive other widgets on the dashboard), dispatch a `CustomEvent` and let the injected bridge forward it; see [Pushing parameters back to Workspace](./iframe#pushing-parameters-back-to-workspace).
25+
26+
:::note
27+
Treat HTML widgets like any other code you run: only render markup and scripts you trust. The page runs in the embedded context, so avoid injecting unsanitized third-party content into the HTML you return.
2628
:::
2729

2830
<img className="pro-border-gradient" width="800" alt="HTML Widget Example" src="https://openbb-cms.directus.app/assets/8234f346-6b2e-49b2-b5de-7150c770a756.png" />
@@ -211,13 +213,11 @@ def html_widget():
211213
<button class="button" onclick="alert('Refreshing data...')">Refresh Dashboard</button>
212214
</div>
213215
</div>
214-
215-
<!-- Note: JavaScript will not execute in HTML widgets for security reasons -->
216-
<!-- This script tag is included only as an example - it will not run -->
216+
217217
<script>
218-
// This JavaScript code will NOT execute
219-
// HTML widgets only render static HTML and CSS
220-
// All dynamic behavior must be implemented server-side
218+
// JavaScript inside an HTML widget executes, so event handlers like the
219+
// onclick above run as written. You can also dispatch the parameter-bridge
220+
// CustomEvent here to push values back to Workspace.
221221
</script>
222222
</body>
223223
</html>
@@ -230,18 +230,18 @@ The gridData parameter specifies the widget's size in the OpenBB Workspace grid
230230

231231
**Complete Design Control**: HTML widgets allow extensive customization through HTML markup and inline CSS styling, enabling the creation of professional-grade interfaces that match your organization's branding and design requirements.
232232

233-
**Server-Side Rendering**: All content is generated server-side, ensuring security while allowing dynamic HTML generation based on real-time data, calculations, and API responses from your backend.
233+
**Server-Side Rendering**: Content is generated server-side, allowing dynamic HTML generation based on real-time data, calculations, and API responses from your backend.
234+
235+
**Client-Side Interactivity**: JavaScript in the returned HTML executes, so you can add event handlers, build interactive controls, and push parameter updates back to Workspace through the [parameter bridge](./iframe#pushing-parameters-back-to-workspace).
234236

235237
**Rich Styling Options**: Leverage the full power of inline CSS for advanced styling including animations, gradients, responsive layouts, and professional visual design that creates engaging dashboard experiences.
236238

237-
**Data Integration**: Generate HTML content dynamically on the server based on live data sources, enabling real-time portfolio monitoring, market data display, and dynamic performance tracking through server-side updates.
239+
**Data Integration**: Generate HTML content dynamically on the server based on live data sources, enabling real-time portfolio monitoring, market data display, and dynamic performance tracking.
238240

239241
## Best Practices
240242

241243
- Use semantic HTML structure for accessibility and maintainability
242244
- Implement responsive design patterns using CSS flexbox and grid layouts
243-
- Generate all dynamic content server-side before returning the HTML response
244-
- Use CSS animations and transitions for visual effects instead of JavaScript
245-
- Handle all data fetching and processing in the Python backend before rendering
246-
- Consider using HTML forms with server endpoints for user interactions
247-
- Refresh widgets periodically to update data rather than relying on client-side updates
245+
- Generate data-heavy content server-side before returning the HTML response, and use client-side JavaScript for interactivity
246+
- Only render markup and scripts you trust; avoid injecting unsanitized third-party content into the returned HTML
247+
- Use the [parameter bridge](./iframe#pushing-parameters-back-to-workspace) to drive other dashboard widgets from a control in the widget

content/workspace/developers/widget-types/iframe.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,74 @@ The bridge below is the complete client side of the protocol — announce on loa
188188
})();
189189
```
190190

191+
## Pushing parameters back to Workspace
192+
193+
The protocol messages above cover the **inbound** direction — Workspace pushing parameter values *into* the iframe with `openbb-params-update`. The parameter bridge is the **outbound** direction: a widget pushes a new parameter value *back to* Workspace. Workspace persists the update and re-sends it to every widget [grouped](../json-specs/apps-json-reference) on that parameter, so one widget can drive the rest of the dashboard.
194+
195+
This lets you build interactive controls — a ticker selector, a date picker, a set of buttons — inside a widget and have the rest of the dashboard react to them.
196+
197+
### The update message
198+
199+
Send an `openbb:widget-params:update` message. Either update all params at once:
200+
201+
```js
202+
{ type: "openbb:widget-params:update", params: { ticker: "NVDA" } }
203+
```
204+
205+
…or a single named param:
206+
207+
```js
208+
{ type: "openbb:widget-params:update", paramName: "ticker", value: "NVDA" }
209+
```
210+
211+
For the update to propagate, the receiving widgets must share the same `paramName` and be in the same group. In `apps.json`, group the widgets with a `param` group on that parameter:
212+
213+
```json
214+
"groups": [
215+
{
216+
"name": "Group 1",
217+
"type": "param",
218+
"paramName": "ticker",
219+
"widgetIds": ["mock_quote", "bridge_iframe"],
220+
"defaultValue": "AAPL"
221+
}
222+
]
223+
```
224+
225+
### Sending the message: iframe vs. HtmlViewer
226+
227+
How you send the message depends on the widget type, because the two forward it differently:
228+
229+
- **`iframe`** — the embedded page posts the message **directly** to the parent with `window.parent.postMessage(...)`.
230+
- **`html` (HtmlViewer)** — the page dispatches a **`CustomEvent`**; the bridge script Workspace injects into the HtmlViewer forwards it for you. The page must **not** `postMessage` itself.
231+
232+
**Iframe widget** — post the update straight to the parent window:
233+
234+
```js
235+
function pick(ticker) {
236+
const msg = { type: "openbb:widget-params:update", params: { ticker } };
237+
(window.top || window.parent).postMessage(msg, "*");
238+
}
239+
```
240+
241+
**HtmlViewer widget** — dispatch a `CustomEvent` and let the injected bridge forward it (with the security token). Do not call `postMessage` directly:
242+
243+
```js
244+
function pick(ticker) {
245+
window.dispatchEvent(new CustomEvent("openbb:widget-params:update", {
246+
detail: { type: "openbb:widget-params:update", params: { ticker } }
247+
}));
248+
}
249+
```
250+
251+
After Workspace persists the update, it re-sends the new value to every widget in the group, which then re-fetch with the new parameter — the full round-trip from one widget's button click to the whole group updating.
252+
253+
:::note
254+
The HtmlViewer (`type: "html"`) outbound bridge relies on the page's JavaScript running so it can dispatch the `CustomEvent`. JavaScript in an [HTML widget](./html) executes, so the page's event handlers run as written.
255+
:::
256+
257+
A complete working backend showing both paths (mock data, no API keys) is in the [iframe parameter bridge example](https://github.com/OpenBB-finance/backends-for-openbb/tree/main/widget-examples/iframe-bridge-example).
258+
191259
## Auto-connecting an MCP server
192260

193261
Set `storage.mcpUrl` in the widget definition to attach an MCP server automatically when the iframe mounts. Its tools become available to Copilot with no manual setup:

0 commit comments

Comments
 (0)