get_document
Retrieve the full content of any Magento 2 GraphQL documentation page by providing its file path relative to the docs root.
Instructions
Retrieve complete documentation page by file path
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | File path relative to docs root, e.g., 'schema/products/queries/products.md' |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- The get_document MCP tool handler. Decorated with @mcp.tool, it accepts a file_path argument and queries the SQLite database to retrieve and format a full documentation page. It returns the document title, path, category, type, keywords, description, and full markdown content.
@mcp.tool( name="get_document", description="Retrieve complete documentation page by file path" ) def get_document( file_path: Annotated[str, Field(description="File path relative to docs root, e.g., 'schema/products/queries/products.md'")] ) -> str: """Get full document content""" db = Database(DB_PATH) try: # Query by file_path doc = dict(db.query( "SELECT * FROM documents WHERE file_path = ?", [file_path] ).__next__()) except StopIteration: return f"Document not found: {file_path}\n\nTip: Use search_documentation to find the correct file path." # Parse keywords keywords = json.loads(doc.get('keywords_json', '[]')) keywords_str = ', '.join(keywords) if keywords else 'None' # Format document lines = [ f"# {doc['title']}", "", f"**Path:** {doc['file_path']}", f"**Category:** {doc['category']}/{doc.get('subcategory', 'N/A')}", f"**Type:** {doc.get('content_type', 'N/A')}", f"**Keywords:** {keywords_str}", "", ] if doc.get('description'): lines.append(f"**Description:** {doc['description']}") lines.append("") lines.append("---") lines.append("") lines.append(doc['content_md']) return "\n".join(lines) - magento_graphql_docs_mcp/server.py:105-108 (registration)Registration of the get_document tool using FastMCP's @mcp.tool() decorator with the name 'get_document'.
@mcp.tool( name="get_document", description="Retrieve complete documentation page by file path" ) - Input schema/signature for get_document: takes a single 'file_path' string parameter annotated with Pydantic Field description, returns a string.
def get_document( file_path: Annotated[str, Field(description="File path relative to docs root, e.g., 'schema/products/queries/products.md'")] ) -> str: - DB_PATH is a configuration constant that provides the database path used by get_document to connect to the SQLite database.
return str(db_path) def get_docs_path() -> str: """ Determines the GraphQL documentation directory path. Priority order: 1. MAGENTO_GRAPHQL_DOCS_PATH environment variable 2. ./data/ directory (symlink or actual directory in project root) 3. ../commerce-webapi/src/pages/graphql/ (sibling directory) Validates that the path exists and contains documentation files. Raises FileNotFoundError with helpful message if not found. """ # Priority 1: Environment variable env_path = os.environ.get("MAGENTO_GRAPHQL_DOCS_PATH") if env_path: path = Path(env_path).resolve() if not path.exists(): print(f"ERROR: MAGENTO_GRAPHQL_DOCS_PATH set to '{env_path}' but directory does not exist", file=sys.stderr) raise FileNotFoundError( f"Documentation directory not found: {env_path}\n" f"The MAGENTO_GRAPHQL_DOCS_PATH environment variable points to a non-existent directory.\n" f"Please verify the path or unset the variable to use auto-detection." ) return str(path) # Priority 2: ./data/ directory (relative to project root) package_dir = Path(__file__).parent.parent data_path = package_dir / "data" if data_path.exists(): # Check if it's a symlink or directory with content if data_path.is_symlink() or (data_path.is_dir() and list(data_path.glob("*.md"))): return str(data_path.resolve()) # Priority 3: Sibling commerce-webapi directory sibling_path = package_dir.parent / "commerce-webapi" / "src" / "pages" / "graphql" if sibling_path.exists(): return str(sibling_path) # No valid path found - provide helpful error message error_msg = ( "Documentation directory not found!\n\n" "The Magento GraphQL documentation files are required but could not be located.\n\n" "Please choose one of these setup methods:\n\n" "1. Set environment variable:\n" f" export MAGENTO_GRAPHQL_DOCS_PATH='/path/to/commerce-webapi/src/pages/graphql'\n\n" "2. Create symlink in project (recommended for development):\n" f" cd {package_dir}\n" f" ln -s /path/to/commerce-webapi/src/pages/graphql data\n\n" "3. Clone commerce-webapi as sibling directory:\n" f" cd {package_dir.parent}\n" " git clone https://github.com/AdobeDocs/commerce-webapi.git\n\n" "For detailed setup instructions, see SETUP.md" ) print(f"ERROR: {error_msg}", file=sys.stderr) raise FileNotFoundError(error_msg) # Configuration values DB_PATH = get_db_path() - The Document data model used to store and retrieve documentation pages. The get_document handler queries the 'documents' table in the SQLite database, which stores rows matching this schema (title, file_path, category, subcategory, content_type, keywords_json, description, content_md, etc.).
class Document(BaseModel): """Represents a documentation page""" id: str # SHA256 hash of file_path file_path: str # Relative to docs root title: str description: Optional[str] = None keywords: List[str] = Field(default_factory=list) category: str # e.g., "schema", "develop", "usage" subcategory: Optional[str] = None # e.g., "products", "cart" content_type: str # "guide", "reference", "tutorial", "schema" searchable_text: str # Combined: title + description + content headers: List[str] = Field(default_factory=list) # All markdown headers last_modified: datetime content_md: str # Full markdown content class CodeBlock(BaseModel): """Represents a code example""" document_id: str language: str # graphql, json, javascript, bash code: str context: Optional[str] = None # Surrounding text for context line_number: int class GraphQLElement(BaseModel): """Represents a GraphQL schema element""" document_id: str element_type: str # query, mutation, type, interface, union name: str fields: List[str] = Field(default_factory=list) parameters: List[str] = Field(default_factory=list) return_type: Optional[str] = None description: Optional[str] = None searchable_text: str class MarkdownDocParser: """Parse markdown documentation files""" def __init__(self, docs_root: Path): self.docs_root = Path(docs_root) if not self.docs_root.exists(): raise FileNotFoundError(f"Documentation directory not found: {docs_root}") def walk_directory(self) -> List[Path]: """Find all .md files recursively""" md_files = list(self.docs_root.rglob("**/*.md")) logger.info(f"Found {len(md_files)} markdown files") return md_files def parse_file(self, file_path: Path) -> Document: """Parse single markdown file""" # Read file content with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # Parse frontmatter post = frontmatter.loads(content) metadata = post.metadata markdown_content = post.content # Get file stats stat = file_path.stat() last_modified = datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc)