Last active 1 month ago

Query up-to-date, version-specific documentation for any programming library. Search for libraries and get relevant code examples and documentation.

liusijin revised this gist 1 month ago. Go to revision

1 file changed, 8 insertions, 2 deletions

Context7.py

@@ -4,6 +4,7 @@
4 4 import json
5 5 import urllib.request
6 6 import urllib.parse
7 + import ssl
7 8 import os
8 9
9 10 CONTEXT7_API = "https://context7.com/api"
@@ -25,8 +26,13 @@ def context7_get(endpoint, params=None):
25 26 if API_KEY:
26 27 headers["Authorization"] = f"Bearer {API_KEY}"
27 28
29 + # Create SSL context for mitmproxy compatibility
30 + ssl_context = ssl.create_default_context()
31 + ssl_context.check_hostname = False
32 + ssl_context.verify_mode = ssl.CERT_NONE
33 +
28 34 req = urllib.request.Request(url, headers=headers)
29 - resp = urllib.request.urlopen(req, timeout=30)
35 + resp = urllib.request.urlopen(req, timeout=30, context=ssl_context)
30 36
31 37 content_type = resp.headers.get("Content-Type", "")
32 38 if "application/json" in content_type:
@@ -34,7 +40,7 @@ def context7_get(endpoint, params=None):
34 40 else:
35 41 return resp.read().decode()
36 42 except Exception as e:
37 - return {"error": str(e)}
43 + return {"error": f"{type(e).__name__}: {e}"}
38 44
39 45 @register_tool(
40 46 "context7_search",

liusijin revised this gist 1 month ago. Go to revision

No changes

liusijin revised this gist 1 month ago. Go to revision

No changes

liusijin revised this gist 1 month ago. Go to revision

1 file changed, 0 insertions, 0 deletions

context7.py renamed to Context7.py

File renamed without changes

liusijin revised this gist 1 month ago. Go to revision

1 file changed, 0 insertions, 0 deletions

context7 renamed to context7.py

File renamed without changes

liusijin revised this gist 1 month ago. Go to revision

No changes

liusijin revised this gist 1 month ago. Go to revision

1 file changed, 117 insertions

context7(file created)

@@ -0,0 +1,117 @@
1 + #!/usr/bin/env python3
2 + """Context7 extension - Query up-to-date documentation for any programming library"""
3 +
4 + import json
5 + import urllib.request
6 + import urllib.parse
7 + import os
8 +
9 + CONTEXT7_API = "https://context7.com/api"
10 + API_KEY = os.environ.get("CONTEXT7_API_KEY") # Optional, for higher rate limits
11 +
12 + def context7_get(endpoint, params=None):
13 + """Make GET request to Context7 API"""
14 + try:
15 + url = f"{CONTEXT7_API}{endpoint}"
16 + if params:
17 + url += "?" + urllib.parse.urlencode(params)
18 +
19 + headers = {
20 + "X-Context7-Source": "mcp",
21 + "Accept": "application/json"
22 + }
23 +
24 + # Add API key if available
25 + if API_KEY:
26 + headers["Authorization"] = f"Bearer {API_KEY}"
27 +
28 + req = urllib.request.Request(url, headers=headers)
29 + resp = urllib.request.urlopen(req, timeout=30)
30 +
31 + content_type = resp.headers.get("Content-Type", "")
32 + if "application/json" in content_type:
33 + return json.loads(resp.read().decode())
34 + else:
35 + return resp.read().decode()
36 + except Exception as e:
37 + return {"error": str(e)}
38 +
39 + @register_tool(
40 + "context7_search",
41 + "Search for libraries by name (e.g., 'react', 'express', 'django')",
42 + {"query": "string"}
43 + )
44 + def context7_search(args):
45 + """Search for libraries in Context7"""
46 + query = args.get("query", "")
47 + if not query:
48 + return "error: query required"
49 +
50 + result = context7_get("/v1/search", {"query": query})
51 +
52 + if isinstance(result, dict) and "error" in result:
53 + return f"error: {result['error']}"
54 +
55 + if isinstance(result, dict):
56 + results = result.get("results", [])
57 + else:
58 + return f"error: Unexpected response format"
59 +
60 + if not results:
61 + return f"No libraries found for: {query}"
62 +
63 + # Format results
64 + output = f"Found {len(results)} libraries:\n\n"
65 + for lib in results[:5]: # Top 5
66 + output += f"• {lib.get('title', 'Unknown')}\n"
67 + output += f" ID: {lib.get('id', 'N/A')}\n"
68 + if lib.get('description'):
69 + output += f" {lib['description']}\n"
70 + output += f" Snippets: {lib.get('totalSnippets', 0)}\n"
71 + output += f" Trust Score: {lib.get('trustScore', 0)}\n"
72 + if lib.get('versions'):
73 + output += f" Versions: {', '.join(lib['versions'][:3])}\n"
74 + output += "\n"
75 +
76 + # Suggest using the top result
77 + if results:
78 + top_lib = results[0]
79 + lib_id = top_lib.get('id', '')
80 + output += f"To get documentation:\ncontext7_docs({{\"library_id\": \"{lib_id}\", \"topic\": \"your topic\"}})"
81 +
82 + return output
83 +
84 + @register_tool(
85 + "context7_docs",
86 + "Get documentation for a library using its Context7 ID",
87 + {"library_id": "string", "topic": "string?", "tokens": "number?"}
88 + )
89 + def context7_docs(args):
90 + """Get library documentation from Context7"""
91 + library_id = args.get("library_id", "")
92 + topic = args.get("topic", "")
93 + tokens = args.get("tokens", 5000)
94 +
95 + if not library_id:
96 + return "error: library_id required (use context7_search first)"
97 +
98 + # Ensure minimum tokens
99 + if tokens < 1000:
100 + tokens = 1000
101 +
102 + params = {
103 + "tokens": tokens,
104 + "type": "txt"
105 + }
106 + if topic:
107 + params["topic"] = topic
108 +
109 + result = context7_get(f"/v1{library_id}", params)
110 +
111 + if isinstance(result, dict) and "error" in result:
112 + return f"error: {result['error']}"
113 +
114 + if not result or result == "null":
115 + return f"No documentation found for {library_id}. Try using context7_search first."
116 +
117 + return result
Newer Older