Skip to main content
This App Showcase post is an AI-generated test blog for evaluating quickstart candidates; treat it as draft application guidance, not final product documentation or financial advice.
AI-generated test blog - HeavenBase Team - June 23, 2026 - ~1,250 words - ~7 min read
Some useful apps begin as a simple board. You have a few rows, a few numbers, and one question you want answered without opening a spreadsheet every time. Portfolio Risk Board is a small HeavenBase tutorial for that pattern. The example uses sample portfolio data, but the lesson is broader: store facts, compute one helpful value, query the rows that need attention, and export the board for an agent client.

1. Background and Goal

This is not an investment model. The goal is to show a local planning board with enough structure to answer simple questions. If you are not familiar with portfolios, read “position” as “one item I hold” and “exposure” as “how much that item is worth in this sample.” The tutorial builds a board that can:
  • store a few positions
  • compute exposure from shares and price
  • store plain-language scenario notes
  • show positions with higher review risk
  • generate MCP JSON so an agent client can inspect the same workspace
The result is intentionally modest. A first useful app should help you act before it tries to become a full platform.

2. Scenario and Setting

We will use a fictional person named Alex. Alex has three rows: cash, a growth equity position, and a bond position. Alex also writes two scenario notes: what to do if rates stay high, and what to do if cash is needed.
ItemPlain MeaningWhy It Is in the Demo
CASHA cash bucket.It keeps the example grounded.
GROA sample growth holding.It has the highest review risk.
BNDA sample bond holding.It gives the board a lower-risk comparison.
The app should answer two questions: “What needs review?” and “What does the whole board currently represent?”
The sample tickers and numbers are fake workflow data. Do not treat this tutorial as financial advice.

3. Step 1: Open the Workspace

The community example uses the same local workspace helper as the other App Showcase demos.
import heavenbase as hb

from community_runtime import demo_workspace, parse_reset, print_frame, seed

WS_ID = "community-app-portfolio-risk-board"

ws, _ = demo_workspace(WS_ID, "apps-portfolio-risk-board", parse_reset())
ws.enable_extension("agent")
The agent extension is enabled because the final step exports an agent-facing configuration. The app still starts as ordinary typed data.

4. Step 2: Define Positions and Scenarios

First define a tiny compute function. In this demo, exposure means shares * price.
def exposure(shares: float | None, price: float | None) -> float:
    return float(shares or 0.0) * float(price or 0.0)


class Position(hb.Entity):
    """Portfolio position."""

    ticker = hb.field(hb.ShortText).desc("Ticker")
    asset_class = hb.field(hb.ShortText).desc("Asset class")
    shares = hb.field(hb.Float).desc("Units")
    price = hb.field(hb.Float).desc("Price per unit")
    risk = hb.field(hb.Integer).desc("1 is defensive, 5 is speculative")
    exposure = hb.field(hb.Float).compute(exposure, inputs=["shares", "price"])


class Scenario(hb.Entity):
    """Stress scenario note."""

    name = hb.field(hb.ShortText).desc("Scenario name")
    assumption = hb.field(hb.LongText).desc("Assumption")
    action = hb.field(hb.LongText).desc("Planned action")
This is the key HeavenBase idea in the tutorial: a row can contain facts you type in and facts the app computes for you.

5. Step 3: Add Sample Rows

Register the two card types and add three positions plus two scenario notes.
ws.register(Position)
ws.register(Scenario)

seed(
    ws,
    Position,
    [
        {"object_id": "cash", "ticker": "CASH", "asset_class": "cash", "shares": 12000.0, "price": 1.0, "risk": 1},
        {"object_id": "growth", "ticker": "GRO", "asset_class": "equity", "shares": 80.0, "price": 72.0, "risk": 4},
        {"object_id": "bond", "ticker": "BND", "asset_class": "bond", "shares": 50.0, "price": 91.0, "risk": 2},
    ],
)
seed(
    ws,
    Scenario,
    [
        {"object_id": "rate-shock", "name": "Rate shock", "assumption": "Rates stay higher for two quarters.", "action": "Do not add duration until allocation review."},
        {"object_id": "cash-need", "name": "Cash need", "assumption": "Unexpected 5000 expense.", "action": "Use cash bucket first."},
    ],
)
You do not enter exposure by hand. HeavenBase computes it from shares and price when the row is written.

6. Step 4: Ask What Needs Review

Now query positions with review risk 3 or higher, and calculate the total exposure from the stored rows.
risky = (
    ws.query(Position)
    .where(Position.risk >= 3)
    .select("ticker", "asset_class", "exposure", "risk")
    .execute()
)

total = round(sum(row["exposure"] for row in ws.rows(Position)), 2)
The output is small enough to read at a glance:
Higher-risk exposure
object_id | ticker | asset_class | exposure | risk
--------------------------------------------------
'growth' | 'GRO' | 'equity' | 5760.0 | 4
Total exposure: 22310.0
The useful part is not the specific number. The useful part is the pattern: compute a value once, then query it like any other field.

7. Step 5: Export the Board to an Agent Client

The last step asks HeavenBase for MCP client JSON. This gives another tool, such as an agent harness, a way to connect to the same workspace.
config_json = ws.to_mcp_json(
    name="portfolio-board",
    profile="agent",
    host="127.0.0.1",
    port=7040,
)
print(config_json.splitlines()[0])
In a real app, you would pair this with a narrower profile and a careful prompt. For this prototype, the important point is that the board does not need to be rebuilt for agent access.
A successful run shows the higher-risk row, prints total exposure, and emits the first line of an MCP JSON configuration.

8. What This Teaches

Portfolio Risk Board is useful as a quickstart candidate because it shows a non-chat workflow. HeavenBase is not only for agent conversations; it can also hold everyday structured data and computed fields. The next version could add allocation targets, review dates, scenario tags, or a read-only agent profile that can explain the board without editing rows.

Try It

From the community examples checkout, run:
rtk bash scripts/run.bash apps.portfolio_risk_board
Treat the numbers as sample data. The reusable pattern is computed operational state plus a scoped path to agent access.

Further Exploration

Related resources:
  • Entities - Use compute Hooks for derived fields
  • Workspace - Keep app rows and agent access in one boundary
  • Query - Filter rows and inspect result frames
  • Routing - Move fields to richer backends when needed
  • HeavenBase MCP - Generate and serve agent-facing tool configs