# MuniPro banker presentation guide

Status: Active

This guide mirrors the packaged `create-banker-presentation` skill.
Use it in the native assistant or an authorized host with presentation tooling.

# Create Banker Presentation

Produce a presentation that preserves the firm's reference master, layouts,
fonts, colors, logos, page numbering and disclosures. Use the host's available
presentation tools and follow their rendering/inspection workflow.
Read the [banker protocol](#banker-reference-0) and
[template bindings](#banker-reference-2) for retrieval, citations,
reusable-template mode, named slots and completion evidence.

1. Establish the issuer, as-of date, fiscal year end and slide selection. Get
   the firm's reference PPTX or an authorized existing template; do not infer
   a firm's branding or silently substitute a generic deck.
2. Call `get_current_munipro_context`. Read the actual tool/profile availability.
   The initial banker profile grants debt datasets, files and document lists.
   It does not grant every source required by the 16 recipes.
3. Resolve the issuer using `list_verified_borrowers`, following all needed
   pages. Obtain datasets with `get_debt_details_dataset`; poll
   `get_job_status`, then use returned structured data/result pages or the
   authenticated API download through an authorized client. Never ask the
   user to paste a bearer token into chat. Retrieve relevant source workbooks
   with `list_issuer_files` and `get_issuer_file_download` when available.
4. Read [recipes.md](#banker-reference-1) for slide-specific inputs and
   formulas. Use the published `/static/mcp/banker-data-guide.md` for field
   semantics. Preserve non-CUSIP securities by stored security ID and retain
   canonical issuer citations with returned series/security identifiers. Choose either leaf
   rows or a single aggregation level, never both. Preserve unknown values.
5. Bind each slide to a template layout and dataset. For missing inputs or
   unsupported capabilities, leave a clearly labelled unpopulated slot or
   omit it with the user's requested scope in mind. Never render invented
   trades, holders, market dates, financing savings or liquidity commitments.
6. Create editable tables/charts where supported. Add as-of date, source,
   units, filters, projection basis and modeling assumptions in notes or the
   firm's source footer. Keep a provenance manifest alongside the deck.
7. Reconcile displayed totals to source totals. Render and inspect every
   slide for clipping, typography, legends, footnotes and reference-template
   fidelity. A PPTX is complete only after rendering succeeds. If this host
   cannot render presentations, deliver an explicitly labelled data/binding
   packet, not a claim that a deck was generated.

For reusable template creation, preserve the reference deck and create a new
copy with named table/chart/text slots and a binding manifest. Remove sample
issuer data from reusable slots. Keep required firm disclaimers. Do not
upload a private template to an external service without authorization.

Financial calculations come from reviewed MuniPro models. Market observations
and scenario outputs are distinct; state timestamps and assumptions. A sample
financing is illustrative and requires banker review before client use.


---

<a id="banker-reference-0"></a>

# Shared banker execution protocol

Status: Active

Use this protocol for banker briefs, source packs, coverage requests, firm
presentations and tie-outs of them. It supplements the live tool schemas; it
grants no access.

## Discovery and identity

Connect to `https://munipro.com/mcp` through the host's authenticated MCP
connector. Follow all `tools/list` cursors. An assigned banker profile admits
at most eleven tools; current permissions can narrow it. Inspect live schemas.
Start with `get_current_munipro_context(detail="summary")`. A skill catalog is
instruction metadata, never proof of data access or a new tool grant.

Resolve issuer names with `list_verified_borrowers`; follow pagination for a
complete requested list. `issuer_id` is MuniPro Borrower ID. Company, credit,
Issue and CUSIP IDs cannot substitute for it. Preserve `(issuer_id, security_id)`
for each stored security, including blank/null CUSIPs. Never deduplicate by
CUSIP, name, coupon or maturity. `issue_id` / `series_id` identify stored series
within the borrower/workspace; retain `entity_key` only at its documented scope.

Use returned IDs and references instead of constructing record or page refs.
Borrower list rows are compact: `entry_actions` contains stable string keys
into response `row_actions`. Expand only a selected template with the row's
`action_arguments`: resolve `{"$row": "borrower_id"}` to the typed value;
in strings replace literal `{borrower_id}` with its value. Bind
`row_ref_templates` and `row_human_pages` the same way; `row_ref_aliases` maps
former row `*_ref` fields to template keys. Rows retain identity and minimal
direct refs. Leave other placeholders unresolved and inspect availability and
scopes before calling. Pages remain capped at 25; follow `refs.next_page` until
`complete` for a full requested list.
Dense exports may require disjoint selected-security partitions. Do not combine
nonempty `cusips` with ID/key selectors or combine `allBorrowerSecurities: true`
with explicit selections. `securityIds` select calculations; outstanding rows
have their own issuer-wide/display selection. Carry `selection` metadata.

## Finish results before using them

For each `tools/call`, distinguish transport/MCP failure, the advertised output
envelope, application outcome and async job state. Prefer structured content;
if a host exposes only JSON text, parse that defined payload once. Never confuse
a copied JSON string with a successful structured tool response.

1. `get_debt_details_dataset` queues work. Record its exact `mcp-job://` ref.
2. Poll `get_job_status` through the host's bounded job scheduler. Stop on
   failed/cancelled, denied access, expiry or the user's cancellation. Queued
   and running states are not results. Use host backoff; never issue a hot loop.
3. On done, inspect `result_outcome`; tool status `ok` does not by itself prove
   job success. Recheck notices/warnings and distinguish computation from
   source freshness.
4. If `result_paged`, read the manifest and fetch the `s000` root initializer
   first through `fetch`. Apply its ordered structural operations. For targeted
   questions, fetch the relevant section and its declared page count; follow
   required provenance/notice companion references. To reconstruct a complete
   export or a `path=[]` object-group result, traverse every required global
   page. Do not concatenate page payloads as complete JSON documents.
5. Require manifest/poll outcome consistency, declared counts and provided
   integrity metadata. Follow the maintained result-page protocol in
   [banker API guide](https://munipro.com/static/mcp/banker-integration-guide.md).
   Results expire after 48 hours. Reauthorization can refuse retained results.
6. Retrieve the actual dataset artifact from its returned `api_download.url`
   when supplied. A locator, manifest or paged stub is not the artifact bytes.

The nine banker HTTP routes have no result-page fetch endpoint. An HTTP-only
adapter needs MCP `fetch` for those pages, or must request a smaller result.
Cancel only after an explicit user request and only the exact owned queued job;
`cancel_job` cannot force-stop running/finished work. An approval ID is not a job.

## Authenticated files

The banker HTTP routes under `https://munipro.com/api/assistant/v1/banker/`
accept the current MCP bearer in `Authorization`. Browser cookies alone do not
authorize them. Other browser XHR, Assistant service API and older REST APIs
retain their own authentication; do not send the MCP bearer to them.

- **Dataset JSON:** complete the job/result flow and use its exact artifact
  download locator, checking the returned size/hash when supplied.
- **Uploaded file:** use `list_issuer_files` and `get_issuer_file_download`.
  Current selection/access are rechecked. There is no assumed PDF-style expiry
  or independent digest contract; calculate and label a local hash if needed.
- **Debt-document PDF:** follow every `next_offset` from
  `list_issuer_debt_documents`. Use the exact MuniPro `download_url` only when
  `download_authentication` is `munipro_oauth_bearer`. Retain the public EMMA
  `source_url` as provenance. The locator lasts 24 hours; re-list after 410.
  Use the response's SHA-256 `ETag` when provided.

Parse the URL and require the exact origin `https://munipro.com` before attaching
the bearer. Do not forward it across redirects or send it to EMMA. Keep tokens
out of prompts, URLs, logs, skill files, manifests and generated documents.
MuniPro handles EMMA PDF retrieval through its established aiohttp proxy/cache;
these skills do not introduce a direct EMMA HTTP client.

Keep authentication, expiry, missing content and indexing coverage distinct.
Without a usable CUSIP, the EMMA index can be absent even when debt and uploaded
files exist. Empty indexed results do not prove no legal documents exist.

## Auditable answers

Use the returned absolute `citation.url` and preserve `?view=canonical`.
The URL opens current authorized MuniPro data, not a historical snapshot. Keep
source exports and hashes for dated assertions. Browser login and MCP OAuth
are separate: a reader may need to sign in. Do not insert tokens into citations.

Pair the issuer citation with returned series designation/ID and security IDs
for row-level audit. Do not fabricate a series-row permalink. A client-created
source ID should bind borrower/workspace, record identity and retained artifact
hash, rather than relying on CUSIP. Label it as a client ID, not a MuniPro ID.

If Rogo supports native source registration, pass the title, URL, IDs, excerpt
and artifact reference through its supported mechanism. That mechanism must
be supplied/verified by Rogo; no specific Rogo endpoint is assumed here.
Record `native_registered`, `link_only` or `pending` based on observed behavior.
An ordinary clickable URL does not establish a Rogo citation pill/source panel.

Preserve source scope, fiscal/as-of basis, parameters, units, unknown values,
warnings and the returned professional-use notice. Verify totals at one grain;
never add parent subtotals and leaves, or treat swap notional as bond principal.

## Approval and output states

`request_borrower_verification` prepares a company-bound human approval.
Present the returned review link; do not click/submit the approval on the user's
behalf as part of this skill. HTTP 400 with `approval_required` can be expected.
Never label a preview, opened page, OAuth consent or queued staff request as
verified/published debt. There is no banker approval polling/callback contract.

Use honest client workflow states: `complete`, `partial`, `needs_input`,
`awaiting_approval`, `blocked` or `failed`. These are adapter states, distinct
from server HTTP statuses, MCP envelopes, jobs and staff verification. The
Rogo adapter guide defines a client-created result schema for these outputs.


---

<a id="banker-reference-1"></a>

# Banker slide recipes

Status: Active

Initial banker access supplies the first four recipes directly. Recipe 5 has
chart overlays but needs instrument/facility details for a complete liquidity
wall. Recipes 6–16 require additional authorized sources. A recipe's presence
never adds tools to the banker profile.

| # | Slide | Required source and construction | Review requirement |
|---|---|---|---|
| 1 | Outstanding debt by credit | `outstanding.rows`; select security leaves, group by `credit`, sum outstanding par; optionally show issued/retired/callable par with their fact basis. | Exclude group subtotal rows. Swaps are not principal. Match the returned as-of basis. |
| 2 | Outstanding debt service by credit | `annualChart.groups.credit`; x=`periods`, y=`fy_ds_<period>`; stack credit series. Use P&I prefixes for split bars. | Fiscal years use the requested fiscal year end. Do not add credit and series aggregates together. |
| 3 | Callable bonds by credit | Outstanding security leaves; follow callable-chart eligibility, variable-rate exclusion and annual/continuous call-date buckets; sum outstanding par by credit and bucket. | Preserve the UI's default VRDB exclusion and any 90-day date shift. Distinguish callable outstanding from a current refunding valuation. |
| 4 | Callable bonds by coupon | Same eligible leaves and call buckets; group displayed percentage coupon to three decimals (`C_5_000` means 5.000%). | Coupon is not yield or spread. Missing coupon stays unknown. |
| 5 | Variable debt liquidity wall | Variable overlays plus facility/instrument liquidity timeline, commitment expiry, put dates, outstanding draws and assumed rates. | Overlay bars alone do not prove facility expiry, available liquidity or covenant headroom. Do not count swap notional as debt. |
| 6 | Secondary credit spreads | Authorized secondary trades/comparables; x=years to maturity, y=benchmark spread in bp; encode par size and credit, timestamp observations. Pitchbook contract: `market.secondary_trading`. | Filter and label trade side, size, date range, stale/outlier treatment and benchmark date. Not available in the initial banker profile. |
| 7 | Secondary-derived scale | Saved/approved secondary scale preview or `scale.secondary_break` / pricing contracts with issuer and as-of scope. | Distinguish observed trades, fitted curve and extrapolated tenors. Never fit a substitute curve silently. |
| 8 | Sample 10/20/30-year level DS | Three reviewed new-money model runs with common par/proceeds target, dated/delivery dates, coupon/yield scale, costs, call assumptions and calendar. | Compare annual debt service and total interest on identical assumptions. Do not calculate sample bond schedules by guessing level-payment math. |
| 9 | Current refunding, <=1 year | Authorized Report-tab/model outputs for the selected callable maturities; carry settlement/call date, escrow, costs and NPV savings. | The one-year boundary uses the supplied as-of date; call eligibility is not a savings calculation. |
| 10 | Taxable advance refunding, >1 year | Authorized taxable advance-refunding model outputs and escrow assumptions for calls after the one-year boundary. | Label taxable structure, benchmark curve, reinvestment/escrow rates and carry. Avoid presenting an unsupported tax conclusion. |
| 11 | Taxable tender opportunities | Select Bonds Monitor tender prices plus authorized tender analysis; price per $100, assumed acceptance and financing/cost inputs. | Indicate price timestamp, source and acceptance assumptions; a modeled tender is not an executable offer. |
| 12 | Defeasance costs | Authorized cashflow/escrow model, eligible investments and settlement assumptions. | State valuation date, reinvestment rates, negative arbitrage, costs and coverage constraints. |
| 13 | Bondholders | Authorized holdings with reporting date, parent consolidation, amounts and coverage. | Holdings snapshots are not a complete live ownership register; disclose missing/unknown coverage. |
| 14 | Fixed Index | Authorized fixed-index history / `market.rates_snapshot` / `market.mmd_curve` with AAA Index benchmark and observation dates. | State percent vs bp and observation frequency; do not substitute a different index without naming it. |
| 15 | Variable Index | Authorized variable-index series, index definition and effective/reset dates. | Do not label an issuer's VRDB rate history as a market-wide index. |
| 16 | Economic calendar | User-provided or authorized current calendar with source, timezone, release time, forecast/previous/actual fields. | No live economic-calendar MCP source is included in the initial profile. Label unavailable fields and confirm event dates. |

The MuniPro firm pitchbook workflow uses company-scoped reference templates,
binding review and compilation. Its feature admission is separate from MCP.
Contracts are declared schemas, not proof that a particular firm's binding
or a live resolver is available. Do not call browser-only compilation routes
with an MCP token or bypass the template review workflow.

For every populated slide keep: recipe ID, template ID/version, issuer ID,
as-of date, fiscal year end, exact dataset parameters, artifact SHA-256,
source URLs, source availability, filters, units, displayed totals, warnings,
and the model run or saved-case ID where applicable.


---

<a id="banker-reference-2"></a>

# Firm template and slide bindings

Status: Active

The two modes share one skill. In **template mode**, produce a reusable copy
with named empty slots and no sample issuer values. In **issuer-deck mode**,
populate selected supported recipes in a copy of an approved template.
Distinguish a template, a data-binding packet and a rendered presentation.

## Establish the firm's reference

Obtain an authorized reference PPTX or an existing admitted company template.
Record its template ID/version and file SHA-256. Inspect its masters/layouts,
fonts, theme, title/body styles, logos, footer/disclosure zones and source-note
convention. Ask only for the missing required template or layout choice.
Do not invent firm branding. Private references remain subject to the user's
permitted storage and processing destinations.

Retain required legal copy and masters. Create a new file for either mode;
preserve the original. Create editable table/chart objects where supported.
Identify any rasterized figure as such.

## Client-created binding manifest

Use `schema: "munipro.banker.template-binding.v1"` and record:

| Field | Content |
|---|---|
| `mode` | `template` or `issuer_deck`. |
| `template` | Reference ID, version, original filename and SHA-256. |
| `issuer_id`, `as_of_date`, `fiscal_year_end` | Actual inputs in deck mode; unpopulated in reusable template mode. |
| `slides` | Ordered recipe IDs, template layout names and named shape/table/chart slots. |
| Per-slide `source` | Dataset JSON path, parameters, artifact digest, canonical URLs and selected identities. |
| Per-slide `transform` | Grouping, units, filters, rounding and existing recipe convention. |
| Per-slide `availability` | `populated`, `missing_source`, `unsupported_in_profile` or `template_slot`. |
| Per-slide `reconciliation` | Source/displayed totals, units, unknown values and explained differences. |
| `review` | Rendered output paths, pages inspected, unresolved layout issues and source-review status. |

Suggested named slots: `issuer_title`, `as_of`, `debt_table_by_credit`,
`debt_service_chart_by_credit`, `callable_chart_by_credit`,
`callable_chart_by_coupon`, `source_footer`. These are client template bindings,
not fixed MuniPro or Rogo APIs.

Use the slide recipes for all sixteen input/transform contracts. The first four
have initial-profile data. A liquidity wall needs instrument/facility evidence;
recipes 6–16 need additional authorized sources. Preserve unsupported slots
only when useful to the requested deck, clearly labeled. Do not silently show
invented zero data or reused sample issuer data.

## Finish and review

Reconcile populated tables/charts to retained source data. Put as-of basis,
fiscal year, units, assumptions, filters and citations in the firm's source
footer or notes. Preserve notices and disclosures. Render every final slide
and inspect clipping, text size, font substitution, labels/legends, notes,
numbering and template identity. Repair observed defects and rerender affected
slides. Report unresolved issues.

Without rendering capability, deliver a binding/data packet with status
`partial` and a missing-renderer limitation. A PPTX existing on disk is not
evidence of correct rendering. Rogo owns its editor/renderer binding; MuniPro's
browser-only firm-pitchbook routes are not authorized by a generic MCP bearer.
