Skip to main content
Glama
john-walkoe

USPTO Final Petition Decisions MCP Server

by john-walkoe

Search_petitions_by_art_unit

Analyze USPTO petition decisions by art unit to identify examiner patterns, assess quality issues, and support cross-referencing with examiner data and PTAB challenge rates.

Instructions

Search petitions by art unit number for examiner/art unit quality analysis.

Use for: Art unit quality assessment, systematic petition patterns, examiner behavior analysis. Returns balanced field set for cross-referencing with PFW examiner data and PTAB challenge rates.

Example:

  • fpd_search_petitions_by_art_unit(art_unit="2128", limit=50)

  • fpd_search_petitions_by_art_unit(art_unit="2128", date_range="2020-01-01:2024-12-31")

Analysis patterns:

  • High petition frequency → Difficult examiners or challenging technology

  • Frequent revival petitions (37 CFR 1.137) → Docketing/procedural issues

  • Examiner disputes (37 CFR 1.181) → Communication/quality problems

  • Denied petitions → Weak prosecution practices

Cross-MCP integration:

  • applicationNumberText → pfw_search_applications_minimal with fields parameter for examiner names

  • Group petitions by examiner to identify individual patterns

  • patentNumber → PTAB MCP to correlate petition history with challenge success

Parameters:

  • art_unit: Art unit number (e.g., "2128", "3600")

  • date_range: Optional date range (format: "YYYY-MM-DD:YYYY-MM-DD")

  • limit: Maximum results (default 50, max 200)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
art_unitYes
date_rangeNo
limitNo

Implementation Reference

  • Primary MCP tool handler: decorated with @mcp.tool(name="Search_petitions_by_art_unit"), performs validation, delegates to API client, applies balanced field filtering, adds specialized LLM guidance for art unit analysis.
    @mcp.tool(name="Search_petitions_by_art_unit") @async_tool_error_handler("art_unit_search") async def fpd_search_petitions_by_art_unit( art_unit: str, date_range: Optional[str] = None, limit: int = 50 ) -> Dict[str, Any]: """Search petitions by art unit number for examiner/art unit quality analysis. **Use for:** Art unit quality assessment, systematic petition patterns, examiner behavior analysis. Returns balanced field set for cross-referencing with PFW examiner data and PTAB challenge rates. **Example:** - fpd_search_petitions_by_art_unit(art_unit="2128", limit=50) - fpd_search_petitions_by_art_unit(art_unit="2128", date_range="2020-01-01:2024-12-31") **Analysis patterns:** - High petition frequency → Difficult examiners or challenging technology - Frequent revival petitions (37 CFR 1.137) → Docketing/procedural issues - Examiner disputes (37 CFR 1.181) → Communication/quality problems - Denied petitions → Weak prosecution practices **Cross-MCP integration:** - applicationNumberText → pfw_search_applications_minimal with fields parameter for examiner names - Group petitions by examiner to identify individual patterns - patentNumber → PTAB MCP to correlate petition history with challenge success **Parameters:** - art_unit: Art unit number (e.g., "2128", "3600") - date_range: Optional date range (format: "YYYY-MM-DD:YYYY-MM-DD") - limit: Maximum results (default 50, max 200)""" try: # Input validation if not art_unit or len(art_unit.strip()) == 0: return format_error_response("Art unit cannot be empty", 400) if limit < api_constants.MIN_SEARCH_LIMIT or limit > api_constants.MAX_SEARCH_LIMIT: return format_error_response(f"Limit must be between {api_constants.MIN_SEARCH_LIMIT} and {api_constants.MAX_SEARCH_LIMIT}", 400) if date_range: # Basic date range format validation parts = date_range.split(":") if len(parts) != 2: return format_error_response( "Date range must be in format YYYY-MM-DD:YYYY-MM-DD", 400 ) # Use API client's search_by_art_unit method result = await api_client.search_by_art_unit( art_unit=art_unit, date_range=date_range, limit=limit ) # Check for errors if "error" in result: return result # Filter response using balanced field set fields = field_manager.get_fields("petitions_balanced") filtered_result = field_manager.filter_response(result, "petitions_balanced") # Add art unit analysis guidance filtered_result["llm_guidance"] = { "workflow": "Art Unit Discovery -> Examiner Mapping -> PTAB Correlation", "analysis_patterns": { "high_frequency": "Many petitions → Difficult examiners/technology/systematic issues", "revival_clustering": "Multiple 37 CFR 1.137 → Docketing/procedural problems", "examiner_disputes": "Multiple 37 CFR 1.181 → Communication/quality issues", "ptab_correlation": "High petitions + high PTAB invalidation → Quality issues" }, "next_steps": [ "Use pfw_search_applications_minimal with fields parameter for examiner mapping", "Group petitions by examiner to identify individual patterns", "Check GRANTED/DENIED outcomes to assess Director overturn rates", "Cross-reference patentNumbers with PTAB for challenge correlation" ], "red_flags": { "high_denial_rate": "Weak prosecution practices", "multiple_examiners": "Art unit-wide problem", "temporal_clustering": "Process breakdown in specific periods" } } return filtered_result except ValueError as e: logger.warning(f"Validation error in art unit search: {str(e)}") return format_error_response(str(e), 400) except httpx.HTTPStatusError as e: logger.error(f"API error in art unit search: {e.response.status_code} - {e.response.text}") return format_error_response(f"API error: {e.response.text}", e.response.status_code) except httpx.TimeoutException as e: logger.error(f"API timeout in art unit search: {str(e)}") return format_error_response("Request timeout - please try again", 408) except Exception as e: logger.error(f"Unexpected error in art unit search: {str(e)}") return format_error_response(f"Internal error: {str(e)}", 500)
  • Service layer handler that delegates to API client and applies field filtering.
    async def search_by_art_unit( self, art_unit: str, date_range: Optional[str] = None, limit: int = 50 ) -> Dict[str, Any]: """ Search petitions by art unit Args: art_unit: Art unit number date_range: Optional date range filter limit: Number of results to return Returns: Search results for the art unit """ result = await self.api_client.search_by_art_unit( art_unit=art_unit, date_range=date_range, limit=limit ) # Filter response using balanced field set if "error" not in result: result = self.field_manager.filter_response(result, "petitions_balanced") return result
  • Core API client implementation: constructs Lucene query for art unit search, applies date range filters, delegates to generic search_petitions method.
    async def search_by_art_unit( self, art_unit: str, date_range: Optional[str] = None, limit: int = 50 ) -> Dict[str, Any]: """ Search petitions by art unit number Args: art_unit: Art unit number (e.g., "2128") date_range: Optional date range filter (e.g., "2020-01-01:2024-12-31") limit: Maximum number of results Returns: Dict containing search results """ try: # Build query query = f"{QueryFieldNames.ART_UNIT}:{art_unit}" # Build filters for date range if provided filters = [] if date_range: # Parse date range parts = date_range.split(":") if len(parts) == 2: filters.append({ "field": FPDFields.PETITION_MAIL_DATE, "valueFrom": parts[0], "valueTo": parts[1] }) return await self.search_petitions( query=query, filters=filters if filters else None, limit=limit ) except Exception as e: logger.error(f"Error in search_by_art_unit: {str(e)}") return format_error_response(str(e), 500, generate_request_id())
  • MCP tool registration decorator specifying the tool name.
    @mcp.tool(name="Search_petitions_by_art_unit")
  • Input schema defined by function parameters: art_unit (required str), date_range (optional str), limit (optional int=50). Output: Dict[str, Any] with filtered results and guidance.
    async def fpd_search_petitions_by_art_unit( art_unit: str, date_range: Optional[str] = None, limit: int = 50 ) -> Dict[str, Any]:

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/john-walkoe/uspto_fpd_mcp'

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