Plugins guide
Publish a HETIBANK plugin that an agent host can install: a manifest, an MCP server, validation and a deterministic bundle.
Anatomy
my-plugin/
plugin.json # agent-plugins.org 1.0.0 + com.openai extension
mcp.json # how the host starts/connects to your MCP server
assets/
icon.png
logo.png
README.md
Create
npx @hetibank/plugins init my-plugin # scaffolds from the buyers-sellers template
npx @hetibank/plugins validate my-plugin
npx @hetibank/plugins bundle my-plugin --out dist
Or copy examples/plugin and edit. The template is the buyers-sellers plugin: assumable-home search, financing view, market report, saved searches, account context and loan evidence.
Manifest
plugin.json must satisfy pluginManifestSchema from @hetibank/contracts:
namekebab-case,versionsemver,description,authorextensions["com.openai"].interface: display name, short/long description, developer name,
category, 1–12 capabilities, URLs, 1–8 default prompts, brandColor (#rrggbb), icon and logo
extensions["com.openai"].review.test_cases: at least one positive and one negative case- optional
publication.countriesandrelease_notes
Negative cases matter: the reviewer expects the plugin to refuse loan approval questions, another person's records, and replacing an accepted agent. Write them down.
MCP server
import { createHetibankMcpServer } from "@hetibank/plugins";
import { createHetibankClient } from "@hetibank/client";
const client = createHetibankClient({
baseUrl: process.env.HETIBANK_API_URL ?? "https://www.hetibank.com/api",
getToken: () => sessionTokenForCurrentUser(), // never a server secret in the browser
getApiKey: () => process.env.HETIBANK_SERVER_KEY,
});
const server = createHetibankMcpServer({ client });
await server.start({ transport: "stdio" });
The curated tool set:
| Tool | Purpose | Read-only |
|---|---|---|
find_assumable_home | payment-first assumable search with applied/relaxed filters | yes |
get_property_financing_view | assumption vs new-loan comparison for one home | yes |
get_market_report | daily Las Vegas report with as-of date | yes |
list_saved_searches | buyer's saved searches and alert state | yes |
get_my_hetibank | account, agent and next Buyer Boost step | yes |
get_loan_evidence | balance/rate evidence ladder for a listing | yes |
Tool rules: description under 1,200 characters, schemas from @hetibank/contracts, readOnlyHint on every read tool, structuredContent for widgets plus a text fallback for hosts without views. Do not copy the 159-parameter MLS search shape — one parameter that works beats a schema nobody reads.
Validate and bundle
npx @hetibank/plugins validate my-plugin # exit 0 valid, 1 invalid, 2 usage error
npx @hetibank/plugins bundle my-plugin --out dist
validate checks: schema, semver, asset existence, https-only remote URLs, no secrets in env or args, review cases present, tool names and descriptions within budget, icon/logo files present. bundle writes a folder plus bundle-manifest.json with a sha256 per file, so two builds of the same input are byte-identical.
Local test with no credentials
npx @hetibank/plugins mcp --mock
Mock mode answers from fixtures so you can exercise tools/list and tools/call in a local MCP client without a HETIBANK session.
Publishing checklist
- [ ]
plugin.jsonandmcp.jsonvalidate - [ ] positive + negative review cases describe real behavior
- [ ] no secret in
env/args; server keys stay server-side - [ ] icon and logo exist and are yours to use
- [ ] widget returns text fallback when structured content is absent
- [ ] bundle manifest committed with the release note
- [ ] support and privacy URLs resolve
What not to do
- Do not invent data the API does not return; concession language belongs in the description.
- Do not put a live API key in the manifest or the browser bundle.
- Do not claim loan approval, guarantees or human advice.
- Do not add a tool that writes to a HETIBANK account without explicit, scoped authorization.