Skip to content

Commit a91d20e

Browse files
committed
completed the flask-mcp-compare servers
1 parent aeb4c2d commit a91d20e

8 files changed

Lines changed: 394 additions & 0 deletions

File tree

flask-mcp-compare/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Flask MCP Server Comparison
2+
3+
## Setting up the Environment
4+
5+
Execute the below commands on your terminal /
6+
command prompt
7+
8+
### Pre Requisites:
9+
10+
- Python
11+
- Pip
12+
- Git
13+
- Anthropic API key
14+
15+
Update the anthropic API key in the .env file
16+
17+
### Steps to execute:
18+
19+
1. Clone the repo
20+
21+
git clone
22+
https://github.com/insightbuilder/codeai_fusion.git
23+
24+
2. Change into flask-mcp-compare folder:
25+
26+
cd flask-mcp-compare
27+
28+
3. Create virtual environment
29+
30+
python -m venv .venv
31+
32+
Ensure the .venv folder is created. Add that
33+
folder to your .gitignore
34+
35+
4. Activate virtual environment
36+
37+
source .venv/bin/activate in linux
38+
.venv\Scripts\activate in windows
39+
40+
5. Install requirements
41+
42+
pip install -r requirements.txt
43+
44+
#### Running the Flask App
45+
46+
python flaskapp.py
47+
48+
#### Running the MCP Server
49+
50+
python mcpclient.py mcpserver.py
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Flask MCP Server Comparison
2+
3+
## Setting up the Environment
4+
5+
Execute the below commands on your terminal /
6+
command prompt
7+
8+
### Pre Requisites:
9+
10+
- Python
11+
- Pip
12+
- Git
13+
- Anthropic API key
14+
15+
Update the anthropic API key in the .env file
16+
17+
### Steps to execute:
18+
19+
1. Clone the repo
20+
21+
git clone
22+
https://github.com/insightbuilder/codeai_fusion.git
23+
24+
2. Change into flask-mcp-compare folder:
25+
26+
cd flask-mcp-compare
27+
28+
3. Create virtual environment
29+
30+
python -m venv .venv
31+
32+
Ensure the .venv folder is created. Add that
33+
folder to your .gitignore
34+
35+
4. Activate virtual environment
36+
37+
source .venv/bin/activate in linux
38+
.venv\Scripts\activate in windows
39+
40+
5. Install requirements
41+
42+
pip install -r requirements.txt
43+
44+
#### Running the Flask App
45+
46+
python flaskapp.py
47+
48+
#### Running the MCP Server
49+
50+
python mcpclient.py mcpserver.py

flask-mcp-compare/flaskapp.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from flask import Flask, render_template, request
2+
3+
app = Flask(__name__)
4+
5+
6+
@app.route("/", methods=["GET", "POST"])
7+
def index():
8+
bmi = None
9+
category = None
10+
11+
if request.method == "POST":
12+
weight = float(request.form.get("weight", 0))
13+
height = float(request.form.get("height", 0)) / 100 # convert cm to meters
14+
15+
if height > 0:
16+
bmi = round(weight / (height**2), 2)
17+
if bmi < 18.5:
18+
category = "Underweight"
19+
elif bmi < 25:
20+
category = "Normal weight"
21+
elif bmi < 30:
22+
category = "Overweight"
23+
else:
24+
category = "Obese"
25+
26+
return render_template("index.html", bmi=bmi, category=category)
27+
28+
29+
if __name__ == "__main__":
30+
app.run(debug=True)

flask-mcp-compare/mcpclient.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import asyncio
2+
from typing import Optional
3+
from contextlib import AsyncExitStack
4+
5+
# pyright: reportMissingImports=false
6+
# pyright: reportOptionalSubscript=false
7+
8+
from mcp import ClientSession, StdioServerParameters
9+
from mcp.client.stdio import stdio_client
10+
11+
from anthropic import Anthropic
12+
from dotenv import load_dotenv
13+
14+
# uncomment this when running in your local environment
15+
# ensure you have updated the .env file with the Anthropic API Key
16+
# load_dotenv() # load environment variables from .env
17+
18+
19+
class MCPClient:
20+
def __init__(self):
21+
# Initialize session and client objects
22+
self.session: Optional[ClientSession] = None
23+
self.exit_stack = AsyncExitStack()
24+
self.anthropic = Anthropic()
25+
26+
# methods will go here
27+
async def connect_to_server(self, server_script_path: str):
28+
"""Connect to an MCP server
29+
30+
Args:
31+
server_script_path: Path to the server script (.py or .js)
32+
"""
33+
is_python = server_script_path.endswith(".py")
34+
is_js = server_script_path.endswith(".js")
35+
if not (is_python or is_js):
36+
raise ValueError("Server script must be a .py or .js file")
37+
38+
command = "python" if is_python else "node"
39+
server_params = StdioServerParameters(
40+
command=command, args=[server_script_path], env=None
41+
)
42+
43+
stdio_transport = await self.exit_stack.enter_async_context(
44+
stdio_client(server_params)
45+
)
46+
self.stdio, self.write = stdio_transport
47+
self.session = await self.exit_stack.enter_async_context(
48+
ClientSession(self.stdio, self.write)
49+
)
50+
51+
await self.session.initialize()
52+
53+
# List available tools
54+
response = await self.session.list_tools()
55+
tools = response.tools
56+
print("\nConnected to server with tools:", [tool.name for tool in tools])
57+
58+
async def process_query(self, query: str) -> str:
59+
"""Process a query using Claude and available tools"""
60+
messages = [{"role": "user", "content": query}]
61+
62+
response = await self.session.list_tools()
63+
available_tools = [
64+
{
65+
"name": tool.name,
66+
"description": tool.description,
67+
"input_schema": tool.inputSchema,
68+
}
69+
for tool in response.tools
70+
]
71+
72+
# Initial Claude API call
73+
response = self.anthropic.messages.create(
74+
model="claude-3-5-haiku-20241022",
75+
max_tokens=1000,
76+
messages=messages,
77+
tools=available_tools,
78+
)
79+
80+
# Process response and handle tool calls
81+
tool_results = []
82+
final_text = []
83+
84+
for content in response.content:
85+
if content.type == "text":
86+
final_text.append(content.text)
87+
elif content.type == "tool_use":
88+
tool_name = content.name
89+
tool_args = content.input
90+
91+
# Execute tool call
92+
result = await self.session.call_tool(tool_name, tool_args)
93+
tool_results.append({"call": tool_name, "result": result})
94+
final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")
95+
96+
# Continue conversation with tool results
97+
if hasattr(content, "text") and content.text:
98+
messages.append({"role": "assistant", "content": content.text})
99+
messages.append({"role": "user", "content": result.content})
100+
101+
# Get next response from Claude
102+
response = self.anthropic.messages.create(
103+
model="claude-3-5-haiku-20241022",
104+
max_tokens=1000,
105+
messages=messages,
106+
)
107+
108+
final_text.append(response.content[0].text)
109+
110+
return "\n".join(final_text)
111+
112+
async def chat_loop(self):
113+
"""Run an interactive chat loop"""
114+
print("\nMCP Client Started!")
115+
print("Type your queries or 'quit' to exit.")
116+
117+
while True:
118+
try:
119+
query = input("\nQuery: ").strip()
120+
121+
if query.lower() == "quit":
122+
break
123+
124+
response = await self.process_query(query)
125+
print("\n" + response)
126+
127+
except Exception as e:
128+
print(f"\nError: {str(e)}")
129+
130+
async def cleanup(self):
131+
"""Clean up resources"""
132+
await self.exit_stack.aclose()
133+
134+
135+
async def main():
136+
if len(sys.argv) < 2:
137+
print("Usage: python mcpclient.py mcpserver.py")
138+
sys.exit(1)
139+
140+
client = MCPClient()
141+
try:
142+
await client.connect_to_server(sys.argv[1])
143+
await client.chat_loop()
144+
finally:
145+
await client.cleanup()
146+
147+
148+
if __name__ == "__main__":
149+
import sys
150+
151+
asyncio.run(main())

flask-mcp-compare/mcpserver.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from mcp.server.fastmcp import FastMCP
2+
3+
mcp = FastMCP("Echo")
4+
5+
6+
@mcp.tool()
7+
def bmi_calculator(weight: float, height: float) -> str:
8+
"""Calculates the BMI using the given weight and height, and returns the value"""
9+
if height > 0 and weight > 0:
10+
bmi = round(weight / (height**2), 2)
11+
12+
return f"Your BMI: {bmi}"
13+
14+
return "Height and weight have to be more than 0"
15+
16+
17+
@mcp.tool()
18+
def custom_eqn(a: float, b: float, d: float) -> float:
19+
"""Performs a custom equation with the given parameters and returns the result"""
20+
x = 25
21+
c = a + b * b
22+
return a * (x ^ 3) - b * (x ^ 2) + c * x - d
23+
24+
25+
if __name__ == "__main__":
26+
print("Starting MCP server...")
27+
mcp.run()

flask-mcp-compare/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mcp[cli]
2+
mcp
3+
python-dotenv
4+
flask
5+
anthropic

flask-mcp-compare/static/style.css

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
body {
2+
font-family: Arial, sans-serif;
3+
background: #f3f3f3;
4+
margin: 0;
5+
padding: 0;
6+
}
7+
8+
.container {
9+
max-width: 600px;
10+
margin: 40px auto;
11+
padding: 30px;
12+
background: #fff;
13+
border-radius: 12px;
14+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
15+
}
16+
17+
.calculator h2 {
18+
color: #4CAF50;
19+
}
20+
21+
form {
22+
display: flex;
23+
flex-direction: column;
24+
}
25+
26+
input, button {
27+
padding: 10px;
28+
margin: 8px 0;
29+
border-radius: 6px;
30+
border: 1px solid #ccc;
31+
}
32+
33+
button {
34+
background: #4CAF50;
35+
color: white;
36+
border: none;
37+
cursor: pointer;
38+
}
39+
40+
.result {
41+
margin-top: 20px;
42+
background: #e7f3e7;
43+
padding: 10px;
44+
border-left: 4px solid #4CAF50;
45+
}
46+

0 commit comments

Comments
 (0)