EMMA MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@EMMA MCP show me California's upcoming municipal bond issues for next month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
EMMA MCP — Custom Muni-Finance Agent for Blaylock Van
NYU Stern Consulting Capstone · Spring 2026 · Marco Figueroa, Justin Ganjian, Andrew Kay, Isaac Mizrahi, Roshan Raja · Professor Marciano
What this is
A custom MCP (Model Context Protocol) server that lets Claude read the muni-bond new-issue market directly from the MSRB's EMMA website. This is the Tier-4 example on our capstone tier ladder — a firm-owned connector to a data source that no vendor covers.
EMMA — the Electronic Municipal Market Access site operated by the Municipal Securities Rulemaking Board — is the official public book of record for every muni bond sold in the United States. New-issue calendars, Official Statements, CUSIP-level details, recent trade prices: all on EMMA. It has no public API.
This MCP exposes 18 tools and 2 resources (a CLAUDE.md rules file and an EMMA_ABBREVIATIONS.md glossary) that Claude auto-loads on connect. Once installed, a banker can ask Claude natural-language questions like "pull every outstanding Rady Children's Hospital bond and download the most recent OS" and Claude executes the full chain — search → issuer lookup → issue details → PDF download → text extraction — in about 20 seconds.
For the full pitch and why it matters to Blaylock, see USAGE.md → Why this exists.
Related MCP server: IsoFinancial-MCP
Prerequisites
You need four things on your laptop. If any are missing, the install instructions below cover it.
Requirement | What it is | Install check |
Claude Desktop | Anthropic's native macOS/Windows client (the MCP host) | |
Python 3.10+ | Runtime for the server | Mac: |
uv | Python package manager (handles the venv automatically) |
|
Playwright Chromium | Headless browser the server drives EMMA with | Installed by one command below |
Install — Mac
# 1. Unzip this folder somewhere sensible
cd ~/Downloads
unzip emma-mcp.zip -d ~/emma-mcp
cd ~/emma-mcp
# 2. If you don't have uv:
brew install uv
# 3. Create the venv + install dependencies (one command)
uv sync
# 4. Install the headless browser Playwright drives
uv run playwright install chromium
# 5. Smoke-test the server (optional — confirms it boots)
uv run python server.py
# You should see the server start and wait on stdin.
# Press Ctrl+C to stop.Wire it into Claude Desktop (Mac)
Open Claude Desktop → Settings → Developer → Edit Config. That opens
claude_desktop_config.json.Add an
emmaentry inside themcpServersobject. Use the absolute path to the.venv/bin/pythonthatuv syncjust created and the absolute path toserver.py:
{
"mcpServers": {
"emma": {
"command": "/Users/YOURNAME/emma-mcp/.venv/bin/python",
"args": ["/Users/YOURNAME/emma-mcp/server.py"]
}
}
}Save, fully quit Claude Desktop (
Cmd+Q, not just close the window), and reopen it.In a new chat, the hammer icon in the composer should now list EMMA tools. That's the tell.
Install — Windows
# 1. Unzip this folder, e.g. to C:\emma-mcp
cd C:\emma-mcp
# 2. If you don't have Python: install from python.org (3.10 or later).
# Check "Add Python to PATH" during install.
# 3. Install uv
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# 4. Create the venv + install deps
uv sync
# 5. Install Playwright's Chromium
uv run playwright install chromium
# 6. Smoke-test
uv run python server.py
# Ctrl+C to stop.Wire it into Claude Desktop (Windows)
Open
%APPDATA%\Claude\claude_desktop_config.jsonin a text editor. (Paste that path into the Explorer address bar — Windows resolves%APPDATA%toC:\Users\YOU\AppData\Roaming.)Use forward slashes or double backslashes in the JSON paths — Windows single backslashes break JSON:
{
"mcpServers": {
"emma": {
"command": "C:/emma-mcp/.venv/Scripts/python.exe",
"args": ["C:/emma-mcp/server.py"]
}
}
}Save, fully quit Claude Desktop (right-click tray icon → Quit), reopen.
Check the hammer icon in the composer for EMMA tools.
First prompt — the 60-second verification
Open a new Claude Desktop chat and paste:
Use the EMMA MCP to pull the upcoming new-issue calendar for the next week. Filter to NY state only. Return a clean table with issuer, par, dated, and sector.
You should see Claude call get_new_issue_calendar with state="NY", get ~10-25 rows back in a few seconds, and format them as a table with EMMA URLs. If that works, every other tool works the same way.
For a more impressive demo, try:
Find Rady Children's Hospital on EMMA, pull their outstanding bonds, get the most recent issue's details, download the Official Statement, and summarize the rating language and use of proceeds from the first 10 pages.
That runs the full five-tool chain end-to-end in about 20 seconds.
More demo prompts in USAGE.md.
Troubleshooting
Claude Desktop doesn't show EMMA tools after restart.
Confirm the JSON is valid (
python3 -m json.tool < claude_desktop_config.json— no output = good).Confirm both paths in the config are absolute and exist. Relative paths and
~do not work.Fully quit Claude Desktop (
Cmd+Q/ tray Quit) — closing the window keeps it running.Check Claude Desktop's MCP logs at
~/Library/Logs/Claude/mcp*.log(Mac) or%APPDATA%\Claude\logs\mcp*.log(Windows) for a specific error.
playwright install chromium hangs or fails.
First-time install downloads ~150 MB and takes 1-2 min on a home connection. Be patient.
Behind a corporate proxy, set
HTTPS_PROXYandHTTP_PROXYbefore running.
Claude calls a tool and it returns "EMMA disclaimer loop" or times out.
EMMA sets a CUSIP disclaimer cookie on first visit. The server pre-seeds it (
Disclaimer6=msrborg) but very rarely EMMA changes the cookie name. Restart Claude Desktop to reset the browser context. If it persists, EMMA may be down — checkhttps://emma.msrb.orgin a regular browser.
A returned table shows cusip_hash: ABC123… instead of a 9-digit CUSIP.
This is intentional, not a bug. EMMA renders CUSIPs as image tags (CGS licensing rule), so the server cannot read them off HTML. The Official Statement PDF is the authoritative CUSIP source. Use
download_official_statementthenextract_pdf_text— the cover and inside-cover carry the real CUSIPs.
"Rady Children's" search finds Franklin OH and Pittsburgh PA children's hospitals but not Rady.
This is a known EMMA quirk, not a server bug. Rady's bonds file under a California conduit (CHFFA / CPFA) with "RADY CHILDRENS" only in the obligor-in-parens portion, which EMMA's QuickSearch does index but weakly. Try
emma_quick_search {query: "rady"}or search the conduit directly:search_issuers_by_state {state: "CA", contains: "health care facilities"}. Full obligor lookup playbook inUSAGE.md→ The conduit cheat sheet.
Server starts but Claude says "no tools available."
You likely edited
server.pyand there's a Python syntax error. Runuv run python server.pyin a terminal — any error prints to stderr. Fix and restart Claude Desktop.
What's in this folder
File / folder | What it is |
| The MCP server itself — ~1,500 lines, Python, Playwright. 18 tools, 2 resources. |
| Blaylock compliance rules. Loaded into every EMMA session as MCP resource |
| EMMA's telegraphic issuer-name abbreviations (HOSP, AUTH, SR, CMNTY, etc.) + conduit cheat sheet. Loaded as resource |
| This file. |
| Extensive reference: the 18 tools, the canonical workflow chain, sample banker prompts, caveats. |
| Python dependency manifest. |
| One-shot driver used during slide preparation — calls the MCP directly so we could screenshot outputs. Not needed to run the server. |
| Companion script that batch-downloaded OS PDFs for the capstone's Tier 2 (Cowork) demo. Not needed to run the server. |
| Sample Official Statements downloaded via the MCP during testing. Keep or delete — the folder auto-recreates on first |
The one-line version
We built the EMMA MCP that no vendor ships, wired it into Claude via the same protocol as every marketplace connector, and governed it with a plain-markdown rules file a banker can read and edit. That is what Tier 4 looks like when a firm actually owns its own tool.
Available Tools
18 toolsclassify_sectorA
Classify a muni bond issue description into a sector using the same keyword rules the calendar tool uses. Useful to show Marciano the classifier is deterministic, not a black box.
Inputs: description (required).
download_official_statementA
Download an Official Statement PDF from EMMA to local disk. Pass either a direct PDF URL or an IssueView URL (the tool will resolve it to the PDF link). Returns file path + size. Use when the banker wants the OS to attach to a deck or read offline.
Inputs: url (required), filename.
emma_quick_searchA
START HERE when the user names a specific obligor, issuer, or keyword. Uses EMMA's global quick search (the same box in EMMA's header) which indexes BOTH long-form and obligor-in-parens names — so 'Childrens Hospital' finds 'CALIFORNIA HEALTH FACILITIES FINANCING AUTHORITY (LUCILE SALTER PACKARD CHILDRENS HOSPITAL AT STANFORD)' without needing the conduit-issuer chase. Returns matching issuers (across all states) and matching specific issues. Each issuer row has a URL you can feed into get_issuer_outstanding_bonds.
Inputs: query (required), limit.
extract_pdf_textA
Extract text from a previously-downloaded OS PDF so you can pull financials, debt service tables, obligor financials, rating language, bond purpose, sources-and-uses, etc. into an Excel model. Works best on OS PDFs saved via download_official_statement.
Inputs: path (required), pages, max_chars.
get_calendar_summaryA
Aggregate the new-issue calendar by a grouping dimension. Returns count and total par per group, sorted by par descending. Perfect for slides: 'NY leads this week at $1.2B across 8 deals; hospitals and schools dominate the sector mix.'
Inputs: group_by, top_n.
get_issue_detailsA
Full IssueView page for a given IssueView URL — per-CUSIP detail (par at issuance, coupon, maturity, initial offering price, current LT rating, price, yield, and ratings from Fitch, KBRA, Moody's, S&P), the Official Statement PDF link, and recent trade activity. This is the single most information-dense page on EMMA for modeling a specific deal.
Inputs: issue_url (required).
get_issuer_outstanding_bondsB
List an issuer's outstanding bond issues from their EMMA profile — issue description, dated date, maturity range. The most reliable drill-down on any issuer.
Inputs: issuer_id, issuer_url, limit.
get_issuer_profileA
Full issuer profile: name, outstanding issues, attempted fetch of Official Statements, Pre-Sale docs, Continuing Disclosures, and Recent Trades. EMMA loads the latter via tab interaction; empty sections are reported honestly rather than guessed at.
Inputs: issuer_id, issuer_url.
get_market_pulseA
Snapshot of this week's muni primary market: total par, deal count, top 5 states, top 5 sectors, top 5 lead managers if available, competitive-vs-negotiated split. Built entirely from the live new-issue calendar — one call, boardroom-ready.
Inputs: no named parameters.
get_new_issue_calendarA
Upcoming municipal bond issues from MSRB EMMA — the primary competitive-intel tool for any muni banker. Each row is enriched with an inferred sector classification. Multi-axis filters: state, sector, tax_status, bank_qualified, sale_method, description_contains, min_principal, max_principal. Use this to answer questions like 'what hospital deals over $100M are pricing this week?'
Inputs: state, sector, tax_status, bank_qualified, +6 more.
get_official_statement_pdfA
Given an EMMA IssueView/Details/P##### URL, return the direct Official Statement PDF URL (and issue title). This is the canonical primary-source OS — use it before quoting coupons, maturities, or call features.
Inputs: issue_url (required).
get_recent_annual_reportsA
Recent issuer annual financial reports filed as continuing disclosures — the source for post-issuance updated obligor financials (revenue, operating income, debt-service coverage).
Inputs: limit, issuer_contains.
get_recent_continuing_disclosuresA
Recent continuing-disclosure filings (audited financials, material events, rating changes, quarterly operating data). Each row has a direct link to the filed PDF. This is where post-issuance credit work lives — ratings today, not at issuance; updated obligor financials for modeling.
Inputs: limit, disclosure_contains, issuer_contains.
get_recent_official_statementsA
List the EMMA Recent Official Statements grid — the 10 most recently filed OS documents across the muni market, with issuer, series, dated date, and a link back to the issuer. Feed a row's issue_url into get_official_statement_pdf to grab the PDF URL.
Inputs: limit.
get_recent_preliminary_statementsA
Recent Preliminary Official Statements (POS) — pre-pricing documents filed right before a deal comes to market. This is the leading edge of the new-issue pipeline. Each row links to the filing PDF and the issuer page.
Inputs: limit, issuer_contains.
get_recent_salesA
Most actively traded muni CUSIPs right now from EMMA's /TradeData grid — description, coupon, maturity, high/low price & yield, trade count, total trade amount, and a link to each security's EMMA detail page. Use this to gauge live-market color for comparable deals.
Inputs: limit.
get_security_detailsA
Pull security-level fields for a 9-digit CUSIP: issuer, coupon, maturity, dated date, par. CUSIPs that are redeemed / matured / pre-refunded return a clear 'no records' response — try a currently-outstanding CUSIP from get_issuer_outstanding_bonds.
Inputs: cusip (required).
search_issuers_by_stateA
List municipal issuers for a state (all 9k+ rows, not just page 1) and filter by name. Feed the issuer_id into get_issuer_outstanding_bonds or get_issuer_profile to drill down. IMPORTANT: the contains filter auto-expands your query into every EMMA abbreviation variant (hospital→HOSP, authority→AUTH, children→CHLDN, senior→SR, community→CMNTY, etc.) — always search in natural English, never in the telegraphic form. For hospital/senior-living/charter-school obligors, search the CONDUIT, not the obligor: e.g. CHLA bonds are filed under CALIFORNIA PUB FIN AUTH HEALTH CARE FACS REV — found by searching contains="health care facilities". See the emma://rules/EMMA_ABBREVIATIONS.md resource for the full variant map and conduit cheat sheet.
Inputs: state (required), contains, limit.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 18 tools
Each tool has a distinct purpose with detailed descriptions. For example, 'download_official_statement' vs 'get_official_statement_pdf' vs 'extract_pdf_text' are clearly separated. No two tools overlap in functionality; agents can unambiguously choose the right tool.
Names follow a consistent verb_noun pattern (e.g., 'classify_sector', 'download_official_statement', 'get_calendar_summary'). While not all use the same verb (mix of 'get_', 'search_', 'extract_'), the structure is uniform and clear, earning a 4 for minor deviation from a single prefix.
With 18 tools, the server covers a wide range of municipal bond data operations without being excessive. Each tool addresses a specific need, from searching issuers to extracting PDF text, making the count well-scoped for the domain.
The tool surface is comprehensive, covering search, issuer details, calendar, documents, and market data. Minor gaps exist, such as lack of historical trade analytics or advanced filtering, but core workflows are fully supported.
Related MCP Connectors
MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence
The Octagon MCP server provides specialized AI-powered financial research and analysis by integrating with the Octagon Market Intelligence API. It enables users to analyze public market data (SEC filings, earnings transcripts, financial metrics, and stock data for 8000+ companies), private market data (3M+ companies, 500k+ funding rounds, 2M+ M&A/IPO transactions), and conduct deep research including web scraping capabilities. The server also features autonomous research agents that search hundreds of sources and return fully cited reports in approximately one minute.
Hosted MCP server for live public-data APIs and Skills for AI agents.
75 MCP tools: SEC financials, FRED economics, IRS 990, FDA, FX, UK Companies House.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for the BoondManager API, enabling Claude to search, create, and modify records across 36 domains with 158 tools.238164 npm21Apache 2.0
- AlicenseNot gradedqualityDmaintenanceAn enhanced MCP server providing comprehensive financial market data endpoints for quantitative trading analysis, including SEC filings, FINRA short volume, earnings, news, and Google Trends. It features meta-tools that consolidate multiple data sources into single efficient calls, optimizing for AI agents with iteration budgets.8MIT

city-data-mcpofficial
AlicenseAqualityDmaintenanceAn MCP server that gives Claude deep access to US public data -- demographics, economics, crime, employment, weather, housing, transit, schools, budgets, and more across 30+ cities for government intelligence workflows.28MIT- FlicenseNot gradedqualityDmaintenanceA production-grade MCP server enabling Claude to perform comprehensive NJ real estate workflows including property search, valuation, neighborhood intelligence, investment analysis, and agent tools via 20 tools and 15+ data sources.-