Spaces:
Running
Running
Refactor functions to use Pydantic models for input validation and enhance the application with additional NumPy-based mathematical tools.
Browse files
app.py
CHANGED
@@ -1,26 +1,214 @@
|
|
1 |
from fastmcp import FastMCP
|
2 |
import numpy as np
|
|
|
|
|
3 |
|
4 |
mcp = FastMCP("Demo 🚀")
|
5 |
|
|
|
|
|
|
|
6 |
@mcp.tool()
|
7 |
-
def hello(
|
8 |
-
return f"Hello, {name}!"
|
|
|
|
|
|
|
|
|
9 |
|
10 |
@mcp.tool()
|
11 |
-
def multiply(
|
12 |
"""Multiplies two numbers."""
|
13 |
-
return a * b
|
|
|
|
|
|
|
|
|
14 |
|
15 |
@mcp.tool()
|
16 |
-
def inner_product(
|
17 |
"""Calculates the inner product of two vectors."""
|
18 |
-
return np.dot(a, b)
|
|
|
|
|
|
|
|
|
19 |
|
20 |
@mcp.tool()
|
21 |
-
def matrix_multiply(
|
22 |
"""Multiplies two matrices."""
|
23 |
-
return np.matmul(a, b)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
# Static resource
|
26 |
@mcp.resource("config://version")
|
@@ -28,15 +216,21 @@ def get_version():
|
|
28 |
return "2.0.1"
|
29 |
|
30 |
# Dynamic resource template
|
|
|
|
|
|
|
31 |
@mcp.resource("users://{user_id}/profile")
|
32 |
-
def get_profile(
|
33 |
# Fetch profile for user_id...
|
34 |
-
return {"name": f"User {user_id}", "status": "active"}
|
|
|
|
|
|
|
35 |
|
36 |
@mcp.prompt()
|
37 |
-
def summarize_request(
|
38 |
"""Generate a prompt asking for a summary."""
|
39 |
-
return f"Please summarize the following text:\n\n{text}"
|
40 |
|
41 |
if __name__ == "__main__":
|
42 |
mcp.run(transport="sse", host="0.0.0.0", port=7860)
|
|
|
1 |
from fastmcp import FastMCP
|
2 |
import numpy as np
|
3 |
+
from pydantic import BaseModel
|
4 |
+
from typing import List, Tuple, Optional
|
5 |
|
6 |
mcp = FastMCP("Demo 🚀")
|
7 |
|
8 |
+
class HelloInput(BaseModel):
|
9 |
+
name: str
|
10 |
+
|
11 |
@mcp.tool()
|
12 |
+
def hello(input: HelloInput) -> str:
|
13 |
+
return f"Hello, {input.name}!"
|
14 |
+
|
15 |
+
class MultiplyInput(BaseModel):
|
16 |
+
a: float
|
17 |
+
b: float
|
18 |
|
19 |
@mcp.tool()
|
20 |
+
def multiply(input: MultiplyInput) -> float:
|
21 |
"""Multiplies two numbers."""
|
22 |
+
return input.a * input.b
|
23 |
+
|
24 |
+
class InnerProductInput(BaseModel):
|
25 |
+
a: List[float]
|
26 |
+
b: List[float]
|
27 |
|
28 |
@mcp.tool()
|
29 |
+
def inner_product(input: InnerProductInput) -> float:
|
30 |
"""Calculates the inner product of two vectors."""
|
31 |
+
return np.dot(input.a, input.b)
|
32 |
+
|
33 |
+
class MatrixMultiplyInput(BaseModel):
|
34 |
+
a: List[List[float]]
|
35 |
+
b: List[List[float]]
|
36 |
|
37 |
@mcp.tool()
|
38 |
+
def matrix_multiply(input: MatrixMultiplyInput) -> List[List[float]]:
|
39 |
"""Multiplies two matrices."""
|
40 |
+
return np.matmul(input.a, input.b)
|
41 |
+
|
42 |
+
class NumpyDotInput(BaseModel):
|
43 |
+
a: List[float]
|
44 |
+
b: List[float]
|
45 |
+
|
46 |
+
@mcp.tool()
|
47 |
+
def numpy_dot(input: NumpyDotInput) -> float:
|
48 |
+
"""Calculates the dot product of two vectors."""
|
49 |
+
return np.dot(input.a, input.b)
|
50 |
+
|
51 |
+
class NumpyMatmulInput(BaseModel):
|
52 |
+
a: List[List[float]]
|
53 |
+
b: List[List[float]]
|
54 |
+
|
55 |
+
@mcp.tool()
|
56 |
+
def numpy_matmul(input: NumpyMatmulInput) -> List[List[float]]:
|
57 |
+
"""Multiplies two matrices using matmul."""
|
58 |
+
return np.matmul(input.a, input.b)
|
59 |
+
|
60 |
+
class NumpyInvInput(BaseModel):
|
61 |
+
a: List[List[float]]
|
62 |
+
|
63 |
+
@mcp.tool()
|
64 |
+
def numpy_inv(input: NumpyInvInput) -> List[List[float]]:
|
65 |
+
"""Calculates the inverse of a matrix."""
|
66 |
+
return np.linalg.inv(input.a)
|
67 |
+
|
68 |
+
class NumpyDetInput(BaseModel):
|
69 |
+
a: List[List[float]]
|
70 |
+
|
71 |
+
@mcp.tool()
|
72 |
+
def numpy_det(input: NumpyDetInput) -> float:
|
73 |
+
"""Calculates the determinant of a matrix."""
|
74 |
+
return np.linalg.det(input.a)
|
75 |
+
|
76 |
+
class NumpyEigInput(BaseModel):
|
77 |
+
a: List[List[float]]
|
78 |
+
|
79 |
+
@mcp.tool()
|
80 |
+
def numpy_eig(input: NumpyEigInput) -> Tuple:
|
81 |
+
"""Calculates the eigenvalues and eigenvectors of a matrix."""
|
82 |
+
return np.linalg.eig(input.a)
|
83 |
+
|
84 |
+
class NumpySvdInput(BaseModel):
|
85 |
+
a: List[List[float]]
|
86 |
+
|
87 |
+
@mcp.tool()
|
88 |
+
def numpy_svd(input: NumpySvdInput) -> Tuple:
|
89 |
+
"""Performs singular value decomposition on a matrix."""
|
90 |
+
return np.linalg.svd(input.a)
|
91 |
+
|
92 |
+
class NumpyNormInput(BaseModel):
|
93 |
+
a: List[float]
|
94 |
+
ord: Optional[int] = None
|
95 |
+
|
96 |
+
@mcp.tool()
|
97 |
+
def numpy_norm(input: NumpyNormInput) -> float:
|
98 |
+
"""Calculates the norm of a vector or matrix."""
|
99 |
+
return np.linalg.norm(input.a, input.ord)
|
100 |
+
|
101 |
+
class NumpyCrossInput(BaseModel):
|
102 |
+
a: List[float]
|
103 |
+
b: List[float]
|
104 |
+
|
105 |
+
@mcp.tool()
|
106 |
+
def numpy_cross(input: NumpyCrossInput) -> List[float]:
|
107 |
+
"""Calculates the cross product of two vectors."""
|
108 |
+
return np.cross(input.a, input.b)
|
109 |
+
|
110 |
+
class NumpyInnerInput(BaseModel):
|
111 |
+
a: List[float]
|
112 |
+
b: List[float]
|
113 |
+
|
114 |
+
@mcp.tool()
|
115 |
+
def numpy_inner(input: NumpyInnerInput) -> float:
|
116 |
+
"""Calculates the inner product of two vectors."""
|
117 |
+
return np.inner(input.a, input.b)
|
118 |
+
|
119 |
+
class NumpyOuterInput(BaseModel):
|
120 |
+
a: List[float]
|
121 |
+
b: List[float]
|
122 |
+
|
123 |
+
@mcp.tool()
|
124 |
+
def numpy_outer(input: NumpyOuterInput) -> List[List[float]]:
|
125 |
+
"""Calculates the outer product of two vectors."""
|
126 |
+
return np.outer(input.a, input.b)
|
127 |
+
|
128 |
+
class NumpyTensordotInput(BaseModel):
|
129 |
+
a: List
|
130 |
+
b: List
|
131 |
+
axes: int = 2
|
132 |
+
|
133 |
+
@mcp.tool()
|
134 |
+
def numpy_tensordot(input: NumpyTensordotInput) -> float:
|
135 |
+
"""Calculates the tensor dot product of two arrays."""
|
136 |
+
return np.tensordot(input.a, input.b, input.axes)
|
137 |
+
|
138 |
+
class NumpyTraceInput(BaseModel):
|
139 |
+
a: List[List[float]]
|
140 |
+
|
141 |
+
@mcp.tool()
|
142 |
+
def numpy_trace(input: NumpyTraceInput) -> float:
|
143 |
+
"""Calculates the trace of a matrix."""
|
144 |
+
return np.trace(input.a)
|
145 |
+
|
146 |
+
class NumpyQrInput(BaseModel):
|
147 |
+
a: List[List[float]]
|
148 |
+
|
149 |
+
@mcp.tool()
|
150 |
+
def numpy_qr(input: NumpyQrInput) -> Tuple:
|
151 |
+
"""Performs QR decomposition on a matrix."""
|
152 |
+
return np.linalg.qr(input.a)
|
153 |
+
|
154 |
+
class NumpyCholeskyInput(BaseModel):
|
155 |
+
a: List[List[float]]
|
156 |
+
|
157 |
+
@mcp.tool()
|
158 |
+
def numpy_cholesky(input: NumpyCholeskyInput) -> List[List[float]]:
|
159 |
+
"""Performs Cholesky decomposition on a matrix."""
|
160 |
+
return np.linalg.cholesky(input.a)
|
161 |
+
|
162 |
+
class NumpySolveInput(BaseModel):
|
163 |
+
a: List[List[float]]
|
164 |
+
b: List[float]
|
165 |
+
|
166 |
+
@mcp.tool()
|
167 |
+
def numpy_solve(input: NumpySolveInput) -> List[float]:
|
168 |
+
"""Solves a linear matrix equation."""
|
169 |
+
return np.linalg.solve(input.a, input.b)
|
170 |
+
|
171 |
+
class NumpyLstsqInput(BaseModel):
|
172 |
+
a: List[List[float]]
|
173 |
+
b: List[float]
|
174 |
+
|
175 |
+
@mcp.tool()
|
176 |
+
def numpy_lstsq(input: NumpyLstsqInput) -> Tuple:
|
177 |
+
"""Solves a linear least squares problem."""
|
178 |
+
return np.linalg.lstsq(input.a, input.b, rcond=None)
|
179 |
+
|
180 |
+
class NumpyPinvInput(BaseModel):
|
181 |
+
a: List[List[float]]
|
182 |
+
|
183 |
+
@mcp.tool()
|
184 |
+
def numpy_pinv(input: NumpyPinvInput) -> List[List[float]]:
|
185 |
+
"""Calculates the Moore-Penrose pseudo-inverse of a matrix."""
|
186 |
+
return np.linalg.pinv(input.a)
|
187 |
+
|
188 |
+
class NumpyCondInput(BaseModel):
|
189 |
+
a: List[List[float]]
|
190 |
+
p: Optional[int] = None
|
191 |
+
|
192 |
+
@mcp.tool()
|
193 |
+
def numpy_cond(input: NumpyCondInput) -> float:
|
194 |
+
"""Calculates the condition number of a matrix."""
|
195 |
+
return np.linalg.cond(input.a, input.p)
|
196 |
+
|
197 |
+
class NumpyMatrixRankInput(BaseModel):
|
198 |
+
a: List[List[float]]
|
199 |
+
|
200 |
+
@mcp.tool()
|
201 |
+
def numpy_matrix_rank(input: NumpyMatrixRankInput) -> int:
|
202 |
+
"""Calculates the rank of a matrix."""
|
203 |
+
return np.linalg.matrix_rank(input.a)
|
204 |
+
|
205 |
+
class NumpyMultiDotInput(BaseModel):
|
206 |
+
arrays: List[List[List[float]]]
|
207 |
+
|
208 |
+
@mcp.tool()
|
209 |
+
def numpy_multi_dot(input: NumpyMultiDotInput) -> List[List[float]]:
|
210 |
+
"""Computes the dot product of two or more arrays in a single function call, while automatically selecting the fastest evaluation order."""
|
211 |
+
return np.linalg.multi_dot(input.arrays)
|
212 |
|
213 |
# Static resource
|
214 |
@mcp.resource("config://version")
|
|
|
216 |
return "2.0.1"
|
217 |
|
218 |
# Dynamic resource template
|
219 |
+
class GetProfileInput(BaseModel):
|
220 |
+
user_id: int
|
221 |
+
|
222 |
@mcp.resource("users://{user_id}/profile")
|
223 |
+
def get_profile(input: GetProfileInput):
|
224 |
# Fetch profile for user_id...
|
225 |
+
return {"name": f"User {input.user_id}", "status": "active"}
|
226 |
+
|
227 |
+
class SummarizeRequestInput(BaseModel):
|
228 |
+
text: str
|
229 |
|
230 |
@mcp.prompt()
|
231 |
+
def summarize_request(input: SummarizeRequestInput) -> str:
|
232 |
"""Generate a prompt asking for a summary."""
|
233 |
+
return f"Please summarize the following text:\n\n{input.text}"
|
234 |
|
235 |
if __name__ == "__main__":
|
236 |
mcp.run(transport="sse", host="0.0.0.0", port=7860)
|