Skip to main content
Glama

get_security_details

Retrieve security details for a 9-digit CUSIP: issuer, coupon, maturity, dated date, and par. Returns clear 'no records' for redeemed or matured bonds.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cusipYes

Implementation Reference

  • Handler function for get_security_details tool — navigates to EMMA Security/Details page for the given CUSIP, validates 9-char length, checks for 'no records exist' message (matured/invalid CUSIPs), and scrapes label fields from the page.
    if name == "get_security_details":
        cusip = args["cusip"].strip().upper()
        if len(cusip) != 9:
            return {"error": "CUSIP must be 9 characters"}
        async with new_page() as page:
            await page.goto(f"{EMMA_BASE}/Security/Details/{cusip}",
                            wait_until=NAV_WAIT, timeout=NAV_TIMEOUT_MS)
            await page.wait_for_timeout(2500)
            body = await page.evaluate("() => document.body.innerText")
            if "no records exist" in body.lower():
                return {
                    "cusip": cusip,
                    "error": "no records exist for this CUSIP — likely matured, "
                             "pre-refunded, or invalid. Try a currently-outstanding "
                             "CUSIP from get_issuer_outstanding_bonds.",
                }
            fields = await page.evaluate(
                """() => {
                    const out = {};
                    document.querySelectorAll('[id*=lbl], [id*=Lbl]').forEach(el => {
                        const k = el.id.split('_').pop().replace(/^lbl/i,'');
                        const v = (el.innerText||'').trim();
                        if (v && v.length<300) out[k]=v;
                    });
                    return out;
                }"""
            )
            return {"cusip": cusip, "fields": fields}
  • Schema/input definition for get_security_details — defines the tool name, description, and inputSchema requiring a single 'cusip' string parameter.
        name="get_security_details",
        description=(
            "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."
        ),
        inputSchema={
            "type": "object",
            "properties": {"cusip": {"type": "string"}},
            "required": ["cusip"],
        },
    ),
  • server.py:577-755 (registration)
    Tool registration via @server.list_tools() — get_security_details is listed among the server's tools in the list_tools function.
            name="get_security_details",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {"cusip": {"type": "string"}},
                "required": ["cusip"],
            },
        ),
        Tool(
            name="emma_quick_search",
            description=(
                "**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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Natural-language search: obligor name, issuer name, CUSIP, state, or keyword",
                    },
                    "limit": {"type": "integer", "default": 25},
                },
                "required": ["query"],
            },
        ),
        Tool(
            name="get_issue_details",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "issue_url": {
                        "type": "string",
                        "description": "EMMA IssueView URL (https://emma.msrb.org/IssueView/Details/P#####)",
                    }
                },
                "required": ["issue_url"],
            },
        ),
        Tool(
            name="get_recent_continuing_disclosures",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "limit": {"type": "integer", "default": 50},
                    "disclosure_contains": {
                        "type": "string",
                        "description": "Filter disclosure description (auto-expanded for EMMA abbreviations)",
                    },
                    "issuer_contains": {
                        "type": "string",
                        "description": "Filter issuer name (auto-expanded for EMMA abbreviations)",
                    },
                },
            },
        ),
        Tool(
            name="extract_pdf_text",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Absolute path to the saved PDF",
                    },
                    "pages": {
                        "type": "string",
                        "description": "Page range like '1-20' or '45,46,47' (optional — default: all)",
                    },
                    "max_chars": {
                        "type": "integer",
                        "default": 120000,
                        "description": "Cap on returned characters to protect context",
                    },
                },
                "required": ["path"],
            },
        ),
        Tool(
            name="get_recent_official_statements",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {"limit": {"type": "integer", "default": 10}},
            },
        ),
        Tool(
            name="get_official_statement_pdf",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "issue_url": {
                        "type": "string",
                        "description": "EMMA IssueView URL (https://emma.msrb.org/IssueView/Details/P#####)",
                    }
                },
                "required": ["issue_url"],
            },
        ),
        Tool(
            name="download_official_statement",
            description=(
                "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."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "url": {
                        "type": "string",
                        "description": "Either a direct .pdf URL or an IssueView/Details/P##### URL",
                    },
                    "filename": {
                        "type": "string",
                        "description": "Optional filename (without extension)",
                    },
                },
                "required": ["url"],
            },
        ),
        Tool(
            name="get_market_pulse",
            description=(
                "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."
            ),
            inputSchema={"type": "object", "properties": {}},
        ),
    ]
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes the response behavior for invalid/outstanding CUSIPs, but without annotations, more details on authentication, rate limits, or format errors would improve transparency. The current disclosure is adequate but basic.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, essential information front-loaded. Every sentence serves a purpose: stating the action, listing fields, and providing usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with no output schema, the description covers input constraints, response behavior for edge cases, and references a sibling tool. It is mostly complete, though more details on the response structure would help.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides no description for cusip (0% coverage). The description compensates by specifying it must be a 9-digit CUSIP and implying it should be outstanding, adding crucial context beyond the schema's type-only constraint.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool pulls specific security-level fields (issuer, coupon, maturity, dated date, par) for a 9-digit CUSIP. It distinguishes from sibling tools like get_issuer_outstanding_bonds by noting when to use that alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when not to use (redeemed/matured/pre-refunded CUSIPs) and directs to the alternative get_issuer_outstanding_bonds for currently-outstanding CUSIPs. This provides clear decision guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ark9164-create/blaylock-emma-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server