Context7 Integration Skill Expert integration of Context7 for document ingestion, semantic search, and role-scoped context retrieval in ERP applications. Quick Reference | Task | Method/Endpoint | |------|-----------------| | Ingest document | | | Batch ingest | | | Search context | | | Get document | | | Delete document | | Project Structure Context7 Client Core Client Class Context Shaping Utilities API Routes Frontend Hook Document Organization Metadata Examples Quality Checklist - [ ] No PII ingestion : Sensitive documents reviewed before upload - [ ] Query bounds : max chunks, min simila…

, frontmatter, re.MULTILINE)\n if not name_match:\n print(\"✗ Missing 'name' in frontmatter\")\n sys.exit(1)\n name = name_match.group(1).strip()\n\n # Extract description (handles multi-line YAML with | or >)\n desc_match = re.search(r'^description:\\s*[\\|>]?\\s*\\n?(.*)', frontmatter, re.MULTILINE | re.DOTALL)\n if not desc_match:\n print(\"✗ Missing 'description' in frontmatter\")\n sys.exit(1)\n desc = desc_match.group(1).strip()\n\n # Check gerund naming\n if not re.match(r'^[a-z][a-z0-9-]*

Context7 Integration Skill Expert integration of Context7 for document ingestion, semantic search, and role-scoped context retrieval in ERP applications. Quick Reference | Task | Method/Endpoint | |------|-----------------| | Ingest document | | | Batch ingest | | | Search context | | | Get document | | | Delete document | | Project Structure Context7 Client Core Client Class Context Shaping Utilities API Routes Frontend Hook Document Organization Metadata Examples Quality Checklist - [ ] No PII ingestion : Sensitive documents reviewed before upload - [ ] Query bounds : max chunks, min simila…

, name):\n print(f\"✗ Invalid name format: {name}\")\n sys.exit(1)\n\n # Check for \"Use when\" trigger\n if 'use when' not in desc.lower():\n print(\"✗ Description missing 'Use when' trigger\")\n sys.exit(1)\n\n # Check verify.py exists\n verify_path = os.path.join(skill_path, \"scripts\", \"verify.py\")\n if not os.path.isfile(verify_path):\n print(\"✗ scripts/verify.py missing\")\n sys.exit(1)\n\n print(f\"✓ {name} valid\")\n sys.exit(0)\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":1902,"content_sha256":"2506808ccdd732a3b016fbdb5bb7d919d31c867996cd7b28beb5438bf2329ea2"},{"filename":"skill-report.json","content":"{\n \"schema_version\": \"2.0\",\n \"meta\": {\n \"generated_at\": \"2026-01-16T17:31:54.163Z\",\n \"slug\": \"awais68-context7-integration\",\n \"source_url\": \"https://github.com/Awais68/hackathon-2-phase-ii-full-stack-web-app/tree/main/.claude/skills/context7-integration\",\n \"source_ref\": \"main\",\n \"model\": \"claude\",\n \"analysis_version\": \"3.0.0\",\n \"source_type\": \"community\",\n \"content_hash\": \"82cc203aebb8f4be0984a1dc13e6878ad1e2c7a93f2ca8ec18353f5544618095\",\n \"tree_hash\": \"cb9654520bb661740e73ff98da35c69169738661a9b5a799786f5e4597af3292\"\n },\n \"skill\": {\n \"name\": \"context7-integration\",\n \"description\": \"Use when integrating Context7 (knowledge/context store) for document ingestion,\\nsemantic search, or scoped context retrieval.\\nTriggers for: uploading documents, searching knowledge base, filtering by role/tenant,\\nor providing AI with document-grounded context.\\nNOT for: general database queries, file storage without context semantics, or non-document content.\\n\",\n \"summary\": \"Use when integrating Context7 (knowledge/context store) for document ingestion,\\nsemantic search, or ...\",\n \"icon\": \"📚\",\n \"version\": \"1.0.0\",\n \"author\": \"Awais68\",\n \"license\": \"MIT\",\n \"category\": \"data\",\n \"tags\": [\n \"knowledge-base\",\n \"document-management\",\n \"semantic-search\",\n \"context-retrieval\",\n \"erp\"\n ],\n \"supported_tools\": [\n \"claude\",\n \"codex\",\n \"claude-code\"\n ],\n \"risk_factors\": [\n \"scripts\",\n \"filesystem\",\n \"env_access\",\n \"network\"\n ]\n },\n \"security_audit\": {\n \"risk_level\": \"safe\",\n \"is_blocked\": false,\n \"safe_to_publish\": true,\n \"summary\": \"This is a legitimate documentation/reference skill for Context7 knowledge store integration. All 101 static findings are false positives caused by the scanner misidentifying benign code patterns. The skill contains standard Python regex for YAML parsing (misidentified as weak crypto), file operations for documentation ingestion (misidentified as reconnaissance), and environment variable access for API credentials (misidentified as secret keys). The 'dangerous combination' heuristic is a false alarm—the skill is designed for authorized API access with proper credential management.\",\n \"risk_factor_evidence\": [\n {\n \"factor\": \"scripts\",\n \"evidence\": [\n {\n \"file\": \"scripts/verify.py\",\n \"line_start\": 1,\n \"line_end\": 62\n }\n ]\n },\n {\n \"factor\": \"filesystem\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 231,\n \"line_end\": 255\n },\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 880,\n \"line_end\": 942\n }\n ]\n },\n {\n \"factor\": \"env_access\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 109,\n \"line_end\": 110\n }\n ]\n },\n {\n \"factor\": \"network\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 109,\n \"line_end\": 137\n }\n ]\n }\n ],\n \"critical_findings\": [],\n \"high_findings\": [],\n \"medium_findings\": [],\n \"low_findings\": [\n {\n \"title\": \"Hardcoded URL fallback for Context7 API endpoint\",\n \"description\": \"Default URL 'https://api.context7.com' is embedded in code\",\n \"locations\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 110,\n \"line_end\": 110\n }\n ]\n }\n ],\n \"dangerous_patterns\": [],\n \"files_scanned\": 3,\n \"total_lines\": 1283,\n \"audit_model\": \"claude\",\n \"audited_at\": \"2026-01-16T17:31:54.163Z\"\n },\n \"content\": {\n \"user_title\": \"Integrate Context7 for knowledge management\",\n \"value_statement\": \"Building AI-powered applications requires grounded context from documents. This skill provides ready-to-use code for integrating Context7 knowledge store with document ingestion, semantic search, and role-based access control for ERP systems.\",\n \"seo_keywords\": [\n \"Context7 integration\",\n \"knowledge base\",\n \"document ingestion\",\n \"semantic search\",\n \"Claude\",\n \"Codex\",\n \"Claude Code\",\n \"context retrieval\",\n \"role-based access\",\n \"ERP\"\n ],\n \"actual_capabilities\": [\n \"Ingest single or batch documents into Context7 knowledge store\",\n \"Perform semantic search with role and tenant filtering\",\n \"Shape and format retrieved context for AI prompts\",\n \"Implement multi-tenancy with school_id namespace isolation\",\n \"Build FastAPI endpoints for knowledge management\",\n \"Create React hooks for frontend search functionality\"\n ],\n \"limitations\": [\n \"Requires running Context7 service instance and API credentials\",\n \"Does not include PDF text extraction (requires PyPDF2 dependency)\",\n \"Semantic search quality depends on document chunking strategy\",\n \"Token limits must be managed for large context responses\"\n ],\n \"use_cases\": [\n {\n \"target_user\": \"Backend Developers\",\n \"title\": \"Build Knowledge APIs\",\n \"description\": \"Create FastAPI endpoints for document ingestion and semantic search with role-based access control.\"\n },\n {\n \"target_user\": \"Frontend Engineers\",\n \"title\": \"Add Search UI\",\n \"description\": \"Implement React search hooks and components for knowledge base queries with context display.\"\n },\n {\n \"target_user\": \"AI Engineers\",\n \"title\": \"Ground AI Responses\",\n \"description\": \"Provide document-grounded context to AI models using shaped context formatting and token limits.\"\n }\n ],\n \"prompt_templates\": [\n {\n \"title\": \"Basic Document Ingest\",\n \"scenario\": \"Upload a document to knowledge base\",\n \"prompt\": \"Use the Context7 client to ingest a document with title, module, category, and role-based permissions. The document is stored at docs/policies/attendance-policy.md\"\n },\n {\n \"title\": \"Search with Filters\",\n \"scenario\": \"Search knowledge base with tenant isolation\",\n \"prompt\": \"Search the Context7 knowledge base for information about fee refunds. Filter by school_id and user role. Return top 5 relevant chunks with similarity above 0.7.\"\n },\n {\n \"title\": \"Batch Ingestion\",\n \"scenario\": \"Bulk upload documentation\",\n \"prompt\": \"Create a batch ingestion script to upload all markdown files from docs/faq/ directory to Context7. Each file should have module=faq and category=faq.\"\n },\n {\n \"title\": \"Context Shaping\",\n \"scenario\": \"Format retrieved documents for AI\",\n \"prompt\": \"Use ContextShaper to format search results into prompt-safe format. Include source citations, limit to 4000 tokens, and truncate at paragraph boundaries.\"\n }\n ],\n \"output_examples\": [\n {\n \"input\": \"Search the knowledge base for information about student registration procedures\",\n \"output\": [\n \"Found 3 relevant documents:\",\n \"• Student Registration Procedure - Similarity: 0.92\",\n \"• Registration FAQ - Similarity: 0.78\",\n \"• New Student Handbook - Similarity: 0.71\",\n \"\",\n \"Top result provides step-by-step guide for registering new students including required documents, verification steps, and enrollment confirmation.\"\n ]\n },\n {\n \"input\": \"Ingest the attendance policy document with admin and teacher role access\",\n \"output\": [\n \"Document ingested successfully:\",\n \"• ID: doc_abc123\",\n \"• Title: Attendance Policy\",\n \"• Module: attendance\",\n \"• Allowed roles: admin, teacher\",\n \"• School ID: school_001\",\n \"• Source: docs/policies/attendance-policy.md\"\n ]\n }\n ],\n \"best_practices\": [\n \"Always validate documents for PII before ingestion to prevent data leaks\",\n \"Use namespace isolation and school_id filtering for multi-tenant ERP systems\",\n \"Set appropriate max_chunks and min_similarity thresholds to control result quality\"\n ],\n \"anti_patterns\": [\n \"Ingesting sensitive documents without access control metadata\",\n \"Returning full document content without similarity scoring or source attribution\",\n \"Bypassing role-based filters when querying knowledge base\"\n ],\n \"faq\": [\n {\n \"question\": \"What is Context7 and how does it work?\",\n \"answer\": \"Context7 is a knowledge store for document ingestion and semantic search. It chunks documents and enables retrieval-augmented generation with role-based access control.\"\n },\n {\n \"question\": \"Does this skill work with Claude Code?\",\n \"answer\": \"Yes. The skill provides code patterns compatible with Claude, Codex, and Claude Code. Integration follows standard MCP patterns for tool usage.\"\n },\n {\n \"question\": \"How do I set up the Context7 API credentials?\",\n \"answer\": \"Set CONTEXT7_API_KEY and CONTEXT7_API_URL environment variables. The client uses these for authenticated requests to your Context7 instance.\"\n },\n {\n \"question\": \"Is my data safe when ingesting documents?\",\n \"answer\": \"Data safety depends on your deployment. The skill includes role-based access controls and multi-tenancy support. Review documents for PII before ingestion.\"\n },\n {\n \"question\": \"What document formats are supported?\",\n \"answer\": \"Markdown, HTML, and plain text are natively supported. PDF extraction requires PyPDF2 library. The skill handles file type detection by extension.\"\n },\n {\n \"question\": \"How does this compare to vector databases like Pinecone?\",\n \"answer\": \"Context7 provides knowledge-specific features like role-based access, document metadata filtering, and context shaping utilities out of the box.\"\n }\n ]\n },\n \"file_structure\": [\n {\n \"name\": \"scripts\",\n \"type\": \"dir\",\n \"path\": \"scripts\",\n \"children\": [\n {\n \"name\": \"verify.py\",\n \"type\": \"file\",\n \"path\": \"scripts/verify.py\",\n \"lines\": 62\n }\n ]\n },\n {\n \"name\": \"SKILL.md\",\n \"type\": \"file\",\n \"path\": \"SKILL.md\",\n \"lines\": 990\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":10488,"content_sha256":"bf19949c14dca75bb36e2a2c6066f77b0a4a817884f04019cc3987096870249e"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Context7 Integration Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"Expert integration of Context7 for document ingestion, semantic search, and role-scoped context retrieval in ERP applications.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Task","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Method/Endpoint","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ingest document","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"context7_client.ingest_document()","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Batch ingest","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"context7_client.ingest_batch()","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Search context","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"context7_client.search()","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Get document","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"context7_client.get_document()","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete document","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"context7_client.delete_document()","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Project Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"backend/\n├── app/\n│ ├── services/\n│ │ └── context7_client.py # Core Context7 client\n│ ├── api/\n│ │ └── knowledge/\n│ │ └── routes.py # Knowledge API endpoints\n│ └── schemas/\n│ └── knowledge.py # Pydantic schemas\nfrontend/\n├── hooks/\n│ └── useContext7Search.ts # Search hook\n└── components/\n └── knowledge/\n └── ContextSearch.tsx # Search component\ndocs/\n├── policies/ # Source documents\n├── faq/ # FAQ documents\n└── procedures/ # Procedure documents","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Context7 Client","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Core Client Class","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# backend/app/services/context7_client.py\nimport os\nfrom typing import Optional\nfrom pydantic import BaseModel\nfrom enum import Enum\nfrom datetime import datetime\n\n\nclass DocumentType(str, Enum):\n MARKDOWN = \"markdown\"\n PDF = \"pdf\"\n HTML = \"html\"\n TEXT = \"text\"\n\n\nclass DocumentMetadata(BaseModel):\n \"\"\"Metadata for context documents.\"\"\"\n title: str\n description: Optional[str] = None\n # Role-based access\n allowed_roles: list[str] = [] # Empty = all roles\n # Organization scope\n school_id: Optional[str] = None\n # Content categorization\n module: str # e.g., \"fees\", \"attendance\", \"policies\"\n category: Optional[str] = None # e.g., \"faq\", \"procedure\", \"policy\"\n # Language\n language: str = \"en\"\n # Versioning\n version: str = \"1.0\"\n effective_date: Optional[datetime] = None\n expiry_date: Optional[datetime] = None\n # Source tracking\n source_file: Optional[str] = None\n source_url: Optional[str] = None\n\n\nclass ContextDocument(BaseModel):\n \"\"\"Document in Context7.\"\"\"\n id: str\n content: str\n metadata: DocumentMetadata\n chunk_id: Optional[str] = None\n similarity_score: Optional[float] = None\n\n\nclass Context7Client:\n \"\"\"Client for Context7 knowledge store.\"\"\"\n\n def __init__(\n self,\n api_key: Optional[str] = None,\n base_url: Optional[str] = None,\n default_namespace: str = \"default\",\n ):\n self.api_key = api_key or os.getenv(\"CONTEXT7_API_KEY\")\n self.base_url = base_url or os.getenv(\"CONTEXT7_API_URL\", \"https://api.context7.com\")\n self.default_namespace = default_namespace\n self._session = None\n\n def _get_session(self):\n \"\"\"Get or create requests session.\"\"\"\n if not self._session:\n import requests\n self._session = requests.Session()\n if self.api_key:\n self._session.headers.update({\"Authorization\": f\"Bearer {self.api_key}\"})\n return self._session\n\n def _request(\n self,\n method: str,\n endpoint: str,\n **kwargs\n ) -> dict:\n \"\"\"Make API request to Context7.\"\"\"\n session = self._get_session()\n response = session.request(\n method,\n f\"{self.base_url}{endpoint}\",\n **kwargs\n )\n response.raise_for_status()\n return response.json()\n\n # === INGESTION ===\n\n def ingest_document(\n self,\n content: str,\n metadata: DocumentMetadata,\n namespace: Optional[str] = None,\n document_id: Optional[str] = None,\n ) -> dict:\n \"\"\"\n Ingest a single document into Context7.\n\n Args:\n content: Document content (markdown, HTML, or text)\n metadata: Document metadata with tags and access control\n namespace: Optional namespace (defaults to default_namespace)\n document_id: Optional document ID for idempotent updates\n\n Returns:\n Ingestion result with document ID\n \"\"\"\n payload = {\n \"content\": content,\n \"metadata\": metadata.model_dump(),\n \"document_id\": document_id,\n \"namespace\": namespace or self.default_namespace,\n }\n\n return self._request(\"POST\", \"/v1/documents\", json=payload)\n\n def ingest_batch(\n self,\n documents: list[tuple[str, DocumentMetadata]],\n namespace: Optional[str] = None,\n batch_size: int = 10,\n ) -> dict:\n \"\"\"\n Ingest multiple documents in batches.\n\n Args:\n documents: List of (content, metadata) tuples\n namespace: Optional namespace\n batch_size: Number of documents per batch\n\n Returns:\n Batch ingestion result with success/failure counts\n \"\"\"\n results = {\"successful\": 0, \"failed\": 0, \"documents\": []}\n namespace = namespace or self.default_namespace\n\n for i in range(0, len(documents), batch_size):\n batch = documents[i:i + batch_size]\n batch_payload = [\n {\n \"content\": content,\n \"metadata\": metadata.model_dump(),\n \"namespace\": namespace,\n }\n for content, metadata in batch\n ]\n\n try:\n response = self._request(\n \"POST\",\n \"/v1/documents/batch\",\n json={\"documents\": batch_payload}\n )\n results[\"successful\"] += len(batch)\n results[\"documents\"].extend(response.get(\"documents\", []))\n except Exception as e:\n results[\"failed\"] += len(batch)\n # Log failed batch for retry\n\n return results\n\n def ingest_from_file(\n self,\n file_path: str,\n metadata: DocumentMetadata,\n namespace: Optional[str] = None,\n ) -> dict:\n \"\"\"\n Ingest a document from a file.\n\n Args:\n file_path: Path to file (markdown, PDF, or HTML)\n metadata: Document metadata\n namespace: Optional namespace\n\n Returns:\n Ingestion result\n \"\"\"\n # Determine document type from extension\n ext = os.path.splitext(file_path)[1].lower()\n\n if ext == \".md\":\n with open(file_path, \"r\", encoding=\"utf-8\") as f:\n content = f.read()\n doc_type = DocumentType.MARKDOWN\n elif ext == \".pdf\":\n content = self._extract_pdf_text(file_path)\n doc_type = DocumentType.PDF\n elif ext in [\".html\", \".htm\"]:\n with open(file_path, \"r\", encoding=\"utf-8\") as f:\n content = f.read()\n content = self._strip_html(content)\n doc_type = DocumentType.HTML\n else:\n # Default to text\n with open(file_path, \"r\", encoding=\"utf-8\") as f:\n content = f.read()\n doc_type = DocumentType.TEXT\n\n # Update metadata with source file\n metadata.source_file = file_path\n\n return self.ingest_document(content, metadata, namespace)\n\n def _extract_pdf_text(self, file_path: str) -> str:\n \"\"\"Extract text from PDF file.\"\"\"\n try:\n import PyPDF2\n with open(file_path, \"rb\") as f:\n reader = PyPDF2.PdfReader(f)\n text = \"\\n\".join(page.extract_text() for page in reader.pages)\n return text\n except ImportError:\n raise ImportError(\"PyPDF2 required for PDF ingestion: pip install PyPDF2\")\n\n def _strip_html(self, html: str) -> str:\n \"\"\"Strip HTML tags from content.\"\"\"\n import re\n clean = re.compile(\"\u003c.*?>\")\n return re.sub(clean, \"\", html)\n\n # === RETRIEVAL ===\n\n def search(\n self,\n query: str,\n namespace: Optional[str] = None,\n filters: Optional[dict] = None,\n max_chunks: int = 5,\n min_similarity: float = 0.7,\n user_role: Optional[str] = None,\n school_id: Optional[str] = None,\n ) -> list[ContextDocument]:\n \"\"\"\n Search for relevant context documents.\n\n Args:\n query: Search query (semantic search)\n namespace: Namespace to search in\n filters: Additional metadata filters\n max_chunks: Maximum number of chunks to return\n min_similarity: Minimum similarity score threshold\n user_role: User's role for access control\n school_id: User's school ID for multi-tenancy\n\n Returns:\n List of relevant document chunks\n \"\"\"\n # Build search payload with access control\n payload = {\n \"query\": query,\n \"namespace\": namespace or self.default_namespace,\n \"max_chunks\": max_chunks,\n \"min_similarity\": min_similarity,\n \"filters\": filters or {},\n }\n\n # Add role-based filtering\n if user_role:\n payload[\"filters\"][\"allowed_roles\"] = [user_role, \"all\"]\n\n # Add tenant filtering\n if school_id:\n payload[\"filters\"][\"school_id\"] = school_id\n\n response = self._request(\"POST\", \"/v1/search\", json=payload)\n\n return [\n ContextDocument(\n id=doc.get(\"id\"),\n content=doc.get(\"content\", \"\"),\n metadata=DocumentMetadata(**doc.get(\"metadata\", {})),\n chunk_id=doc.get(\"chunk_id\"),\n similarity_score=doc.get(\"similarity_score\"),\n )\n for doc in response.get(\"documents\", [])\n ]\n\n def get_document(\n self,\n document_id: str,\n namespace: Optional[str] = None,\n ) -> Optional[ContextDocument]:\n \"\"\"\n Get a specific document by ID.\n\n Args:\n document_id: Document ID\n namespace: Namespace\n\n Returns:\n Document or None if not found\n \"\"\"\n try:\n response = self._request(\n \"GET\",\n f\"/v1/documents/{document_id}\",\n params={\"namespace\": namespace or self.default_namespace}\n )\n return ContextDocument(\n id=response.get(\"id\"),\n content=response.get(\"content\", \"\"),\n metadata=DocumentMetadata(**response.get(\"metadata\", {})),\n )\n except Exception:\n return None\n\n def delete_document(\n self,\n document_id: str,\n namespace: Optional[str] = None,\n ) -> bool:\n \"\"\"\n Delete a document from Context7.\n\n Args:\n document_id: Document ID\n namespace: Namespace\n\n Returns:\n True if deleted successfully\n \"\"\"\n try:\n self._request(\n \"DELETE\",\n f\"/v1/documents/{document_id}\",\n params={\"namespace\": namespace or self.default_namespace}\n )\n return True\n except Exception:\n return False\n\n # === MANAGEMENT ===\n\n def list_documents(\n self,\n namespace: Optional[str] = None,\n module: Optional[str] = None,\n limit: int = 100,\n ) -> list[dict]:\n \"\"\"\n List documents in a namespace.\n\n Args:\n namespace: Namespace to list\n module: Filter by module\n limit: Maximum number of results\n\n Returns:\n List of document summaries\n \"\"\"\n params = {\n \"namespace\": namespace or self.default_namespace,\n \"limit\": limit,\n }\n if module:\n params[\"module\"] = module\n\n response = self._request(\"GET\", \"/v1/documents\", params=params)\n return response.get(\"documents\", [])\n\n def get_stats(self, namespace: Optional[str] = None) -> dict:\n \"\"\"Get statistics for a namespace.\"\"\"\n response = self._request(\n \"GET\",\n \"/v1/stats\",\n params={\"namespace\": namespace or self.default_namespace}\n )\n return response\n\n\n# Singleton instance\n_context7_client: Optional[Context7Client] = None\n\n\ndef get_context7_client() -> Context7Client:\n \"\"\"Get or create Context7 client singleton.\"\"\"\n global _context7_client\n if _context7_client is None:\n _context7_client = Context7Client()\n return _context7_client","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Context Shaping Utilities","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# backend/app/services/context_shaper.py\nfrom typing import list\nfrom backend.app.services.context7_client import ContextDocument\n\n\nclass ContextShaper:\n \"\"\"Shape and format retrieved context for AI prompts.\"\"\"\n\n MAX_TOKENS = 4000 # Reserve space for prompt\n CHUNK_HEADER = \"### Source: {title}\"\n FOOTER = \"\\n\\n---\\n*Source: {source}*\"\n\n def shape_for_prompt(\n self,\n documents: list[ContextDocument],\n query: str,\n max_chunks: int = 5,\n include_sources: bool = True,\n ) -> str:\n \"\"\"\n Shape retrieved documents into prompt-safe format.\n\n Args:\n documents: Retrieved document chunks\n query: Original search query\n max_chunks: Maximum chunks to include\n include_sources: Include source citations\n\n Returns:\n Formatted context string\n \"\"\"\n chunks = documents[:max_chunks]\n\n sections = []\n for i, doc in enumerate(chunks):\n header = f\"## Chunk {i + 1}\"\n if doc.metadata.title:\n header += f\": {doc.metadata.title}\"\n\n section = header\n section += f\"\\n\\n{self._format_content(doc.content)}\"\n\n if include_sources and doc.metadata.source_file:\n section += self.FOOTER.format(source=doc.metadata.source_file)\n\n sections.append(section)\n\n context = \"\\n\\n\".join(sections)\n\n # Ensure context fits in token limit\n context = self._truncate_to_token_limit(context, self.MAX_TOKENS)\n\n return context\n\n def _format_content(self, content: str) -> str:\n \"\"\"Format content for readability.\"\"\"\n # Normalize whitespace\n lines = content.split(\"\\n\")\n lines = [line.strip() for line in lines if line.strip()]\n return \"\\n\".join(lines)\n\n def _truncate_to_token_limit(self, text: str, max_tokens: int) -> str:\n \"\"\"Truncate text to fit within token limit.\"\"\"\n # Rough estimate: 4 characters per token\n max_chars = max_tokens * 4\n\n if len(text) \u003c= max_chars:\n return text\n\n # Truncate and add note\n truncated = text[:max_chars - 50]\n truncated = truncated.rsplit(\"\\n\", 1)[0] # Don't cut mid-line\n truncated += \"\\n\\n*... (context truncated for length)*\"\n\n return truncated\n\n def format_for_chat(\n self,\n documents: list[ContextDocument],\n user_role: str,\n ) -> str:\n \"\"\"\n Format context for chat widget display.\n\n Args:\n documents: Retrieved documents\n user_role: User's role for messaging\n\n Returns:\n User-friendly formatted context\n \"\"\"\n if not documents:\n return \"No relevant information found.\"\n\n formatted = []\n for doc in documents:\n if doc.metadata.title:\n formatted.append(f\"**{doc.metadata.title}**\")\n formatted.append(doc.content[:500]) # Limit per chunk\n formatted.append(\"\")\n\n return \"\\n\".join(formatted)\n\n\n# Singleton\ncontext_shaper = ContextShaper()","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"API Routes","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# backend/app/api/knowledge/routes.py\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom typing import Optional\nfrom pydantic import BaseModel\n\nfrom app.services.context7_client import (\n get_context7_client,\n DocumentMetadata,\n Context7Client,\n)\nfrom app.services.context_shaper import get_context_shaper, ContextShaper\nfrom app.auth.jwt import get_current_user\n\n\nrouter = APIRouter(prefix=\"/knowledge\", tags=[\"knowledge\"])\n\n\nclass IngestRequest(BaseModel):\n \"\"\"Request to ingest a document.\"\"\"\n content: str\n title: str\n description: Optional[str] = None\n module: str\n category: Optional[str] = None\n allowed_roles: list[str] = []\n school_id: Optional[str] = None\n\n\nclass SearchRequest(BaseModel):\n \"\"\"Request to search knowledge base.\"\"\"\n query: str\n module: Optional[str] = None\n max_chunks: int = 5\n min_similarity: float = 0.7\n\n\nclass SearchResponse(BaseModel):\n \"\"\"Search response with shaped context.\"\"\"\n documents: list[dict]\n context: str # Shaped for prompt\n\n\[email protected](\"/ingest\")\nasync def ingest_document(\n request: IngestRequest,\n current_user = Depends(get_current_user),\n client: Context7Client = Depends(get_context7_client),\n) -> dict:\n \"\"\"\n Ingest a document into the knowledge base.\n\n Requires admin or content-manager role.\n \"\"\"\n # Check permissions\n if \"admin\" not in current_user.roles and \"content-manager\" not in current_user.roles:\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN,\n detail=\"Insufficient permissions to ingest documents\",\n )\n\n # Build metadata\n metadata = DocumentMetadata(\n title=request.title,\n description=request.description,\n allowed_roles=request.allowed_roles or [\"all\"],\n school_id=request.school_id or current_user.school_id,\n module=request.module,\n category=request.category,\n )\n\n # Ingest\n result = client.ingest_document(\n content=request.content,\n metadata=metadata,\n )\n\n return {\"status\": \"ingested\", \"document_id\": result.get(\"id\")}\n\n\[email protected](\"/search\", response_model=SearchResponse)\nasync def search_knowledge(\n request: SearchRequest,\n current_user = Depends(get_current_user),\n client: Context7Client = Depends(get_context7_client),\n shaper: ContextShaper = Depends(get_context_shaper),\n) -> SearchResponse:\n \"\"\"\n Search the knowledge base.\n\n Returns shaped context suitable for AI prompts.\n \"\"\"\n # Search with role and tenant filtering\n documents = client.search(\n query=request.query,\n filters={\"module\": request.module} if request.module else {},\n max_chunks=request.max_chunks,\n min_similarity=request.min_similarity,\n user_role=current_user.role,\n school_id=current_user.school_id,\n )\n\n # Shape for prompt\n context = shaper.shape_for_prompt(\n documents=documents,\n query=request.query,\n max_chunks=request.max_chunks,\n )\n\n return SearchResponse(\n documents=[\n {\n \"id\": doc.id,\n \"title\": doc.metadata.title,\n \"content\": doc.content[:200],\n \"similarity\": doc.similarity_score,\n }\n for doc in documents\n ],\n context=context,\n )\n\n\[email protected](\"/modules\")\nasync def list_modules(\n current_user = Depends(get_current_user),\n client: Context7Client = Depends(get_context7_client),\n) -> dict:\n \"\"\"List available knowledge modules.\"\"\"\n documents = client.list_documents(\n limit=1000,\n )\n\n modules = set()\n for doc in documents:\n if doc.get(\"metadata\", {}).get(\"school_id\") in [None, current_user.school_id]:\n modules.add(doc.get(\"metadata\", {}).get(\"module\"))\n\n return {\"modules\": sorted(modules)}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Frontend Hook","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// frontend/hooks/useContext7Search.ts\nimport { useState, useCallback } from \"react\";\n\ninterface SearchResult {\n id: string;\n title: string;\n content: string;\n similarity: number;\n}\n\ninterface SearchOptions {\n module?: string;\n maxChunks?: number;\n}\n\nexport function useContext7Search() {\n const [results, setResults] = useState\u003cSearchResult[]>([]);\n const [context, setContext] = useState\u003cstring>(\"\");\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState\u003cstring | null>(null);\n\n const search = useCallback(async (\n query: string,\n options: SearchOptions = {}\n ) => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetch(\"/api/v1/knowledge/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query,\n module: options.module,\n max_chunks: options.maxChunks || 5,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\"Search failed\");\n }\n\n const data = await response.json();\n\n setResults(data.documents);\n setContext(data.context);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Search failed\");\n setResults([]);\n setContext(\"\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n const clear = useCallback(() => {\n setResults([]);\n setContext(\"\");\n setError(null);\n }, []);\n\n return {\n search,\n clear,\n results,\n context,\n loading,\n error,\n };\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Document Organization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"docs/\n├── policies/\n│ ├── attendance-policy.md\n│ ├── fee-refund-policy.md\n│ └── grading-policy.md\n├── procedures/\n│ ├── student-registration.md\n│ ├── fee-payment.md\n│ └── transcript-request.md\n├── faq/\n│ ├── fees-faq.md\n│ ├── attendance-faq.md\n│ └── grades-faq.md\n└── handbooks/\n ├── student-handbook.md\n └── parent-handbook.md","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Metadata Examples","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# Fee policy document\nDocumentMetadata(\n title=\"Fee Refund Policy\",\n description=\"Guidelines for fee refunds and cancellations\",\n module=\"fees\",\n category=\"policy\",\n allowed_roles=[\"admin\", \"accountant\", \"parent\", \"student\"],\n school_id=\"school_001\",\n language=\"en\",\n source_file=\"docs/policies/fee-refund-policy.md\",\n)\n\n# Student FAQ\nDocumentMetadata(\n title=\"Fee Payment FAQ\",\n description=\"Common questions about fee payment\",\n module=\"fees\",\n category=\"faq\",\n allowed_roles=[\"student\", \"parent\"],\n school_id=\"school_001\",\n language=\"en\",\n source_file=\"docs/faq/fees-faq.md\",\n)\n\n# Staff procedure\nDocumentMetadata(\n title=\"Student Registration Procedure\",\n description=\"Step-by-step guide for registering new students\",\n module=\"registration\",\n category=\"procedure\",\n allowed_roles=[\"admin\", \"registrar\"],\n school_id=\"school_001\",\n language=\"en\",\n source_file=\"docs/procedures/student-registration.md\",\n)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quality Checklist","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"No PII ingestion","type":"text","marks":[{"type":"strong"}]},{"text":": Sensitive documents reviewed before upload","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Query bounds","type":"text","marks":[{"type":"strong"}]},{"text":": max_chunks, min_similarity prevent excessive results","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Error handling","type":"text","marks":[{"type":"strong"}]},{"text":": Graceful fallback when context unavailable","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Source attribution","type":"text","marks":[{"type":"strong"}]},{"text":": Clear indication when answers are document-based","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Multi-tenancy","type":"text","marks":[{"type":"strong"}]},{"text":": school_id filtering prevents cross-tenant access","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Role filtering","type":"text","marks":[{"type":"strong"}]},{"text":": allowed_roles field controls access","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Token limits","type":"text","marks":[{"type":"strong"}]},{"text":": Context truncation prevents prompt overflow","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration Points","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Integration","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@jwt-auth","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Extract role and school_id from JWT for access control","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@api-client","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API calls for ingest/search endpoints","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@chatkit-widget","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Provide context for AI-powered chat","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@fastapi-app","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Register knowledge API routes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@error-handling","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Handle context retrieval errors gracefully","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Multi-Tenancy","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# Per-school namespace isolation\nclass Context7Client:\n # ...\n\n def search(self, query: str, school_id: str, **kwargs) -> list[ContextDocument]:\n # Always filter by school_id\n return super().search(\n query,\n school_id=school_id,\n filters={\"school_id\": school_id},\n **kwargs\n )\n\n def ingest_document(\n self,\n content: str,\n metadata: DocumentMetadata,\n school_id: str,\n **kwargs\n ) -> dict:\n # Always set school_id on metadata\n metadata.school_id = school_id\n return super().ingest_document(content, metadata, **kwargs)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Batch Ingestion Script","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# scripts/ingest_docs.py\n#!/usr/bin/env python3\n\"\"\"Batch ingest documentation into Context7.\"\"\"\nimport os\nimport sys\nfrom pathlib import Path\n\n# Add project to path\nsys.path.insert(0, str(Path(__file__).parent.parent))\n\nfrom app.services.context7_client import Context7Client, DocumentMetadata\n\n\ndef ingest_directory(\n dir_path: str,\n module: str,\n category: str,\n school_id: str,\n allowed_roles: list[str],\n):\n \"\"\"Ingest all documents in a directory.\"\"\"\n client = Context7Client()\n dir_path = Path(dir_path)\n\n for file_path in dir_path.rglob(\"*.md\"):\n print(f\"Ingesting: {file_path}\")\n\n metadata = DocumentMetadata(\n title=file_path.stem.replace(\"-\", \" \").title(),\n module=module,\n category=category,\n school_id=school_id,\n allowed_roles=allowed_roles,\n source_file=str(file_path),\n )\n\n try:\n client.ingest_from_file(str(file_path), metadata)\n print(f\" ✓ Ingested\")\n except Exception as e:\n print(f\" ✗ Failed: {e}\")\n\n\nif __name__ == \"__main__\":\n import argparse\n\n parser = argparse.ArgumentParser(description=\"Batch ingest documents\")\n parser.add_argument(\"--dir\", required=True, help=\"Directory to ingest\")\n parser.add_argument(\"--module\", required=True, help=\"Document module\")\n parser.add_argument(\"--category\", required=True, help=\"Document category\")\n parser.add_argument(\"--school-id\", required=True, help=\"School ID\")\n parser.add_argument(\"--roles\", default=\"all\", help=\"Comma-separated allowed roles\")\n\n args = parser.parse_args()\n\n ingest_directory(\n args.dir,\n args.module,\n args.category,\n args.school_id,\n args.roles.split(\",\"),\n )","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Error Handling","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# backend/app/services/context7_client.py\n\nclass Context7Error(Exception):\n \"\"\"Base exception for Context7 errors.\"\"\"\n pass\n\n\nclass Context7SearchError(Context7Error):\n \"\"\"Error during context search.\"\"\"\n pass\n\n\nclass Context7IngestError(Context7Error):\n \"\"\"Error during document ingestion.\"\"\"\n pass\n\n\n# Usage in search\ndef search(self, *args, **kwargs) -> list[ContextDocument]:\n try:\n return self._search_impl(*args, **kwargs)\n except Exception as e:\n raise Context7SearchError(f\"Search failed: {e}\") from e\n\n\n# Frontend fallback\nfunction useContext7Search() {\n const { search, results, loading, error } = useContext7Search();\n\n // Fallback to general response if context fails\n const handleSearch = async (query: string) => {\n try {\n await search(query);\n } catch {\n // Use generic response\n setResults([]);\n setContext(\"\");\n }\n };\n\n return { search: handleSearch, results, loading, error };\n}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"context7-integration","author":"@skillopedia","source":{"stars":336,"repo_name":"marketplace","origin_url":"https://github.com/aiskillstore/marketplace/blob/HEAD/skills/awais68/context7-integration/SKILL.md","repo_owner":"aiskillstore","body_sha256":"f327ba03ab3e4229c2e54970860288b6c6bfd4fdcb10b73f17e726f707636947","cluster_key":"deeeeff51e86f1a6d6c7f04f45ae331b5062ff254d27216e0fcfbcde9fc30a33","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aiskillstore/marketplace/skills/awais68/context7-integration/SKILL.md","attachments":[{"id":"2a7ac485-0379-5b28-bd2f-aa5f6c94b846","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2a7ac485-0379-5b28-bd2f-aa5f6c94b846/attachment.py","path":"scripts/verify.py","size":1902,"sha256":"2506808ccdd732a3b016fbdb5bb7d919d31c867996cd7b28beb5438bf2329ea2","contentType":"text/x-python; charset=utf-8"},{"id":"2dc0d62c-ae25-50d0-b8c1-6a24bc12bc30","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2dc0d62c-ae25-50d0-b8c1-6a24bc12bc30/attachment.json","path":"skill-report.json","size":10488,"sha256":"bf19949c14dca75bb36e2a2c6066f77b0a4a817884f04019cc3987096870249e","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"13e279350a72ed1757441f1cb0b643438585934decc062053b801dac89429789","attachment_count":2,"text_attachments":2,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/awais68/context7-integration/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"data-analytics","category_label":"Data"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"data-analytics","import_tag":"clean-skills-v1","description":"Use when integrating Context7 (knowledge/context store) for document ingestion,\nsemantic search, or scoped context retrieval.\nTriggers for: uploading documents, searching knowledge base, filtering by role/tenant,\nor providing AI with document-grounded context.\nNOT for: general database queries, file storage without context semantics, or non-document content.\n"}},"renderedAt":1782986758701}

Context7 Integration Skill Expert integration of Context7 for document ingestion, semantic search, and role-scoped context retrieval in ERP applications. Quick Reference | Task | Method/Endpoint | |------|-----------------| | Ingest document | | | Batch ingest | | | Search context | | | Get document | | | Delete document | | Project Structure Context7 Client Core Client Class Context Shaping Utilities API Routes Frontend Hook Document Organization Metadata Examples Quality Checklist - [ ] No PII ingestion : Sensitive documents reviewed before upload - [ ] Query bounds : max chunks, min simila…