lookup_far_clause
Look up current FAR or DFARS clause text by section identifier. Returns parsed clean text with headings, paragraphs, and citations, auto-resolving latest available date.
Instructions
Convenience tool: look up the current text of a FAR or DFARS clause.
Pass a section identifier like '15.305', '52.212-4', '2.101', etc. Default chapter='1' (FAR). Use chapter='2' for DFARS (e.g., '252.227-7014').
Auto-resolves the latest available date. Returns parsed clean text with heading, paragraphs, and citations.
Common FAR sections: 2.101 (Definitions), 9.104-1 (Responsibility), 15.305 (Proposal Evaluation), 19.502-2 (Small Business Set-Asides), 52.212-4 (Commercial Terms), 52.212-5 (Required Commercial Terms).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| section_id | Yes | ||
| chapter | No | 1 | |
| date | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- The tool handler function for 'lookup_far_clause'. Decorated with @mcp.tool, it takes a section_id, chapter (default '1' for FAR), and optional date. Coerces input, validates chapter against Title 48 chapters, resolves date if needed, then delegates to get_cfr_content to fetch and parse the CFR text from the eCFR API.
@mcp.tool(annotations={"title": "Lookup FAR Clause", "readOnlyHint": True, "destructiveHint": False}) async def lookup_far_clause( section_id: Any, chapter: Any = "1", date: str | None = None, ) -> dict[str, Any]: """Convenience tool: look up the current text of a FAR or DFARS clause. Pass a section identifier like '15.305', '52.212-4', '2.101', etc. Default chapter='1' (FAR). Use chapter='2' for DFARS (e.g., '252.227-7014'). Auto-resolves the latest available date. Returns parsed clean text with heading, paragraphs, and citations. Common FAR sections: 2.101 (Definitions), 9.104-1 (Responsibility), 15.305 (Proposal Evaluation), 19.502-2 (Small Business Set-Asides), 52.212-4 (Commercial Terms), 52.212-5 (Required Commercial Terms). """ section_id = _coerce_cfr_str(section_id, field="section_id", strip_prefixes=True) if not section_id: raise ValueError( "section_id is required. Pass a FAR/DFARS section like '15.305' or '52.212-4'. " f"Common sections: {', '.join(list(COMMON_FAR_SECTIONS.keys())[:5])}." ) chapter = _validate_chapter(chapter, title_number=48) date = _validate_date_ymd(date, field="date") if date is None: date = await _resolve_date(48) return await get_cfr_content( title_number=48, date=date, chapter=chapter, section=section_id, ) - The core workhorse function 'get_cfr_content' called by lookup_far_clause. Fetches XML from the eCFR API versioner endpoint and parses it into clean text (heading, paragraphs, citations). Validates title_number, date, section/part/subpart/chapter, auto-resolves the latest date, and returns parsed content.
async def get_cfr_content( title_number: int = 48, date: str | None = None, part: Any = None, subpart: Any = None, section: Any = None, chapter: Any = None, raw_xml: bool = False, ) -> dict[str, Any]: """Get the full text of a CFR section, subpart, or part. This is the primary workhorse for reading regulatory text. Returns parsed clean text by default (heading, paragraphs, citations). Set raw_xml=True to get the original XML instead. Specify the narrowest scope possible to keep responses manageable: - section='15.305' for a single FAR section - subpart='15.3' for a subpart - part='15' for an entire part (can be large) - chapter='1' for an entire chapter (often >1 MB, avoid) Date auto-resolves to the latest available if not provided. Do NOT use today's date directly -- eCFR lags 1-2 business days and today often 404s. Title 48 = FAR/DFARS. Chapter 1 = FAR (Parts 1-99), Chapter 2 = DFARS (Parts 200-299). Other chapters = agency FAR supplements (GSAR, VAAR, etc.). For DFARS clauses, use chapter='2' (e.g., section='252.227-7014'). part/subpart/section accept int or string. Common prefix mistakes like section='FAR 15.305' or '48 CFR 15.305' are stripped automatically. """ title_number = _validate_title_number(title_number) date = _validate_date_ymd(date, field="date") section = _coerce_cfr_str(section, field="section", strip_prefixes=True) part = _coerce_cfr_str(part, field="part", strip_prefixes=True) subpart = _coerce_cfr_str(subpart, field="subpart", strip_prefixes=True) chapter = _validate_chapter(chapter, title_number=title_number) if not any((section, part, subpart, chapter)): raise ValueError( "get_cfr_content requires at least one of: section, subpart, part, chapter. " "Calling without any filter returns the entire title (often 20+ MB)." ) if date is None: date = await _resolve_date(title_number) path = f"/api/versioner/v1/full/{date}/title-{title_number}.xml" params: dict[str, str] = {} if chapter: params["chapter"] = chapter if part: params["part"] = part if subpart: params["subpart"] = subpart if section: params["section"] = section xml_content = await _get_xml(path, params) if raw_xml: return {"date": date, "title": title_number, "xml": xml_content} parsed = _parse_xml_to_text(xml_content) parsed["date"] = date parsed["title"] = title_number if section: parsed["section"] = section if part: parsed["part"] = part if subpart: parsed["subpart"] = subpart if chapter: parsed["chapter"] = chapter return parsed - Helper '_resolve_date' called by lookup_far_clause when no date is provided. Queries the eCFR titles.json API to find the latest available date for Title 48.
async def _resolve_date(title_number: int) -> str: """Resolve the latest available date for a CFR title. Called before any versioner endpoint. Using today's date often returns 404 because eCFR lags 1-2 business days. Raises ValueError with an actionable message for reserved titles (which have null up_to_date_as_of) rather than building a URL with 'None' in it. """ data = await _get_json("/api/versioner/v1/titles.json") titles = _as_list(_safe_dict(data).get("titles")) for title in titles: t = _safe_dict(title) if _safe_int(t.get("number")) == title_number: utd = t.get("up_to_date_as_of") if not isinstance(utd, str) or not utd.strip(): reason = "this title is marked 'reserved'" if t.get("reserved") else ( "the API did not return up_to_date_as_of" ) raise ValueError( f"Cannot resolve a date for title {title_number}: {reason}. " f"Reserved or un-issued titles have no published content." ) return utd raise ValueError(f"Title {title_number} not found in eCFR titles list.") - Helper '_coerce_cfr_str' normalizes section_id input (e.g., strips 'FAR ' or '48 CFR ' prefixes, accepts ints). Used by lookup_far_clause to clean up the section_id parameter.
def _coerce_cfr_str( value: Any, *, field: str, strip_prefixes: bool = False, maxlen: int = 120, ) -> str | None: """Accept int or str for CFR identifiers (part/subpart/section/chapter). LLMs often pass ints (part=15). We coerce to str, strip whitespace, and optionally strip common user-added prefixes like 'FAR ' or '48 CFR '. Returns None for None/empty/whitespace-only. Raises on other types. """ if value is None: return None if isinstance(value, bool): raise ValueError(f"{field} must be a string or integer, not bool.") if not isinstance(value, (str, int)): raise ValueError( f"{field} must be a string or integer. Got {type(value).__name__}." ) raw = str(value) if "\x00" in raw: raise ValueError(f"{field}={value!r} contains a null byte.") if any(c in raw for c in ("\n", "\r", "\t")): raise ValueError(f"{field}={value!r} must not contain newline/tab characters.") s = raw.strip() if not s: return None if strip_prefixes: s = _SECTION_PREFIX_RE.sub("", s).strip() if not s: return None if len(s) > maxlen: raise ValueError( f"{field} exceeds maximum length of {maxlen} chars. Got {len(s)}." ) return s - Helper '_validate_chapter' validates the chapter parameter against known Title 48 chapters. lookup_far_clause defaults chapter='1' (FAR) and validates it here.
def _validate_chapter(value: Any, *, title_number: int | None = None) -> str | None: """Chapter is a string or int. If title=48, validate against TITLE_48_CHAPTERS.""" s = _coerce_cfr_str(value, field="chapter", maxlen=8) if s is None: return None # For title 48 we know every legitimate chapter. if title_number == 48 and s not in TITLE_48_CHAPTERS: sample = ", ".join(list(TITLE_48_CHAPTERS.keys())[:10]) raise ValueError( f"chapter={value!r} is not a valid Title 48 chapter. " f"Valid chapters: {sample} (see TITLE_48_CHAPTERS for full list). " f"Chapter 1=FAR, 2=DFARS." ) return s