Last active 1 month ago

Access AI-generated documentation for any GitHub repository. Ask questions, get documentation structure, and read full contents.

DeepWiki.py Raw
1#!/usr/bin/env python3
2"""DeepWiki extension - MCP HTTP client for GitHub repo documentation"""
3
4import json
5import urllib.request
6import ssl
7import time
8
9def mcp_call(tool_name, arguments):
10 """Make MCP JSON-RPC call to DeepWiki"""
11 url = "https://mcp.deepwiki.com/mcp"
12 request_id = str(int(time.time() * 1000))
13
14 data = {
15 "jsonrpc": "2.0",
16 "id": request_id,
17 "method": "tools/call",
18 "params": {
19 "name": tool_name,
20 "arguments": arguments
21 }
22 }
23
24 try:
25 # Create SSL context that doesn't verify certificates for mitmproxy
26 ssl_context = ssl.create_default_context()
27 ssl_context.check_hostname = False
28 ssl_context.verify_mode = ssl.CERT_NONE
29
30 req = urllib.request.Request(
31 url,
32 json.dumps(data).encode(),
33 {
34 "Content-Type": "application/json",
35 "Accept": "application/json, text/event-stream"
36 }
37 )
38 resp = urllib.request.urlopen(req, timeout=60, context=ssl_context)
39
40 # Handle SSE response
41 response_text = resp.read().decode()
42
43 # Parse SSE format: extract JSON from "data: " lines
44 for line in response_text.split('\n'):
45 if line.startswith('data: '):
46 data_str = line[6:].strip() # Skip "data: " prefix
47
48 # Skip ping events
49 if data_str == "ping":
50 continue
51
52 try:
53 result = json.loads(data_str)
54
55 if "error" in result:
56 return f"error: {result['error'].get('message', str(result['error']))}"
57
58 # Extract text from MCP response
59 content = result.get("result", {}).get("content", [])
60 if content:
61 texts = [item["text"] for item in content if item.get("type") == "text"]
62 if texts:
63 return "\n".join(texts)
64 except json.JSONDecodeError:
65 continue
66
67 return "error: No valid data in response"
68 except Exception as e:
69 return f"error: {type(e).__name__}: {e}"
70
71@register_tool(
72 "deepwiki_ask",
73 "Ask questions about GitHub repo",
74 {"repo": "string", "question": "string"}
75)
76def deepwiki_ask(args):
77 """Ask a question about a GitHub repository (format: owner/repo)"""
78 return mcp_call("ask_question", {
79 "repoName": args["repo"],
80 "question": args["question"]
81 })
82
83@register_tool(
84 "deepwiki_structure",
85 "Get repo documentation structure",
86 {"repo": "string"}
87)
88def deepwiki_structure(args):
89 """Get documentation structure/topics for a GitHub repository (format: owner/repo)"""
90 return mcp_call("read_wiki_structure", {
91 "repoName": args["repo"]
92 })
93
94@register_tool(
95 "deepwiki_contents",
96 "Get repo documentation contents",
97 {"repo": "string"}
98)
99def deepwiki_contents(args):
100 """Get full documentation contents for a GitHub repository (format: owner/repo)"""
101 return mcp_call("read_wiki_contents", {
102 "repoName": args["repo"]
103 })
104