AI Quickstart

This walkthrough takes you from an empty folder to a running portal where customers sign in and work with their own support cases — by asking an AI coding agent rather than writing it by hand. Each step gives you a prompt to paste, what the agent will do with it, and what to check before you move on. The example uses the Case table (incident) that comes with Dynamics 365 Customer Service; with a table of your own, every prompt works the same way.

Before you start

  • The .NET 10 SDK, and Node.js if you choose the React template.
  • A Dataverse environment in which you are a System Administrator. Use a development or sandbox environment for this walkthrough.
  • Permission to create app registrations in that environment's Entra tenant.
  • An address for the portal's email — registration confirmations and password resets — with a shared mailbox for it in Exchange Online, which needs no licence. Approving the address takes an Office 365 Global Administrator or Exchange Administrator.
  • An AI coding agent that supports MCP. The commands below are for Claude Code; the MCP Server page has the configuration for Visual Studio, VS Code and Cursor.

How this works

Two things let an agent get this right rather than merely plausible: the Power Portals Pro MCP server, which reads your actual Dataverse environment and makes the configuration changes a portal needs, and the instructions every generated project ships for agents.

1. Install the MCP server

Install it once per machine, at user scope, so it is available in every folder — including the empty one you are about to create the project in:

dnx ships with the .NET 10 SDK. Restart your agent if it was already running, then check the server is there by asking something only it can answer, such as "use get_component_api to list MainGrid's parameters".

2. Make a folder and sign in

Create the folder your portal will live in, and sign in from inside it — once to your Dataverse environment, and once to Azure, which is what the app registrations in step 4 are created through:

Both sign-ins belong to this folder, not to the machine. They write .ppp/mcp.json here, naming the environment and the tenant, and keep your tokens in your user profile, so a project in another folder can point at another customer at the same time. Both use a device code, so you can finish them on your phone. If your account sees several Azure subscriptions you don't need to choose one yet — that only matters once you deploy. Then start your agent in this folder.

3. Create the project

Tell the agent what you are building — which stack, React or Blazor, and who will sign in:

The agent installs the project templates if they are missing, asks about anything it cannot tell from your request, and runs dotnet new. Each customer becomes a contact in Dataverse, and what they may see is decided by the security registrations in the project's Program.cs. That is the template's default security model, and the one the rest of this walkthrough uses. Either stack works; every later prompt is the same.

Note

Restart your agent in the same folder once the project exists. The project brings its own .mcp.json, which pins the MCP server to the version that matches its packages, along with its skills and AGENTS.md — and most agents only read those when they start. Approve the project's MCP server if your agent asks.

4. Connect it to Dataverse

A new project will not start until it can reach Dataverse. Ask the agent to set that up:

The agent follows the project's set-up-portal skill, starting with check_setup to see what is missing. Expect to approve each of these:

The connection settings land in the project's user secrets as each step completes. The agent finishes by running check_setup again; once that is clean, run the project — F5, or dotnet run in the server project — and you will see the template's home page and sample pages.

5. Decide what customers should see

Describe the outcome you want in business terms, and let the agent find the table. Asking before anything is written is worth it: the agent reads your environment, so it suggests what is actually there, your own custom tables and columns included.

Expect it to look the table up with list_tables and describe_table, read its views with list_views, and come back with the Case table (incident), the lookup that ties a case to its customer (customerid), and the columns to show and to edit. Adjust that list now: it decides what the portal publishes.

6. Secure the table

A portal shows nothing it has not been told to show: until a table is registered, its pages return 403 or an empty grid. Ask the agent to open the table up — only as far as you mean to:

The agent works through the project's secure-a-table skill, confirming who the access is for, which rows, which operations and which columns. Don't skip any of them: each answer changes what is published.

Then it writes the registration in the server project's Program.cs. For this example, expect something like:

RowsOwnedByContact("customerid") limits every query to the signed-in contact's own cases, and makes them the customer on a case they create. Columns are opt-in: anything not named in Reading is withheld, and only the columns in Writing can be changed. WritingOnCreate covers the priority — set when the case is logged, read-only from then on. Security covers every option.

The application user's own role

The registration decides what each customer may do, but the portal still talks to Dataverse as its application user, and that user needs privileges on the table itself. They go in the security role of your own from step 4, never in the Power Portals Pro role. The agent:

  1. Finds your role on the application user with get_application_user — and if step 4 didn't make one, creates it with create_security_role and assigns it with assign_application_user_role.
  2. Grants it what the registration needs with add_table_privileges_to_role: Read, Create, Write and Append on incident, and Append To on contact, because every new case is linked to a contact. Then it runs check_setup, which compares the tables your pages use with the tables your code registers.

Why a role of your own?

The Power Portals Pro role ships in a managed solution. Dataverse would let you add privileges to it, but the next upgrade of that solution can put it back the way it shipped, taking your grants with it — so the MCP server refuses to add privileges to any managed role. A role of your own also shows anyone reviewing the environment later exactly what the portal can reach.

7. Add the pages

With the table secured, ask for both pages in one go — the list in the menu, and the page a case opens in:

The agent follows the project's add-table-pages skill. It adds the routes, a list page with a MainGrid, the menu entry and a RecordContext page that also opens empty for logging a new case. It reads real view ids with list_views rather than writing placeholders, and keeps every column within what the registration lets customers read — the stock Dynamics views include agent-only columns, so expect it to offer views of its own. If you ask for a column the registration leaves out, it should stop and ask rather than quietly widen access. Related records can go on the case page as subgrids; name them, and it will secure that table too.

8. Try it as two customers

The agent cannot sign in as a customer, so this part is yours. It is also the test that matters most: the point of the registration is what one customer cannot see.

  1. Run the portal and register a customer. The confirmation email arrives once the email queue's mailbox has passed Test & Enable in step 4.
  2. Open Cases, log a new case, then open it again from the grid. Change its title and save.
  3. Sign out, register a second customer and open Cases. The grid should be empty: the first customer's case is theirs alone. Pasting the address of that case into this session should not show it either.

If either customer sees something they shouldn't, don't adjust it by hand. Tell the agent what you saw and what you expected, and let it work through secure-a-table again.

If something doesn't look right

Where to go next