pgurazada1 commited on
Commit
ecbc1ec
·
verified ·
1 Parent(s): 870bab9

Update server.py

Browse files
Files changed (1) hide show
  1. server.py +44 -194
server.py CHANGED
@@ -1,120 +1,10 @@
1
- # import os
2
- # import uvicorn
3
- # import inspect
4
-
5
- # from mcp.server.fastmcp import FastMCP
6
- # from starlette.requests import Request
7
- # from starlette.responses import PlainTextResponse, JSONResponse
8
-
9
- # from langchain_community.utilities import SQLDatabase
10
- # from langchain_community.tools.sql_database.tool import QuerySQLCheckerTool
11
- # from langchain_openai import ChatOpenAI
12
-
13
- # llm = ChatOpenAI(
14
- # api_key=os.environ.get('OPENAI_API_KEY', None),
15
- # base_url=os.environ['OPENAI_BASE_URL'],
16
- # model='gpt-4o-mini',
17
- # temperature=0
18
- # )
19
-
20
- # # Create an MCP server and the tool registry
21
- # mcp = FastMCP("Credit Card Database Server")
22
- # tool_registry = []
23
-
24
- # def register_tool(fn):
25
- # """Decorator to register tool metadata and with MCP."""
26
- # # Register with MCP
27
- # mcp.tool()(fn)
28
- # # Save metadata
29
- # sig = inspect.signature(fn)
30
- # params = [
31
- # {
32
- # "name": param.name,
33
- # "type": str(param.annotation) if param.annotation is not inspect._empty else "Any",
34
- # "default": param.default if param.default is not inspect._empty else None,
35
- # }
36
- # for param in sig.parameters.values()
37
- # ]
38
- # tool_registry.append({
39
- # "name": fn.__name__,
40
- # "description": fn.__doc__.strip() if fn.__doc__ else "",
41
- # "parameters": params,
42
- # })
43
- # return fn
44
-
45
- # credit_card_db = SQLDatabase.from_uri(r"sqlite:///data/ccms.db")
46
- # query_checker_tool = QuerySQLCheckerTool(db=credit_card_db, llm=llm)
47
-
48
- # @mcp.custom_route("/", methods=["GET"])
49
- # async def home(request: Request) -> PlainTextResponse:
50
- # return PlainTextResponse(
51
- # """
52
- # Credit Card Database MCP Server
53
- # ----
54
- # Use the following URL to connect with this server
55
- # https://pgurazada1-credit-card-database-mcp-server.hf.space/mcp/
56
-
57
- # Access the following URL for a list of tools and their documentation.
58
- # https://pgurazada1-credit-card-database-mcp-server.hf.space/tools/
59
- # """
60
- # )
61
-
62
- # @register_tool
63
- # def sql_db_list_tables():
64
- # """
65
- # Returns a comma-separated list of table names in the database.
66
- # """
67
- # return credit_card_db.get_usable_table_names()
68
-
69
- # @register_tool
70
- # def sql_db_schema(table_names: list[str]) -> str:
71
- # """
72
- # Input 'table_names_str' is a comma-separated string of table names.
73
- # Returns the DDL SQL schema for these tables.
74
- # """
75
- # return credit_card_db.get_table_info(table_names)
76
-
77
- # @register_tool
78
- # def sql_db_query_checker(query: str) -> str:
79
- # """
80
- # Input 'query' is a SQL query string.
81
- # Checks if the query is valid.
82
- # If the query is valid, it returns the original query.
83
- # If the query is not valid, it returns the corrected query.
84
- # This tool is used to ensure the query is valid before executing it.
85
- # """
86
- # return query_checker_tool.run(query)
87
-
88
- # @register_tool
89
- # def sql_db_query(query: str) -> str:
90
- # """
91
- # Input 'query' is a SQL query string.
92
- # Executes the query (SELECT only) and returns the result.
93
- # """
94
- # return credit_card_db.run(query)
95
-
96
- # @mcp.custom_route("/tools", methods=["GET"])
97
- # async def list_tools(request: Request) -> JSONResponse:
98
- # """Return all registered tool metadata as JSON."""
99
- # return JSONResponse(tool_registry)
100
-
101
- # if __name__ == "__main__":
102
- # uvicorn.run(mcp.streamable_http_app, host="0.0.0.0", port=8000)
103
-
104
-
105
- ##--- version with Google OAuth---
106
-
107
  import os
108
  import uvicorn
109
  import inspect
110
 
111
  from mcp.server.fastmcp import FastMCP
112
  from starlette.requests import Request
113
- from starlette.responses import PlainTextResponse, JSONResponse, RedirectResponse
114
- from starlette.middleware.sessions import SessionMiddleware
115
- from fastapi import FastAPI
116
-
117
- from authlib.integrations.starlette_client import OAuth, OAuthError
118
 
119
  from langchain_community.utilities import SQLDatabase
120
  from langchain_community.tools.sql_database.tool import QuerySQLCheckerTool
@@ -127,37 +17,15 @@ llm = ChatOpenAI(
127
  temperature=0
128
  )
129
 
130
- credit_card_db = SQLDatabase.from_uri(r"sqlite:///data/ccms.db")
131
- query_checker_tool = QuerySQLCheckerTool(db=credit_card_db, llm=llm)
132
-
133
- # Google OAuth config - set these in your environment
134
- GOOGLE_CLIENT_ID = os.environ["GOOGLE_CLIENT_ID"]
135
- GOOGLE_CLIENT_SECRET = os.environ["GOOGLE_CLIENT_SECRET"]
136
- SECRET_KEY = os.environ.get("SESSION_SECRET", "supersecret") # should be set securely
137
-
138
- # FastAPI app & session middleware
139
- app = FastAPI()
140
- app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
141
-
142
- # Set up OAuth
143
- oauth = OAuth()
144
- CONF_URL = 'https://accounts.google.com/.well-known/openid-configuration'
145
- oauth.register(
146
- name='google',
147
- client_id=GOOGLE_CLIENT_ID,
148
- client_secret=GOOGLE_CLIENT_SECRET,
149
- server_metadata_url=CONF_URL,
150
- client_kwargs={
151
- 'scope': 'openid email profile'
152
- }
153
- )
154
-
155
- # MCP
156
  mcp = FastMCP("Credit Card Database Server")
157
  tool_registry = []
158
 
159
  def register_tool(fn):
 
 
160
  mcp.tool()(fn)
 
161
  sig = inspect.signature(fn)
162
  params = [
163
  {
@@ -174,79 +42,61 @@ def register_tool(fn):
174
  })
175
  return fn
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  @register_tool
178
  def sql_db_list_tables():
179
- """Returns a comma-separated list of table names in the database."""
 
 
180
  return credit_card_db.get_usable_table_names()
181
 
182
  @register_tool
183
  def sql_db_schema(table_names: list[str]) -> str:
184
- """Input 'table_names_str' is a comma-separated string of table names. Returns the DDL SQL schema for these tables."""
 
 
 
185
  return credit_card_db.get_table_info(table_names)
186
 
187
  @register_tool
188
  def sql_db_query_checker(query: str) -> str:
189
- """Checks if the query is valid. If valid, returns the original query; if not, returns the corrected query."""
 
 
 
 
 
 
190
  return query_checker_tool.run(query)
191
 
192
  @register_tool
193
  def sql_db_query(query: str) -> str:
194
- """Executes the query (SELECT only) and returns the result."""
 
 
 
195
  return credit_card_db.run(query)
196
 
197
- @app.route("/")
198
- async def home(request: Request):
199
- user = request.session.get("user")
200
- if user:
201
- username = user["name"]
202
- return PlainTextResponse(f"Hello, {username}! You are logged in with Google.\nAccess /mcp/, /tools/")
203
- else:
204
- return PlainTextResponse("Hello! Please go to https://pgurazada1-credit-card-database-mcp-server.hf.space/login to sign in with Google.")
205
-
206
- @app.route("/login")
207
- async def login(request: Request):
208
- redirect_uri = str(request.url_for('auth')).replace("http://", "https://")
209
- print("Redirect URI:", redirect_uri)
210
- return await oauth.google.authorize_redirect(request, redirect_uri)
211
-
212
- @app.route("/auth")
213
- async def auth(request: Request):
214
- token = await oauth.google.authorize_access_token(request)
215
- token_dict = dict(token)
216
- print("TOKEN:", token_dict)
217
- user_info = token_dict.get("userinfo")
218
- if not user_info:
219
- # fallback: fetch from userinfo endpoint if not present
220
- user_info = await oauth.google.userinfo(request, token=token_dict)
221
- request.session["user"] = dict(user_info)
222
- return RedirectResponse(url="/")
223
-
224
- @app.route("/logout")
225
- async def logout(request: Request):
226
- request.session.pop("user", None)
227
- return RedirectResponse(url="/")
228
-
229
- # Protect MCP endpoints with authentication
230
- def require_google_auth(request: Request):
231
- user = request.session.get("user")
232
- if not user:
233
- return RedirectResponse(url="/login")
234
- return user
235
-
236
- @app.route("/mcp/{path:path}", methods=["GET", "POST"])
237
- async def mcp_proxy(request: Request):
238
- user = require_google_auth(request)
239
- if isinstance(user, RedirectResponse):
240
- return user
241
- # forward request to MCP server (adapt as needed)
242
- return await mcp.streamable_http_app(request.scope, request.receive, request.send)
243
-
244
- @app.route("/tools")
245
- async def list_tools(request: Request):
246
- user = require_google_auth(request)
247
- if isinstance(user, RedirectResponse):
248
- return user
249
  return JSONResponse(tool_registry)
250
 
251
  if __name__ == "__main__":
252
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  import uvicorn
3
  import inspect
4
 
5
  from mcp.server.fastmcp import FastMCP
6
  from starlette.requests import Request
7
+ from starlette.responses import PlainTextResponse, JSONResponse
 
 
 
 
8
 
9
  from langchain_community.utilities import SQLDatabase
10
  from langchain_community.tools.sql_database.tool import QuerySQLCheckerTool
 
17
  temperature=0
18
  )
19
 
20
+ # Create an MCP server and the tool registry
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  mcp = FastMCP("Credit Card Database Server")
22
  tool_registry = []
23
 
24
  def register_tool(fn):
25
+ """Decorator to register tool metadata and with MCP."""
26
+ # Register with MCP
27
  mcp.tool()(fn)
28
+ # Save metadata
29
  sig = inspect.signature(fn)
30
  params = [
31
  {
 
42
  })
43
  return fn
44
 
45
+ credit_card_db = SQLDatabase.from_uri(r"sqlite:///data/ccms.db")
46
+ query_checker_tool = QuerySQLCheckerTool(db=credit_card_db, llm=llm)
47
+
48
+ @mcp.custom_route("/", methods=["GET"])
49
+ async def home(request: Request) -> PlainTextResponse:
50
+ return PlainTextResponse(
51
+ """
52
+ Credit Card Database MCP Server
53
+ ----
54
+ Use the following URL to connect with this server
55
+ https://pgurazada1-credit-card-database-mcp-server.hf.space/mcp/
56
+
57
+ Access the following URL for a list of tools and their documentation.
58
+ https://pgurazada1-credit-card-database-mcp-server.hf.space/tools/
59
+ """
60
+ )
61
+
62
  @register_tool
63
  def sql_db_list_tables():
64
+ """
65
+ Returns a comma-separated list of table names in the database.
66
+ """
67
  return credit_card_db.get_usable_table_names()
68
 
69
  @register_tool
70
  def sql_db_schema(table_names: list[str]) -> str:
71
+ """
72
+ Input 'table_names_str' is a comma-separated string of table names.
73
+ Returns the DDL SQL schema for these tables.
74
+ """
75
  return credit_card_db.get_table_info(table_names)
76
 
77
  @register_tool
78
  def sql_db_query_checker(query: str) -> str:
79
+ """
80
+ Input 'query' is a SQL query string.
81
+ Checks if the query is valid.
82
+ If the query is valid, it returns the original query.
83
+ If the query is not valid, it returns the corrected query.
84
+ This tool is used to ensure the query is valid before executing it.
85
+ """
86
  return query_checker_tool.run(query)
87
 
88
  @register_tool
89
  def sql_db_query(query: str) -> str:
90
+ """
91
+ Input 'query' is a SQL query string.
92
+ Executes the query (SELECT only) and returns the result.
93
+ """
94
  return credit_card_db.run(query)
95
 
96
+ @mcp.custom_route("/tools", methods=["GET"])
97
+ async def list_tools(request: Request) -> JSONResponse:
98
+ """Return all registered tool metadata as JSON."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  return JSONResponse(tool_registry)
100
 
101
  if __name__ == "__main__":
102
+ uvicorn.run(mcp.streamable_http_app, host="0.0.0.0", port=8000)