ffdecmcp 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.
- ffdecmcp-0.1.0/LICENSE +21 -0
- ffdecmcp-0.1.0/PKG-INFO +191 -0
- ffdecmcp-0.1.0/README.md +163 -0
- ffdecmcp-0.1.0/pyproject.toml +49 -0
- ffdecmcp-0.1.0/setup.cfg +4 -0
- ffdecmcp-0.1.0/src/ffdecmcp/__init__.py +7 -0
- ffdecmcp-0.1.0/src/ffdecmcp/__main__.py +79 -0
- ffdecmcp-0.1.0/src/ffdecmcp/config.py +335 -0
- ffdecmcp-0.1.0/src/ffdecmcp/ffdec.py +606 -0
- ffdecmcp-0.1.0/src/ffdecmcp/server.py +390 -0
- ffdecmcp-0.1.0/src/ffdecmcp/utils.py +202 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/PKG-INFO +191 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/SOURCES.txt +17 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/dependency_links.txt +1 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/entry_points.txt +2 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/requires.txt +6 -0
- ffdecmcp-0.1.0/src/ffdecmcp.egg-info/top_level.txt +1 -0
- ffdecmcp-0.1.0/tests/test_ffdec.py +33 -0
- ffdecmcp-0.1.0/tests/test_tools.py +59 -0
ffdecmcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sublimnl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ffdecmcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ffdecmcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP wrapper for JPEXS Free Flash Decompiler (FFDec) - expose SWF decompilation tools to AI assistants
|
|
5
|
+
Author: sublimnl
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sublimnl/ffdecmcp
|
|
8
|
+
Project-URL: Repository, https://github.com/sublimnl/ffdecmcp
|
|
9
|
+
Project-URL: Issues, https://github.com/sublimnl/ffdecmcp/issues
|
|
10
|
+
Keywords: mcp,ffdec,swf,flash,decompiler,actionscript
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: fastmcp>=2.14.0
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# ffdecmcp
|
|
30
|
+
|
|
31
|
+
MCP (Model Context Protocol) wrapper for **JPEXS Free Flash Decompiler (FFDec)** - expose SWF decompilation and analysis tools to AI assistants like Claude.
|
|
32
|
+
|
|
33
|
+
## Tools
|
|
34
|
+
|
|
35
|
+
### 1. `decompile_swf`
|
|
36
|
+
Decompile all ActionScript code from a SWF file to organized directory structure.
|
|
37
|
+
|
|
38
|
+
**Parameters:**
|
|
39
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
40
|
+
- `output_dir` (required): Directory for decompiled scripts
|
|
41
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
42
|
+
|
|
43
|
+
### 2. `extract_actionscript`
|
|
44
|
+
Extract specific ActionScript classes by name (AS3 only). Faster than full decompilation when you only need specific classes.
|
|
45
|
+
|
|
46
|
+
**Parameters:**
|
|
47
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
48
|
+
- `class_names` (required): List of class names (e.g., `['com.example.Main']`)
|
|
49
|
+
- `output_dir` (required): Directory for extracted classes
|
|
50
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
51
|
+
|
|
52
|
+
### 3. `list_symbols`
|
|
53
|
+
List all ActionScript classes and symbols in a SWF file. Great for exploring a SWF before full decompilation.
|
|
54
|
+
|
|
55
|
+
**Parameters:**
|
|
56
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
57
|
+
|
|
58
|
+
**Returns:** Structured JSON with packages, classes, and total count
|
|
59
|
+
|
|
60
|
+
### 4. `extract_assets`
|
|
61
|
+
Extract images, sounds, fonts, shapes, movie clips, and binary data from SWF.
|
|
62
|
+
|
|
63
|
+
**Parameters:**
|
|
64
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
65
|
+
- `output_dir` (required): Directory for extracted assets
|
|
66
|
+
- `asset_types` (optional): Types to extract - `image`, `sound`, `font`, `shape`, `movie`, `binaryData`, `all` (default: `["all"]`)
|
|
67
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
68
|
+
|
|
69
|
+
### 5. `get_swf_metadata`
|
|
70
|
+
Extract SWF header information (dimensions, frame rate, compression, etc.). Fast and doesn't require decompilation.
|
|
71
|
+
|
|
72
|
+
**Parameters:**
|
|
73
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
74
|
+
|
|
75
|
+
**Returns:** JSON with version, width, height, frame_rate, frame_count, compression
|
|
76
|
+
|
|
77
|
+
### 6. `deobfuscate`
|
|
78
|
+
Run FFDec's deobfuscation algorithms to remove obfuscation and anti-decompilation tricks.
|
|
79
|
+
|
|
80
|
+
**Parameters:**
|
|
81
|
+
- `swf_path` (required): Absolute path to obfuscated SWF
|
|
82
|
+
- `output_path` (required): Path for deobfuscated SWF
|
|
83
|
+
- `level` (optional): Deobfuscation level - `traps`, `deadcode`, `max` (default: `max`)
|
|
84
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
**Prerequisites:** Python 3.10+ and Java (for running the FFDec JAR).
|
|
89
|
+
|
|
90
|
+
### Claude Code
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
claude mcp add ffdecmcp -- uvx ffdecmcp
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
That's it. On first run, FFDec will be auto-downloaded if not already installed.
|
|
97
|
+
|
|
98
|
+
### Claude Desktop
|
|
99
|
+
|
|
100
|
+
Add to your config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"ffdecmcp": {
|
|
106
|
+
"command": "uvx",
|
|
107
|
+
"args": ["ffdecmcp"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Standalone
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Just run it - FFDec will be auto-downloaded to ~/.ffdecmcp/ if needed
|
|
117
|
+
uvx ffdecmcp
|
|
118
|
+
|
|
119
|
+
# Or point to an existing FFDec installation
|
|
120
|
+
uvx ffdecmcp --ffdec-path /path/to/ffdec.jar
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Installation
|
|
124
|
+
|
|
125
|
+
No installation is required when using `uvx`. For a permanent install:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
uv pip install ffdecmcp
|
|
129
|
+
# or
|
|
130
|
+
pip install ffdecmcp
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### FFDec
|
|
134
|
+
|
|
135
|
+
FFDec is automatically downloaded on first run if not found. You can also install it manually.
|
|
136
|
+
|
|
137
|
+
The server finds FFDec in this order:
|
|
138
|
+
|
|
139
|
+
1. `--ffdec-path` CLI arg / `FFDEC_PATH` env var
|
|
140
|
+
2. Previously auto-downloaded JAR (`~/.ffdecmcp/ffdec.jar`)
|
|
141
|
+
3. Common install locations and PATH
|
|
142
|
+
5. Auto-download from GitHub
|
|
143
|
+
|
|
144
|
+
### CLI Options
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
ffdecmcp [--ffdec-path PATH] [--timeout SECONDS]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
| Option | Env Var | Description |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| `--ffdec-path` | `FFDEC_PATH` | Path to FFDec (JAR, native binary, or WSL path) |
|
|
153
|
+
| `--timeout` | `FFDEC_TIMEOUT` | Default timeout in seconds (default: 60) |
|
|
154
|
+
|
|
155
|
+
CLI arguments take precedence over environment variables.
|
|
156
|
+
|
|
157
|
+
### Development
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
git clone https://github.com/sublimnl/ffdecmcp.git
|
|
161
|
+
cd ffdecmcp
|
|
162
|
+
uv pip install -e ".[dev]"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Example Usage in Claude
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
You: Can you analyze this SWF file for me?
|
|
169
|
+
Path: C:\Users\foo\game.swf
|
|
170
|
+
|
|
171
|
+
Claude will:
|
|
172
|
+
1. Use get_swf_metadata to check dimensions, version, etc.
|
|
173
|
+
2. Use list_symbols to see what classes are present
|
|
174
|
+
3. Use decompile_swf to extract all ActionScript code
|
|
175
|
+
4. Analyze the decompiled code and provide insights
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## References
|
|
179
|
+
|
|
180
|
+
- **FFDec**: https://github.com/jindrapetrik/jpexs-decompiler
|
|
181
|
+
- **FFDec CLI Docs**: https://github.com/jindrapetrik/jpexs-decompiler/wiki/Commandline-arguments
|
|
182
|
+
- **Model Context Protocol**: https://modelcontextprotocol.io
|
|
183
|
+
- **FastMCP**: https://github.com/jlowin/fastmcp
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
MIT License - see LICENSE file for details
|
|
188
|
+
|
|
189
|
+
## Contributing
|
|
190
|
+
|
|
191
|
+
Contributions welcome! Please open an issue or PR on GitHub.
|
ffdecmcp-0.1.0/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# ffdecmcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) wrapper for **JPEXS Free Flash Decompiler (FFDec)** - expose SWF decompilation and analysis tools to AI assistants like Claude.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
### 1. `decompile_swf`
|
|
8
|
+
Decompile all ActionScript code from a SWF file to organized directory structure.
|
|
9
|
+
|
|
10
|
+
**Parameters:**
|
|
11
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
12
|
+
- `output_dir` (required): Directory for decompiled scripts
|
|
13
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
14
|
+
|
|
15
|
+
### 2. `extract_actionscript`
|
|
16
|
+
Extract specific ActionScript classes by name (AS3 only). Faster than full decompilation when you only need specific classes.
|
|
17
|
+
|
|
18
|
+
**Parameters:**
|
|
19
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
20
|
+
- `class_names` (required): List of class names (e.g., `['com.example.Main']`)
|
|
21
|
+
- `output_dir` (required): Directory for extracted classes
|
|
22
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
23
|
+
|
|
24
|
+
### 3. `list_symbols`
|
|
25
|
+
List all ActionScript classes and symbols in a SWF file. Great for exploring a SWF before full decompilation.
|
|
26
|
+
|
|
27
|
+
**Parameters:**
|
|
28
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
29
|
+
|
|
30
|
+
**Returns:** Structured JSON with packages, classes, and total count
|
|
31
|
+
|
|
32
|
+
### 4. `extract_assets`
|
|
33
|
+
Extract images, sounds, fonts, shapes, movie clips, and binary data from SWF.
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
37
|
+
- `output_dir` (required): Directory for extracted assets
|
|
38
|
+
- `asset_types` (optional): Types to extract - `image`, `sound`, `font`, `shape`, `movie`, `binaryData`, `all` (default: `["all"]`)
|
|
39
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
40
|
+
|
|
41
|
+
### 5. `get_swf_metadata`
|
|
42
|
+
Extract SWF header information (dimensions, frame rate, compression, etc.). Fast and doesn't require decompilation.
|
|
43
|
+
|
|
44
|
+
**Parameters:**
|
|
45
|
+
- `swf_path` (required): Absolute path to SWF file
|
|
46
|
+
|
|
47
|
+
**Returns:** JSON with version, width, height, frame_rate, frame_count, compression
|
|
48
|
+
|
|
49
|
+
### 6. `deobfuscate`
|
|
50
|
+
Run FFDec's deobfuscation algorithms to remove obfuscation and anti-decompilation tricks.
|
|
51
|
+
|
|
52
|
+
**Parameters:**
|
|
53
|
+
- `swf_path` (required): Absolute path to obfuscated SWF
|
|
54
|
+
- `output_path` (required): Path for deobfuscated SWF
|
|
55
|
+
- `level` (optional): Deobfuscation level - `traps`, `deadcode`, `max` (default: `max`)
|
|
56
|
+
- `timeout` (optional): Timeout in seconds (default: 60)
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
**Prerequisites:** Python 3.10+ and Java (for running the FFDec JAR).
|
|
61
|
+
|
|
62
|
+
### Claude Code
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
claude mcp add ffdecmcp -- uvx ffdecmcp
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
That's it. On first run, FFDec will be auto-downloaded if not already installed.
|
|
69
|
+
|
|
70
|
+
### Claude Desktop
|
|
71
|
+
|
|
72
|
+
Add to your config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"ffdecmcp": {
|
|
78
|
+
"command": "uvx",
|
|
79
|
+
"args": ["ffdecmcp"]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Standalone
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Just run it - FFDec will be auto-downloaded to ~/.ffdecmcp/ if needed
|
|
89
|
+
uvx ffdecmcp
|
|
90
|
+
|
|
91
|
+
# Or point to an existing FFDec installation
|
|
92
|
+
uvx ffdecmcp --ffdec-path /path/to/ffdec.jar
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Installation
|
|
96
|
+
|
|
97
|
+
No installation is required when using `uvx`. For a permanent install:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
uv pip install ffdecmcp
|
|
101
|
+
# or
|
|
102
|
+
pip install ffdecmcp
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### FFDec
|
|
106
|
+
|
|
107
|
+
FFDec is automatically downloaded on first run if not found. You can also install it manually.
|
|
108
|
+
|
|
109
|
+
The server finds FFDec in this order:
|
|
110
|
+
|
|
111
|
+
1. `--ffdec-path` CLI arg / `FFDEC_PATH` env var
|
|
112
|
+
2. Previously auto-downloaded JAR (`~/.ffdecmcp/ffdec.jar`)
|
|
113
|
+
3. Common install locations and PATH
|
|
114
|
+
5. Auto-download from GitHub
|
|
115
|
+
|
|
116
|
+
### CLI Options
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
ffdecmcp [--ffdec-path PATH] [--timeout SECONDS]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Option | Env Var | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `--ffdec-path` | `FFDEC_PATH` | Path to FFDec (JAR, native binary, or WSL path) |
|
|
125
|
+
| `--timeout` | `FFDEC_TIMEOUT` | Default timeout in seconds (default: 60) |
|
|
126
|
+
|
|
127
|
+
CLI arguments take precedence over environment variables.
|
|
128
|
+
|
|
129
|
+
### Development
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
git clone https://github.com/sublimnl/ffdecmcp.git
|
|
133
|
+
cd ffdecmcp
|
|
134
|
+
uv pip install -e ".[dev]"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Example Usage in Claude
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
You: Can you analyze this SWF file for me?
|
|
141
|
+
Path: C:\Users\foo\game.swf
|
|
142
|
+
|
|
143
|
+
Claude will:
|
|
144
|
+
1. Use get_swf_metadata to check dimensions, version, etc.
|
|
145
|
+
2. Use list_symbols to see what classes are present
|
|
146
|
+
3. Use decompile_swf to extract all ActionScript code
|
|
147
|
+
4. Analyze the decompiled code and provide insights
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## References
|
|
151
|
+
|
|
152
|
+
- **FFDec**: https://github.com/jindrapetrik/jpexs-decompiler
|
|
153
|
+
- **FFDec CLI Docs**: https://github.com/jindrapetrik/jpexs-decompiler/wiki/Commandline-arguments
|
|
154
|
+
- **Model Context Protocol**: https://modelcontextprotocol.io
|
|
155
|
+
- **FastMCP**: https://github.com/jlowin/fastmcp
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT License - see LICENSE file for details
|
|
160
|
+
|
|
161
|
+
## Contributing
|
|
162
|
+
|
|
163
|
+
Contributions welcome! Please open an issue or PR on GitHub.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ffdecmcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP wrapper for JPEXS Free Flash Decompiler (FFDec) - expose SWF decompilation tools to AI assistants"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "sublimnl" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["mcp", "ffdec", "swf", "flash", "decompiler", "actionscript"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"fastmcp>=2.14.0",
|
|
28
|
+
"python-dotenv>=1.0.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/sublimnl/ffdecmcp"
|
|
33
|
+
Repository = "https://github.com/sublimnl/ffdecmcp"
|
|
34
|
+
Issues = "https://github.com/sublimnl/ffdecmcp/issues"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=7.0.0",
|
|
39
|
+
"pytest-asyncio>=0.21.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
ffdecmcp = "ffdecmcp.__main__:main"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
where = ["src"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-data]
|
|
49
|
+
ffdecmcp = ["py.typed"]
|
ffdecmcp-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Entry point for ffdecmcp server."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
|
|
10
|
+
# Configure logging to stderr (critical for STDIO transport)
|
|
11
|
+
logging.basicConfig(
|
|
12
|
+
level=logging.INFO,
|
|
13
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
14
|
+
stream=sys.stderr,
|
|
15
|
+
)
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main():
|
|
20
|
+
"""Main entry point for ffdecmcp server."""
|
|
21
|
+
parser = argparse.ArgumentParser(
|
|
22
|
+
prog="ffdecmcp",
|
|
23
|
+
description="MCP server for JPEXS Free Flash Decompiler (FFDec)",
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--ffdec-path",
|
|
27
|
+
metavar="PATH",
|
|
28
|
+
help="Path to FFDec (JAR file, native binary, or WSL path). "
|
|
29
|
+
"Can also be set via FFDEC_PATH env var.",
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--timeout",
|
|
33
|
+
type=int,
|
|
34
|
+
metavar="SECONDS",
|
|
35
|
+
help="Default timeout for FFDec operations in seconds (default: 60). "
|
|
36
|
+
"Can also be set via FFDEC_TIMEOUT env var.",
|
|
37
|
+
)
|
|
38
|
+
args = parser.parse_args()
|
|
39
|
+
|
|
40
|
+
# CLI args take precedence over env vars
|
|
41
|
+
if args.ffdec_path:
|
|
42
|
+
os.environ["FFDEC_PATH"] = args.ffdec_path
|
|
43
|
+
if args.timeout is not None:
|
|
44
|
+
os.environ["FFDEC_TIMEOUT"] = str(args.timeout)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Load .env file (env vars and CLI args take precedence)
|
|
48
|
+
load_dotenv()
|
|
49
|
+
|
|
50
|
+
logger.info("Starting ffdecmcp server...")
|
|
51
|
+
|
|
52
|
+
# Import after environment is loaded
|
|
53
|
+
from .config import get_config
|
|
54
|
+
from .server import mcp
|
|
55
|
+
|
|
56
|
+
# Verify FFDec configuration on startup - fail fast if not found
|
|
57
|
+
try:
|
|
58
|
+
config = get_config()
|
|
59
|
+
logger.info(
|
|
60
|
+
f"FFDec detected: mode={config.mode.value}, path={config.path}, timeout={config.timeout}s"
|
|
61
|
+
)
|
|
62
|
+
except RuntimeError as e:
|
|
63
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
64
|
+
sys.exit(1)
|
|
65
|
+
|
|
66
|
+
# Run the FastMCP server
|
|
67
|
+
logger.info("ffdecmcp server started successfully")
|
|
68
|
+
mcp.run()
|
|
69
|
+
|
|
70
|
+
except KeyboardInterrupt:
|
|
71
|
+
logger.info("Server shutdown requested")
|
|
72
|
+
sys.exit(0)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
logger.error(f"Failed to start server: {e}", exc_info=True)
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
main()
|