fastmcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastmcp-0.1.0/.github/workflows/publish.yml +32 -0
- fastmcp-0.1.0/.gitignore +14 -0
- fastmcp-0.1.0/.python-version +1 -0
- fastmcp-0.1.0/PKG-INFO +121 -0
- fastmcp-0.1.0/README.md +107 -0
- fastmcp-0.1.0/examples/desktop.py +29 -0
- fastmcp-0.1.0/examples/screenshot.py +34 -0
- fastmcp-0.1.0/pyproject.toml +37 -0
- fastmcp-0.1.0/setup.cfg +4 -0
- fastmcp-0.1.0/src/fastmcp/__init__.py +1 -0
- fastmcp-0.1.0/src/fastmcp/_version.py +16 -0
- fastmcp-0.1.0/src/fastmcp/cli/__init__.py +5 -0
- fastmcp-0.1.0/src/fastmcp/cli/claude.py +88 -0
- fastmcp-0.1.0/src/fastmcp/cli/cli.py +306 -0
- fastmcp-0.1.0/src/fastmcp/cli.py +6 -0
- fastmcp-0.1.0/src/fastmcp/exceptions.py +17 -0
- fastmcp-0.1.0/src/fastmcp/resources.py +219 -0
- fastmcp-0.1.0/src/fastmcp/server.py +275 -0
- fastmcp-0.1.0/src/fastmcp/tools.py +101 -0
- fastmcp-0.1.0/src/fastmcp/utilities/__init__.py +1 -0
- fastmcp-0.1.0/src/fastmcp/utilities/logging.py +30 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/PKG-INFO +121 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/SOURCES.txt +35 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/dependency_links.txt +1 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/entry_points.txt +2 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/requires.txt +5 -0
- fastmcp-0.1.0/src/fastmcp.egg-info/top_level.txt +1 -0
- fastmcp-0.1.0/tests/__init__.py +0 -0
- fastmcp-0.1.0/tests/resources/__init__.py +0 -0
- fastmcp-0.1.0/tests/resources/test_file_resources.py +109 -0
- fastmcp-0.1.0/tests/resources/test_function_resources.py +38 -0
- fastmcp-0.1.0/tests/resources/test_resource_manager.py +242 -0
- fastmcp-0.1.0/tests/servers/__init__.py +0 -0
- fastmcp-0.1.0/tests/servers/test_file_server.py +112 -0
- fastmcp-0.1.0/tests/test_server.py +76 -0
- fastmcp-0.1.0/tests/test_tool_manager.py +155 -0
- fastmcp-0.1.0/uv.lock +1027 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Publish FastMCP to PyPI
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish-pypi-release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: release
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
cache: pip
|
|
22
|
+
cache-dependency-path: "**/pyproject.toml"
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
pip install setuptools wheel build
|
|
26
|
+
- name: Build
|
|
27
|
+
run: |
|
|
28
|
+
python -m build
|
|
29
|
+
- name: Publish
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
31
|
+
with:
|
|
32
|
+
verbose: true
|
fastmcp-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
fastmcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: fastmcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A more ergonomic interface for MCP servers
|
|
5
|
+
Author: Jeremiah Lowin
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: httpx>=0.26.0
|
|
10
|
+
Requires-Dist: mcp>=1.0.0
|
|
11
|
+
Requires-Dist: pydantic-settings>=2.6.1
|
|
12
|
+
Requires-Dist: pydantic>=2.5.3
|
|
13
|
+
Requires-Dist: typer>=0.9.0
|
|
14
|
+
|
|
15
|
+
# FastMCP
|
|
16
|
+
|
|
17
|
+
> **Note**: This is experimental software. The Model Context Protocol itself is only a few days old and the specification is still evolving.
|
|
18
|
+
|
|
19
|
+
A fast, pythonic way to build Model Context Protocol (MCP) servers.
|
|
20
|
+
|
|
21
|
+
The Model Context Protocol is an extremely powerful way to give LLMs access to tools and resources. However, building MCP servers can be difficult and cumbersome. FastMCP provides a simple, intuitive interface for creating MCP servers in Python.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
MCP servers require you to use [uv](https://github.com/astral-sh/uv) as your dependency manager.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Install uv with brew:
|
|
29
|
+
```bash
|
|
30
|
+
brew install uv
|
|
31
|
+
```
|
|
32
|
+
*(Editor's note: I was unable to get MCP servers working unless uv was installed with brew.)*
|
|
33
|
+
|
|
34
|
+
Install FastMCP:
|
|
35
|
+
```bash
|
|
36
|
+
uv pip install fastmcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
Here's a simple example that exposes your desktop directory as a resource and provides a basic addition tool:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from pathlib import Path
|
|
47
|
+
from fastmcp import FastMCP
|
|
48
|
+
|
|
49
|
+
# Create server
|
|
50
|
+
mcp = FastMCP("Demo")
|
|
51
|
+
|
|
52
|
+
@mcp.resource("dir://desktop")
|
|
53
|
+
def desktop() -> list[str]:
|
|
54
|
+
"""List the files in the user's desktop"""
|
|
55
|
+
desktop = Path.home() / "Desktop"
|
|
56
|
+
return [str(f) for f in desktop.iterdir()]
|
|
57
|
+
|
|
58
|
+
@mcp.tool()
|
|
59
|
+
def add(a: int, b: int) -> int:
|
|
60
|
+
"""Add two numbers"""
|
|
61
|
+
return a + b
|
|
62
|
+
|
|
63
|
+
if __name__ == "__main__":
|
|
64
|
+
mcp.run()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Features
|
|
68
|
+
|
|
69
|
+
### Resources
|
|
70
|
+
|
|
71
|
+
Resources are data sources that can be accessed by the LLM. They can be files, directories, or any other data source. Resources are defined using the `@resource` decorator:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
@mcp.resource("file://config.json")
|
|
75
|
+
def get_config() -> str:
|
|
76
|
+
"""Read the config file"""
|
|
77
|
+
return Path("config.json").read_text()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Tools
|
|
81
|
+
|
|
82
|
+
Tools are functions that can be called by the LLM. They are defined using the `@tool` decorator:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
@mcp.tool()
|
|
86
|
+
def calculate(x: int, y: int) -> int:
|
|
87
|
+
"""Perform a calculation"""
|
|
88
|
+
return x + y
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
### Running the Dev Inspector
|
|
94
|
+
|
|
95
|
+
FastMCP includes a development server with the MCP Inspector for testing your server:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
fastmcp dev your_server.py
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Installing in Claude
|
|
102
|
+
|
|
103
|
+
To use your server with Claude Desktop:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
fastmcp install your_server.py --name "My Server"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
## Configuration
|
|
111
|
+
|
|
112
|
+
FastMCP can be configured via environment variables with the prefix `FASTMCP_`:
|
|
113
|
+
|
|
114
|
+
- `FASTMCP_DEBUG`: Enable debug mode
|
|
115
|
+
- `FASTMCP_LOG_LEVEL`: Set logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
116
|
+
- `FASTMCP_HOST`: HTTP server host (default: 0.0.0.0)
|
|
117
|
+
- `FASTMCP_PORT`: HTTP server port (default: 8000)
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
Apache 2.0
|
fastmcp-0.1.0/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# FastMCP
|
|
2
|
+
|
|
3
|
+
> **Note**: This is experimental software. The Model Context Protocol itself is only a few days old and the specification is still evolving.
|
|
4
|
+
|
|
5
|
+
A fast, pythonic way to build Model Context Protocol (MCP) servers.
|
|
6
|
+
|
|
7
|
+
The Model Context Protocol is an extremely powerful way to give LLMs access to tools and resources. However, building MCP servers can be difficult and cumbersome. FastMCP provides a simple, intuitive interface for creating MCP servers in Python.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
MCP servers require you to use [uv](https://github.com/astral-sh/uv) as your dependency manager.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Install uv with brew:
|
|
15
|
+
```bash
|
|
16
|
+
brew install uv
|
|
17
|
+
```
|
|
18
|
+
*(Editor's note: I was unable to get MCP servers working unless uv was installed with brew.)*
|
|
19
|
+
|
|
20
|
+
Install FastMCP:
|
|
21
|
+
```bash
|
|
22
|
+
uv pip install fastmcp
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
Here's a simple example that exposes your desktop directory as a resource and provides a basic addition tool:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from fastmcp import FastMCP
|
|
34
|
+
|
|
35
|
+
# Create server
|
|
36
|
+
mcp = FastMCP("Demo")
|
|
37
|
+
|
|
38
|
+
@mcp.resource("dir://desktop")
|
|
39
|
+
def desktop() -> list[str]:
|
|
40
|
+
"""List the files in the user's desktop"""
|
|
41
|
+
desktop = Path.home() / "Desktop"
|
|
42
|
+
return [str(f) for f in desktop.iterdir()]
|
|
43
|
+
|
|
44
|
+
@mcp.tool()
|
|
45
|
+
def add(a: int, b: int) -> int:
|
|
46
|
+
"""Add two numbers"""
|
|
47
|
+
return a + b
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
mcp.run()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Features
|
|
54
|
+
|
|
55
|
+
### Resources
|
|
56
|
+
|
|
57
|
+
Resources are data sources that can be accessed by the LLM. They can be files, directories, or any other data source. Resources are defined using the `@resource` decorator:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
@mcp.resource("file://config.json")
|
|
61
|
+
def get_config() -> str:
|
|
62
|
+
"""Read the config file"""
|
|
63
|
+
return Path("config.json").read_text()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Tools
|
|
67
|
+
|
|
68
|
+
Tools are functions that can be called by the LLM. They are defined using the `@tool` decorator:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
@mcp.tool()
|
|
72
|
+
def calculate(x: int, y: int) -> int:
|
|
73
|
+
"""Perform a calculation"""
|
|
74
|
+
return x + y
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
### Running the Dev Inspector
|
|
80
|
+
|
|
81
|
+
FastMCP includes a development server with the MCP Inspector for testing your server:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
fastmcp dev your_server.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Installing in Claude
|
|
88
|
+
|
|
89
|
+
To use your server with Claude Desktop:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
fastmcp install your_server.py --name "My Server"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
FastMCP can be configured via environment variables with the prefix `FASTMCP_`:
|
|
99
|
+
|
|
100
|
+
- `FASTMCP_DEBUG`: Enable debug mode
|
|
101
|
+
- `FASTMCP_LOG_LEVEL`: Set logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
102
|
+
- `FASTMCP_HOST`: HTTP server host (default: 0.0.0.0)
|
|
103
|
+
- `FASTMCP_PORT`: HTTP server port (default: 8000)
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
Apache 2.0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FastMCP Desktop Example
|
|
3
|
+
|
|
4
|
+
A simple example that exposes the desktop directory as a resource.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from fastmcp.server import FastMCP
|
|
10
|
+
|
|
11
|
+
# Create server
|
|
12
|
+
mcp = FastMCP("Demo")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@mcp.resource("dir://desktop")
|
|
16
|
+
def desktop() -> list[str]:
|
|
17
|
+
"""List the files in the user's desktop"""
|
|
18
|
+
desktop = Path.home() / "Desktop"
|
|
19
|
+
return [str(f) for f in desktop.iterdir()]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@mcp.tool()
|
|
23
|
+
def add(a: int, b: int) -> int:
|
|
24
|
+
"""Add two numbers"""
|
|
25
|
+
return a + b
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
mcp.run()
|
|
@@ -0,0 +1,34 @@
|
|
|
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__":
|
|
34
|
+
mcp.run()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fastmcp"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "A more ergonomic interface for MCP servers"
|
|
5
|
+
authors = [{ name = "Jeremiah Lowin" }]
|
|
6
|
+
dependencies = [
|
|
7
|
+
"httpx>=0.26.0",
|
|
8
|
+
"mcp>=1.0.0",
|
|
9
|
+
"pydantic-settings>=2.6.1",
|
|
10
|
+
"pydantic>=2.5.3",
|
|
11
|
+
"typer>=0.9.0",
|
|
12
|
+
]
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
license = { text = "Apache-2.0" }
|
|
16
|
+
|
|
17
|
+
[project.scripts]
|
|
18
|
+
fastmcp = "fastmcp.cli:app"
|
|
19
|
+
|
|
20
|
+
[build-system]
|
|
21
|
+
requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
|
|
22
|
+
build-backend = "setuptools.build_meta"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools_scm]
|
|
25
|
+
write_to = "src/fastmcp/_version.py"
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = [
|
|
29
|
+
"copychat>=0.5.2",
|
|
30
|
+
"ipython>=8.12.3",
|
|
31
|
+
"pdbpp>=0.10.3",
|
|
32
|
+
"pytest>=8.3.3",
|
|
33
|
+
"pytest-asyncio>=0.23.5",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[tool.pytest.ini_options]
|
|
37
|
+
asyncio_mode = "auto"
|
fastmcp-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .server import FastMCP
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '0.1.0'
|
|
16
|
+
__version_tuple__ = version_tuple = (0, 1, 0)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Claude app integration utilities."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from ..utilities.logging import get_logger
|
|
9
|
+
|
|
10
|
+
logger = get_logger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_claude_config_path() -> Path | None:
|
|
14
|
+
"""Get the Claude config directory based on platform."""
|
|
15
|
+
if sys.platform == "win32":
|
|
16
|
+
path = Path(Path.home(), "AppData", "Roaming", "Claude")
|
|
17
|
+
elif sys.platform == "darwin":
|
|
18
|
+
path = Path(Path.home(), "Library", "Application Support", "Claude")
|
|
19
|
+
else:
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
if path.exists():
|
|
23
|
+
return path
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def update_claude_config(
|
|
28
|
+
file: Path,
|
|
29
|
+
server_name: Optional[str] = None,
|
|
30
|
+
*,
|
|
31
|
+
uv_directory: Optional[Path] = None,
|
|
32
|
+
) -> bool:
|
|
33
|
+
"""Add the MCP server to Claude's configuration.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
file: Path to the server file
|
|
37
|
+
server_name: Optional custom name for the server. If not provided,
|
|
38
|
+
defaults to the file stem
|
|
39
|
+
uv_directory: Optional directory containing pyproject.toml
|
|
40
|
+
"""
|
|
41
|
+
config_dir = get_claude_config_path()
|
|
42
|
+
if not config_dir:
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
config_file = config_dir / "claude_desktop_config.json"
|
|
46
|
+
if not config_file.exists():
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
config = json.loads(config_file.read_text())
|
|
51
|
+
if "mcpServers" not in config:
|
|
52
|
+
config["mcpServers"] = {}
|
|
53
|
+
|
|
54
|
+
# Use provided server_name or fall back to file stem
|
|
55
|
+
name = server_name or file.stem
|
|
56
|
+
if name in config["mcpServers"]:
|
|
57
|
+
logger.warning(
|
|
58
|
+
f"Server '{name}' already exists in Claude config",
|
|
59
|
+
extra={"config_file": str(config_file)},
|
|
60
|
+
)
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
# Build uv run command
|
|
64
|
+
args = []
|
|
65
|
+
if uv_directory:
|
|
66
|
+
args.extend(["--directory", str(uv_directory)])
|
|
67
|
+
args.extend(["run", str(file)])
|
|
68
|
+
|
|
69
|
+
config["mcpServers"][name] = {
|
|
70
|
+
"command": "uv",
|
|
71
|
+
"args": args,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
config_file.write_text(json.dumps(config, indent=2))
|
|
75
|
+
logger.info(
|
|
76
|
+
f"Added server '{name}' to Claude config",
|
|
77
|
+
extra={"config_file": str(config_file)},
|
|
78
|
+
)
|
|
79
|
+
return True
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.error(
|
|
82
|
+
"Failed to update Claude config",
|
|
83
|
+
extra={
|
|
84
|
+
"error": str(e),
|
|
85
|
+
"config_file": str(config_file),
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
return False
|