Jeremiah Lowin commited on
Commit
f88f9cc
·
1 Parent(s): c52b60b

Screenshot demo working

Browse files
examples/screenshot.py CHANGED
@@ -1,33 +1,31 @@
1
  # /// script
2
- # dependencies = ["pyautogui"]
3
  # ///
4
 
5
  """
6
  FastMCP Screenshot Example
7
 
8
- A simple example that provides a tool to capture screenshots.
9
  """
10
 
11
- import base64
12
  import io
13
- import pyautogui
14
 
15
- from fastmcp.server import FastMCP
16
 
17
  # Create server
18
  mcp = FastMCP("Screenshot Demo")
19
 
20
 
21
  @mcp.tool()
22
- def take_screenshot() -> str:
23
- """Take a screenshot and return it as a base64 encoded string"""
24
- # Capture the screen
25
- screenshot = pyautogui.screenshot()
26
 
27
- # Convert to base64
28
  buffer = io.BytesIO()
29
- screenshot.save(buffer, format="PNG")
30
- return base64.b64encode(buffer.getvalue()).decode()
 
31
 
32
 
33
  if __name__ == "__main__":
 
1
  # /// script
2
+ # dependencies = ["fastmcp", "pyautogui", "Pillow"]
3
  # ///
4
 
5
  """
6
  FastMCP Screenshot Example
7
 
8
+ Give Claude a tool to capture and view screenshots.
9
  """
10
 
 
11
  import io
 
12
 
13
+ from fastmcp import FastMCP, Image
14
 
15
  # Create server
16
  mcp = FastMCP("Screenshot Demo")
17
 
18
 
19
  @mcp.tool()
20
+ def take_screenshot() -> Image:
21
+ """Take a screenshot of the user's screen and return it as an image"""
22
+ import pyautogui
 
23
 
24
+ screenshot = pyautogui.screenshot()
25
  buffer = io.BytesIO()
26
+ # if the file exceeds ~1MB, it will be rejected by Claude
27
+ screenshot.convert("RGB").save(buffer, format="JPEG", quality=60, optimize=True)
28
+ return Image(data=buffer.getvalue(), format="jpeg")
29
 
30
 
31
  if __name__ == "__main__":
src/fastmcp/cli/cli.py CHANGED
@@ -275,7 +275,7 @@ def install(
275
  typer.Option(
276
  "--name",
277
  "-n",
278
- help="Custom name for the server (defaults to file name)",
279
  ),
280
  ] = None,
281
  with_editable: Annotated[
@@ -324,17 +324,28 @@ def install(
324
  logger.error("Claude app not found")
325
  sys.exit(1)
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  if claude.update_claude_config(
328
  file,
329
- server_name,
330
  with_editable=with_editable,
331
  with_packages=with_packages,
332
  force=force,
333
  ):
334
- name = server_name or file.stem
335
  print(f"Successfully installed {name} in Claude app")
336
  else:
337
- name = server_name or file.stem
338
  print(f"Failed to install {name} in Claude app")
339
  sys.exit(1)
340
 
 
275
  typer.Option(
276
  "--name",
277
  "-n",
278
+ help="Custom name for the server (defaults to server's name attribute or file name)",
279
  ),
280
  ] = None,
281
  with_editable: Annotated[
 
324
  logger.error("Claude app not found")
325
  sys.exit(1)
326
 
327
+ # Try to import server to get its name, but fall back to file name if dependencies missing
328
+ name = server_name
329
+ if not name:
330
+ try:
331
+ server = _import_server(file, server_object)
332
+ name = server.name
333
+ except (ImportError, ModuleNotFoundError) as e:
334
+ logger.debug(
335
+ "Could not import server (likely missing dependencies), using file name",
336
+ extra={"error": str(e)},
337
+ )
338
+ name = file.stem
339
+
340
  if claude.update_claude_config(
341
  file,
342
+ name,
343
  with_editable=with_editable,
344
  with_packages=with_packages,
345
  force=force,
346
  ):
 
347
  print(f"Successfully installed {name} in Claude app")
348
  else:
 
349
  print(f"Failed to install {name} in Claude app")
350
  sys.exit(1)
351
 
src/fastmcp/tools.py CHANGED
@@ -56,6 +56,7 @@ class Image:
56
  data = base64.b64encode(f.read()).decode()
57
  else:
58
  data = base64.b64encode(self.data).decode()
 
59
  return ImageContent(type="image", data=data, mimeType=self._mime_type)
60
 
61
 
 
56
  data = base64.b64encode(f.read()).decode()
57
  else:
58
  data = base64.b64encode(self.data).decode()
59
+
60
  return ImageContent(type="image", data=data, mimeType=self._mime_type)
61
 
62