mirror of
https://github.com/Shubhamsaboo/awesome-llm-apps.git
synced 2026-03-09 07:25:00 -05:00
- Replaced Node.js MCP server with the official GitHub MCP server running in Docker. - Added OpenAI API key input for enhanced query processing. - Updated README to reflect new requirements and usage instructions.
158 lines
6.1 KiB
Python
158 lines
6.1 KiB
Python
import asyncio
|
|
import os
|
|
import streamlit as st
|
|
from textwrap import dedent
|
|
from agno.agent import Agent
|
|
from agno.tools.mcp import MCPTools
|
|
from mcp import ClientSession, StdioServerParameters
|
|
from mcp.client.stdio import stdio_client
|
|
|
|
st.set_page_config(page_title="🐙 GitHub MCP Agent", page_icon="🐙", layout="wide")
|
|
|
|
st.markdown("<h1 class='main-header'>🐙 GitHub MCP Agent</h1>", unsafe_allow_html=True)
|
|
st.markdown("Explore GitHub repositories with natural language using the Model Context Protocol")
|
|
|
|
with st.sidebar:
|
|
st.header("🔑 Authentication")
|
|
|
|
openai_key = st.text_input("OpenAI API Key", type="password",
|
|
help="Required for the AI agent to interpret queries and format results")
|
|
if openai_key:
|
|
os.environ["OPENAI_API_KEY"] = openai_key
|
|
|
|
github_token = st.text_input("GitHub Token", type="password",
|
|
help="Create a token with repo scope at github.com/settings/tokens")
|
|
if github_token:
|
|
os.environ["GITHUB_TOKEN"] = github_token
|
|
|
|
st.markdown("---")
|
|
st.markdown("### Example Queries")
|
|
|
|
st.markdown("**Issues**")
|
|
st.markdown("- Show me issues by label")
|
|
st.markdown("- What issues are being actively discussed?")
|
|
|
|
st.markdown("**Pull Requests**")
|
|
st.markdown("- What PRs need review?")
|
|
st.markdown("- Show me recent merged PRs")
|
|
|
|
st.markdown("**Repository**")
|
|
st.markdown("- Show repository health metrics")
|
|
st.markdown("- Show repository activity patterns")
|
|
|
|
st.markdown("---")
|
|
st.caption("Note: Always specify the repository in your query if not already selected in the main input.")
|
|
|
|
col1, col2 = st.columns([3, 1])
|
|
with col1:
|
|
repo = st.text_input("Repository", value="Shubhamsaboo/awesome-llm-apps", help="Format: owner/repo")
|
|
with col2:
|
|
query_type = st.selectbox("Query Type", [
|
|
"Issues", "Pull Requests", "Repository Activity", "Custom"
|
|
])
|
|
|
|
if query_type == "Issues":
|
|
query_template = f"Find issues labeled as bugs in {repo}"
|
|
elif query_type == "Pull Requests":
|
|
query_template = f"Show me recent merged PRs in {repo}"
|
|
elif query_type == "Repository Activity":
|
|
query_template = f"Analyze code quality trends in {repo}"
|
|
else:
|
|
query_template = ""
|
|
|
|
query = st.text_area("Your Query", value=query_template,
|
|
placeholder="What would you like to know about this repository?")
|
|
|
|
async def run_github_agent(message):
|
|
if not os.getenv("GITHUB_TOKEN"):
|
|
return "Error: GitHub token not provided"
|
|
|
|
if not os.getenv("OPENAI_API_KEY"):
|
|
return "Error: OpenAI API key not provided"
|
|
|
|
try:
|
|
server_params = StdioServerParameters(
|
|
command="docker",
|
|
args=[
|
|
"run", "-i", "--rm",
|
|
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
"-e", "GITHUB_TOOLSETS",
|
|
"ghcr.io/github/github-mcp-server"
|
|
],
|
|
env={
|
|
**os.environ,
|
|
"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv('GITHUB_TOKEN'),
|
|
"GITHUB_TOOLSETS": "repos,issues,pull_requests"
|
|
}
|
|
)
|
|
|
|
async with stdio_client(server_params) as (read, write):
|
|
async with ClientSession(read, write) as session:
|
|
mcp_tools = MCPTools(session=session)
|
|
await mcp_tools.initialize()
|
|
|
|
agent = Agent(
|
|
tools=[mcp_tools],
|
|
instructions=dedent("""\
|
|
You are a GitHub assistant. Help users explore repositories and their activity.
|
|
- Provide organized, concise insights about the repository
|
|
- Focus on facts and data from the GitHub API
|
|
- Use markdown formatting for better readability
|
|
- Present numerical data in tables when appropriate
|
|
- Include links to relevant GitHub pages when helpful
|
|
"""),
|
|
markdown=True,
|
|
)
|
|
|
|
response = await asyncio.wait_for(agent.arun(message), timeout=120.0)
|
|
return response.content
|
|
|
|
except asyncio.TimeoutError:
|
|
return "Error: Request timed out after 120 seconds"
|
|
except Exception as e:
|
|
return f"Error: {str(e)}"
|
|
|
|
if st.button("🚀 Run Query", type="primary", use_container_width=True):
|
|
if not openai_key:
|
|
st.error("Please enter your OpenAI API key in the sidebar")
|
|
elif not github_token:
|
|
st.error("Please enter your GitHub token in the sidebar")
|
|
elif not query:
|
|
st.error("Please enter a query")
|
|
else:
|
|
with st.spinner("Analyzing GitHub repository..."):
|
|
if repo and repo not in query:
|
|
full_query = f"{query} in {repo}"
|
|
else:
|
|
full_query = query
|
|
|
|
result = asyncio.run(run_github_agent(full_query))
|
|
|
|
st.markdown("### Results")
|
|
st.markdown(result)
|
|
|
|
if 'result' not in locals():
|
|
st.markdown(
|
|
"""<div class='info-box'>
|
|
<h4>How to use this app:</h4>
|
|
<ol>
|
|
<li>Enter your <strong>OpenAI API key</strong> in the sidebar (powers the AI agent)</li>
|
|
<li>Enter your <strong>GitHub token</strong> in the sidebar</li>
|
|
<li>Specify a repository (e.g., Shubhamsaboo/awesome-llm-apps)</li>
|
|
<li>Select a query type or write your own</li>
|
|
<li>Click 'Run Query' to see results</li>
|
|
</ol>
|
|
<p><strong>How it works:</strong></p>
|
|
<ul>
|
|
<li>Uses the official GitHub MCP server via Docker for real-time access to GitHub API</li>
|
|
<li>AI Agent (powered by OpenAI) interprets your queries and calls appropriate GitHub APIs</li>
|
|
<li>Results are formatted in readable markdown with insights and links</li>
|
|
<li>Queries work best when focused on specific aspects like issues, PRs, or repository info</li>
|
|
</ul>
|
|
</div>""",
|
|
unsafe_allow_html=True
|
|
)
|
|
|
|
st.markdown("---")
|
|
st.write("Built with Streamlit, Agno, and Model Context Protocol ❤️")
|