What a plug-in can do
Everything a plug-in does goes through the contract, IStudioPlugin and IStudioHost. This page is what contract 1.2, OpenBI Studio 0.3.74’s (it came with 0.3.73), gives; the API reference has every member.
Agent tools
A plug-in’s AgentTools are classes of MCP tools: ModelContextProtocol’s [McpServerToolType] classes, with [McpServerTool] methods and [Description] on the methods and their parameters.
- The studio makes each class with its services: ask for
IStudioHostin its constructor, and for what yourConfigureServicesadds. - While the plug-in is on, its tools join the studio’s agent endpoint, for every agent that connects (see How agents work with OpenBI). Turning a plug-in on or off restarts the endpoint, and agents connect again.
- They share one list with the studio’s tools: name them with a prefix of your own.
AgentInstructionstells agents about them. Its first sentences, about 320 characters, join the studio’s briefing; the whole text is in the guide for agents, underplugin/and the plug-in’s name.- Their calls are the agent’s: windows they open don’t take the developer’s keyboard, and a failed call shows in the Activity panel with why. Write your own lines there with
Log(…, byAgent: true).
The open model
HasProject,ProjectName,ProjectFolder,ProjectChanged- Whether a project is open, which, where; the event says a project was opened or closed, or its model loaded again.
Tables- The model’s tables, each with its columns, its measures’ names and their details (OAX, format, display folder, description), its rows (or “live”).
DaxAsync(dax)- An OAX query on the open model, as the developer: all its data, no role applied. The method keeps DAX in its name: OAX, OpenBI’s expression language, is compatible with DAX, so a query written for Power BI runs as it is. Its rows come back as JSON values (
QueryResult.Textgives one as text). ShowDax(dax),ShowView(view)- Shows a query in the OAX view and runs it; shows one of the studio’s views (
report,tables,model,dax,prediction,operations-research,quantitative,networks,versions), asks for a project (open-project,import-powerbi), or moves the tab in front into a window of its own (new-window).
A data plug-in’s tables and sign-ins
Added in contract 1.1 (OpenBI Studio 0.3.67), for a plug-in that brings a system’s data into the open project:
ReloadModelAsync(refresh)- The plug-in writes its files into the project, tables as M queries, measures, relationships (with
OpenBI.Studio.Core’sStudioProject) and report pages in its reports folder; then the studio reads the model again and loads its data. Withrefresh, every table is read from its source again; without, a table whose definition did not change keeps its rows. SetSourceCredentialAsync(address, auth, user, secret)- Keeps a source’s sign-in in the user’s credential store, sealed for them (DPAPI on Windows, the keychain on a Mac), as the developer’s own sign-ins are: the model’s queries reach the source without the secret in the model, its M, the project or the logs.
auth:key(a header and its value,Authorizationunless named),passwordoranonymous. HasSourceCredentialAsync(address),RemoveSourceCredentialAsync(address)- Whether there is a sign-in for the address (its secret is never given out); remove it. The studio’s Data sources window changes or removes it too.
A plug-in can’t add OAX or M functions of its own: its tables come in through the M the studio already runs.
Tabs
Each PluginView in Views is a tab under SPECIALTY: its Id, Title, Glyph, ToolTip, and Create, which makes its view once, the first time it is shown. The view is kept while the studio runs, and the tab can move to a window of its own on another screen. With NeedsProject, the tab is off until a project is open.
- The Windows studio shows a WPF
FrameworkElement; the Mac studio an AvaloniaControl. A view of the wrong kind shows a note instead. ShowPluginView(pluginId, viewId)brings one of your tabs to the front;MainWindowis the owner for your dialogs (a WPF window on Windows, an Avalonia one on a Mac).InvokeAsyncruns work on the studio’s UI thread and waits;Postruns it later.
Settings and secrets
Storage(pluginId) keeps a plug-in’s settings and secrets on this computer, beside the studio’s settings, never in a project:
Load<T>(name)andSave<T>(name, value): settings, as JSON.Secret(key)andSetSecret(key, value): secrets, encrypted for the user (nullremoves one).
Removing a plug-in leaves them: installed again, it finds them.
Microsoft sign-in
MicrosoftTokenAsync(scopes, interactive, …) gives an access token for Microsoft Graph or another Microsoft service: quietly when it can, else, when interactive, with Microsoft’s sign-in window. Name an Entra application of your own with clientId, or leave it to the studio; authority is organizations, consumers or common.
Privacy
Privacy- Whether personal data is protected from agents:
off,identifiers(OpenBI’s own detectors) orpresidio(those and Presidio’s), and whether your organization’s policy enforces it. NewPseudonymizer()- A pseudonymizer with the detectors the settings name:
AnonymizeAsyncturns personal data in a text into numbered tokens (<PERSON_1>), the same value always the same token;Restoreputs the values back into a text or a tool call’s JSON arguments. Its table of tokens stays in memory. SetPrivacy(mode, presidioUrl, language)- Sets the studio’s privacy, unless the policy imposes it (then
false).
The pseudonymizer works on what your plug-in hands an agent. The studio’s own tools answer with the model’s data as it is (see Privacy).
The studio
Log(title, detail, error, byAgent)- A line in the Activity panel, the developer’s or (
byAgent) done for an agent. SetStatus(text),StudioVersion- The status bar’s text; the studio’s version.
Agent- The studio’s MCP endpoint: its address, whether it listens, and the settings that connect an agent (Claude Code’s command, any client’s JSON), which hold no key. Its
Keyis empty: the studio’s agent key is the person’s, for the agents they connect, never a plug-in’s.
Calling the agent endpoint
Most plug-ins never call the studio’s agent endpoint themselves: their tools are called by the agent the person connects, and Agent.ClaudeCommand shows how to connect one. A plug-in that starts an agent of its own, or calls the studio’s tools itself, asks for a key of its own (contract 1.2):
- It says so in
plugin.json:"agentAccess": { "reason": "…", "tools": ["studio_status", "model_measures", "dax_query"] }, naming only the tools it needs (none named: every tool). - It asks with the host
Initializegave it:RequestAgentAccessAsync(). The first time, the studio asks the person, with the reason and the tools, and remembers the answer for that version of the plug-in; a new version, or a changedagentAccess, asks again.RequestAgentAccessAsync(ask: false)never asks. - Allowed, it gets
PluginAgentAccess: the endpoint’s address, a key of its own (send it asAuthorization: Bearer; never show it or write it to a file), the tools it may call, an MCP client’s settings for an agent it starts, andRevoked. Not declared, refused, or turned off by IT:null.
The key lives in memory while the studio runs and the plug-in is on. The endpoint takes it for the named tools only (tools/list shows only those; another answers tool_not_allowed), and the Activity panel names the plug-in for each call. The person withdraws it in Specialty modules: from the next request the endpoint refuses the key and Revoked is cancelled, as it is when the plug-in is turned off or removed. IT can keep every plug-in from a key of its own (DisablePluginAgentAccess, see Your organization’s policy).
What a plug-in doesn’t do
- Run in OpenBI Server: plug-ins are OpenBI Studio’s.
- Add OAX or M functions, ribbon commands or views other than its tabs.
- Run in a sandbox: it has the user’s rights, which is why the studio checks its signature, on Windows and on a Mac (see Signing).
- Get the studio’s agent key: a plug-in that calls the endpoint asks for a key of its own (see Calling the agent endpoint).