Kaballas commited on
Commit
bc7893a
·
verified ·
1 Parent(s): d1ab426

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +6 -434
app.py CHANGED
@@ -1,437 +1,9 @@
1
- from fastmcp import FastMCP
2
- import requests
3
 
4
- # Step 1: Create the server
5
- mcp = FastMCP(name="MCP Server with Standardized Tools")
6
-
7
-
8
- # Step 2: Add tools with proper naming and documentation
9
- @mcp.tool
10
- def calculate_sum(first_number: int, second_number: int) -> int:
11
- """
12
- This tool adds two integer numbers and returns their sum.
13
-
14
- When to use:
15
- - When simple mathematical addition is required
16
- - As a basic calculator function
17
-
18
- Limitations:
19
- - Only handles integers, not floating point numbers
20
- - No validation for integer overflow
21
-
22
- Parameters:
23
- - first_number: The first integer to be added
24
- - second_number: The second integer to be added
25
-
26
- Returns:
27
- - The sum of the two provided integers
28
- """
29
- return first_number + second_number
30
-
31
-
32
- @mcp.tool
33
- def count_file_rows(file_path: str) -> int:
34
- """
35
- This tool counts the number of rows (lines) in a text file.
36
-
37
- When to use:
38
- - When you need to know the total number of lines in a file
39
- - For analyzing file size in terms of line count
40
- - Before processing files to understand their scope
41
-
42
- Limitations:
43
- - Only works with text files that can be read line by line
44
- - Very large files may take time to process
45
- - Binary files may produce unexpected results
46
-
47
- Parameters:
48
- - file_path: The absolute or relative path to the file to count rows for
49
-
50
- Returns:
51
- - The total number of rows (lines) in the file as an integer
52
- """
53
- try:
54
- with open(file_path, 'r', encoding='utf-8') as file:
55
- row_count = sum(1 for line in file)
56
- return row_count
57
- except FileNotFoundError:
58
- raise ValueError(f"File not found: {file_path}")
59
- except PermissionError:
60
- raise ValueError(f"Permission denied accessing file: {file_path}")
61
- except UnicodeDecodeError:
62
- # Try with different encoding for non-UTF-8 files
63
- try:
64
- with open(file_path, 'r', encoding='latin-1') as file:
65
- row_count = sum(1 for line in file)
66
- return row_count
67
- except Exception:
68
- raise ValueError(f"Unable to read file (encoding issue): {file_path}")
69
- except Exception as e:
70
- raise ValueError(f"Error reading file: {e}")
71
-
72
-
73
- # Step 3: Add a static resource (resources follow their own convention)
74
- @mcp.resource("resource://config")
75
- def get_config() -> dict:
76
- """
77
- Provides the application's configuration.
78
-
79
- When to use:
80
- - When configuration values are needed across the application
81
-
82
- Returns:
83
- - A dictionary containing version and author information
84
- """
85
- return {"version": "1.0", "author": "MyTeam"}
86
-
87
-
88
- # Step 4: Add a resource template for dynamic content
89
- @mcp.resource("greetings://{name}")
90
- def personalized_greeting(name: str) -> str:
91
- """
92
- Generates a personalized greeting for the given name.
93
-
94
- Parameters:
95
- - name: The person's name to include in the greeting
96
-
97
- Returns:
98
- - A personalized greeting string
99
- """
100
- return f"Hello, {name}! Welcome to the MCP server."
101
-
102
-
103
- @mcp.tool
104
- def query_tax_advice(question: str) -> str:
105
- """
106
- This tool sends tax-related questions to the ATO API and returns the response.
107
-
108
- When to use:
109
- - When users need tax information or guidance
110
- - For tax compliance queries
111
-
112
- Limitations:
113
- - Limited to Australian tax regulations
114
- - Responses are informational only and not legal advice
115
- - API rate limits apply (max 100 requests per hour)
116
-
117
- Parameters:
118
- - question: The tax-related question in natural language format
119
-
120
- Returns:
121
- - A string containing the ATO's response to the tax query
122
- """
123
- url = "https://kaballas-doe-work.hf.space/api/v1/openai/chat/completions"
124
- headers = {
125
- "accept": "*/*",
126
- "Authorization": "Bearer PF9RE8T-7DFMFQ9-P14FTVJ-640YR2Y",
127
- "Content-Type": "application/json",
128
- }
129
- data = {
130
- "messages": [
131
- {"role": "system", "content": "You are a helpful assistant"},
132
- {"role": "user", "content": question},
133
- ],
134
- "model": "tax",
135
- "stream": False,
136
- "temperature": 0.7,
137
- }
138
- print("\n--- DEBUG ---")
139
- print("User question:", question)
140
- print("Request headers:", headers)
141
- print("Request payload:", data)
142
- try:
143
- response = requests.post(url, headers=headers, json=data)
144
- print("Response status code:", response.status_code)
145
- print("Raw response:", response.text)
146
- response.raise_for_status()
147
- print("Response JSON:", response.json())
148
- return str(response.json())
149
- except Exception as e:
150
- print("Exception occurred:", e)
151
- return f"Error: {e}"
152
-
153
-
154
- @mcp.tool
155
- def generate_qa_plan(task: str, deadline: str) -> str:
156
- """
157
- This tool generates a structured QA plan based on the given task and deadline.
158
-
159
- When to use:
160
- - When creating test plans for software projects
161
- - For establishing QA workflows with specific deadlines
162
-
163
- Limitations:
164
- - Plans are templates and may need customization
165
- - Does not integrate with project management tools
166
-
167
- Parameters:
168
- - task: A description of the task requiring QA planning
169
- - deadline: The date by which the QA process must be completed (format: YYYY-MM-DD)
170
-
171
- Returns:
172
- - A formatted string containing the QA plan with todo items
173
- """
174
- todo = f""" {task}
175
-
176
- IMPORTANT: Recursively fetching links is crucial. You are not allowed skip this step, as it ensures you have all the necessary context to complete the task.
177
-
178
- ### Read File Tool (`functions.read_file`)
179
-
180
- 1. Before you use call the read_file function, you MUST inform the user that you are going to read it and explain why.
181
-
182
- 2. Always read the entire file. You may read up to 2000 lines in a single read operation. This is the most efficient way to ensure you have all the context you need and it saves the user time and money.
183
-
184
- 3. Unless a file has changed since the last time you read it.
185
-
186
- IMPORTANT: Read the entire file. Failure to do so will result in a bad rating for you.
187
- - [ ] IMPORTANT: Do **not** return control the user until you have **fully completed the user's entire request**. All items in your todo list MUST be checked off. Failure to do so will result in a bad rating for you.
188
- - [ ] Validate if action is complete
189
-
190
- """
191
- return todo
192
-
193
-
194
- @mcp.tool
195
- def generate_python_code(task: str) -> str:
196
- """
197
- This tool generates Python code that accomplishes the described task.
198
-
199
- When to use:
200
- - When users need Python implementation examples
201
- - For automating Python code generation based on requirements
202
-
203
- Limitations:
204
- - Generated code may require review and optimization
205
- - Complex algorithms might not be optimally implemented
206
- - Does not handle external dependencies or package installations
207
-
208
- Parameters:
209
- - task: A description of what the Python code should accomplish
210
-
211
- Returns:
212
- - A string containing the generated Python code with explanatory comments
213
- """
214
- url = "https://kaballas-doe-work.hf.space/api/v1/openai/chat/completions"
215
- headers = {
216
- "accept": "*/*",
217
- "Authorization": "Bearer PF9RE8T-7DFMFQ9-P14FTVJ-640YR2Y",
218
- "Content-Type": "application/json",
219
- }
220
- prompt = f"""Task is to write python code for the following task : '{task}' . """
221
-
222
- data = {
223
- "messages": [
224
- {"role": "system", "content": "You are a helpful assistant"},
225
- {"role": "user", "content": prompt},
226
- ],
227
- "model": "python",
228
- "stream": False,
229
- "temperature": 0.7,
230
- }
231
- try:
232
- response = requests.post(url, headers=headers, json=data)
233
- response.raise_for_status()
234
- # Extract and return only the 'content' field from the 'assistant' message
235
- return response.json()["choices"][0]["message"]["content"]
236
- except Exception as e:
237
- return f"Error: {e}"
238
-
239
-
240
- @mcp.tool
241
- def query_sap_knowledge(question: str) -> str:
242
- """
243
- This tool provides answers to SAP-related questions by querying a specialized knowledge model.
244
-
245
- When to use:
246
- - When users need information about SAP systems, modules, or best practices
247
- - For troubleshooting SAP-specific issues
248
-
249
- Limitations:
250
- - Knowledge base may not cover the latest SAP updates
251
- - Technical implementation details may vary by SAP version
252
- - Some specialized modules may have limited coverage
253
-
254
- Parameters:
255
- - question: The SAP-related question in natural language format
256
-
257
- Returns:
258
- - A detailed response addressing the SAP question
259
- """
260
- url = "https://kaballas-doe-work.hf.space/api/v1/openai/chat/completions"
261
- headers = {
262
- "accept": "*/*",
263
- "Authorization": "Bearer PF9RE8T-7DFMFQ9-P14FTVJ-640YR2Y",
264
- "Content-Type": "application/json",
265
- }
266
- prompt = f"""Anwser the SAP related Question '{question}' . """
267
-
268
- data = {
269
- "messages": [
270
- {"role": "system", "content": "You are a helpful assistant"},
271
- {"role": "user", "content": prompt},
272
- ],
273
- "model": "sap",
274
- "stream": False,
275
- "temperature": 0.7,
276
- }
277
- try:
278
- response = requests.post(url, headers=headers, json=data)
279
- response.raise_for_status()
280
- # Extract and return only the 'content' field from the 'assistant' message
281
- return response.json()["choices"][0]["message"]["content"]
282
- except Exception as e:
283
- return f"Error: {e}"
284
-
285
-
286
- @mcp.tool(
287
- title="Task Analysis & Planning"
288
- )
289
- def interpret_task(task: str, deadline: str = "") -> str:
290
- """
291
- This tool analyzes a given task and generates a structured plan for completion.
292
-
293
- When to use:
294
- - As the first step in processing any user request
295
- - For breaking down complex tasks into manageable steps
296
-
297
- Limitations:
298
- - Generated plans may need adjustment for specialized domains
299
- - Cannot account for all edge cases in complex workflows
300
- - Task interpretation quality depends on input clarity
301
-
302
- Parameters:
303
- - task: The description of the task to be analyzed and planned
304
- - deadline: Optional deadline for task completion (format: YYYY-MM-DD)
305
-
306
- Returns:
307
- - A structured plan with steps to complete the task
308
- """
309
- url = "https://kaballas-doe-work.hf.space/api/v1/openai/chat/completions"
310
-
311
- headers = {
312
- "accept": "*/*",
313
- "Authorization": "Bearer PF9RE8T-7DFMFQ9-P14FTVJ-640YR2Y",
314
- "Content-Type": "application/json",
315
- }
316
-
317
- # Step 1: Send request to TaskInterpreter model
318
- prompt = f"""INSTRUCTIONS: MCP TOOLING AND SCHEMA COMPLIANCE
319
-
320
- ----------------------------------------
321
- AVAILABLE TOOLS (DO NOT USE ANY OTHERS)
322
- ----------------------------------------
323
-
324
- {{
325
- "tools": [
326
- {{
327
- "name": "calculate_sum",
328
- "description": "Adds two integers and returns the result. Intended for basic integer addition tasks."
329
- }},
330
- {{
331
- "name": "count_file_rows",
332
- "description": "Counts the number of lines in a text file. Useful for gauging file size or preprocessing needs."
333
- }},
334
- {{
335
- "name": "query_tax_advice",
336
- "description": "Sends a natural language tax-related question to an ATO model and returns a response. Limited to Australian tax domain."
337
- }},
338
- {{
339
- "name": "generate_qa_plan",
340
- "description": "Generates a checklist-style QA plan for a task and deadline, including mandatory procedural steps."
341
- }},
342
- {{
343
- "name": "generate_python_code",
344
- "description": "Returns Python code that fulfills a user-described programming task. Output is raw code with inline comments."
345
- }},
346
- {{
347
- "name": "query_sap_knowledge",
348
- "description": "Answers SAP-related questions using a specialized model trained on SAP system knowledge."
349
- }},
350
- {{
351
- "name": "interpret_task",
352
- "description": "Analyzes a task and produces a structured execution plan. Often used as a first step before tool invocation."
353
- }}
354
- ],
355
-
356
- }}
357
-
358
- ----------------------------------------------------
359
- MCP TOOLING RULES (ALL MUST BE FOLLOWED STRICTLY)
360
- ----------------------------------------------------
361
-
362
- 1. STRUCTURED RESULTS & SCHEMA COMPLIANCE
363
-
364
- - All tool results must be structured JSON.
365
- - If a tool defines an `outputSchema`, your output MUST conform exactly.
366
- - Match all field names, data types, and required properties — no omissions, additions, or type mismatches.
367
- - Clients and systems will validate JSON against this schema.
368
-
369
- 2. TOOL NAMING CONVENTION
370
-
371
- - Use only lowercase snake_case format: verb_noun
372
- - The name must describe what the tool does and to what.
373
- - DO NOT use vague names like `add`, `doTask`, or `Handler`.
374
-
375
- Examples:
376
- ✓ calculate_sum
377
- ✓ query_tax_advice
378
- ✓ interpret_task
379
- ✗ Add
380
- ✗ ATO_HELP
381
- ✗ TaskInterpreter
382
-
383
- 3. JSON OUTPUT REQUIREMENT
384
-
385
- - Every tool result MUST return JSON only.
386
- - DO NOT include markdown, comments, or explanatory text outside of the JSON object.
387
- - Validate your output before returning it.
388
-
389
- 4. EXISTING USER GUIDELINES (STILL IN EFFECT)
390
-
391
- - Use step-by-step reasoning unless explicitly instructed not to.
392
- - Prioritize correctness, clarity, and concise execution.
393
- - Be brutally honest when asked — no sugarcoating or vague optimism.
394
- - Always ask, “Am I missing something?” after completing a task.
395
-
396
- ---------------------------------------------
397
- POSSIBLE BLIND SPOTS / NEXT STEPS
398
- ---------------------------------------------
399
-
400
- - Ensure every tool has an explicit and validated output schema.
401
- - Review tool naming for consistency with the required convention.
402
- - Add schema validation to downstream consumers if not yet implemented.
403
- - Eliminate or refactor any tools not listed in the approved set above.
404
-
405
- No based on my instructions I need a tool for the following TASK :
406
-
407
- **{task}
408
-
409
- Return only the JSON object that represents the tool specification—no extra text, comments, or keys outside the schema.
410
- """
411
-
412
-
413
- print(prompt)
414
- data = {
415
- "messages": [
416
- {"role": "system", "content": "All tool invocation results must be returned in JSON format only. Do not add extra text, commentary, or non‑JSON content"},
417
- {"role": "user", "content": prompt},
418
- ],
419
- "model": "tools",
420
- "stream": False,
421
- "temperature": 0.3,
422
- }
423
-
424
- content = None
425
- try:
426
- response = requests.post(url, headers=headers, json=data)
427
- response.raise_for_status()
428
- content = response.json()["choices"][0]["message"]["content"]
429
-
430
- print("-----------------")
431
- print(content)
432
- print("-----------------")
433
- return content
434
- except Exception as e:
435
- return f"Error: {e}"
436
 
 
437
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi_mcp import FastApiMCP
3
 
4
+ app = FastAPI()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ mcp = FastApiMCP(app)
7
 
8
+ # Mount the MCP server directly to your FastAPI app
9
+ mcp.mount()