morfiade-mcp 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.
- morfiade_mcp-0.1.0/LICENSE +21 -0
- morfiade_mcp-0.1.0/PKG-INFO +260 -0
- morfiade_mcp-0.1.0/README.md +237 -0
- morfiade_mcp-0.1.0/morfiade_mcp.egg-info/PKG-INFO +260 -0
- morfiade_mcp-0.1.0/morfiade_mcp.egg-info/SOURCES.txt +9 -0
- morfiade_mcp-0.1.0/morfiade_mcp.egg-info/dependency_links.txt +1 -0
- morfiade_mcp-0.1.0/morfiade_mcp.egg-info/entry_points.txt +2 -0
- morfiade_mcp-0.1.0/morfiade_mcp.egg-info/top_level.txt +1 -0
- morfiade_mcp-0.1.0/morfiade_mcp.py +141 -0
- morfiade_mcp-0.1.0/pyproject.toml +35 -0
- morfiade_mcp-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Morfiade
|
|
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.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: morfiade-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Launcher for the Morfiade MCP server — manage local Chrome profiles on Windows from an AI agent
|
|
5
|
+
Author-email: Morfiade <github@morfiade.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://morfiade.com/en/
|
|
8
|
+
Project-URL: Repository, https://github.com/morfiade-app/morfiade-mcp
|
|
9
|
+
Project-URL: Documentation, https://github.com/morfiade-app/morfiade-mcp/blob/main/docs/TOOLS.md
|
|
10
|
+
Keywords: mcp,model-context-protocol,chrome,profiles,multi-account,browser-automation
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Requires-Python: >=3.7
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# Morfiade MCP
|
|
25
|
+
|
|
26
|
+
<!-- mcp-name: io.github.morfiade-app/morfiade-mcp -->
|
|
27
|
+
|
|
28
|
+
**MCP server for local Google Chrome profiles on Windows.** 18 tools that let an
|
|
29
|
+
AI agent list, create, launch and organise real Chrome profiles on your own
|
|
30
|
+
machine — each with its own cookies, sessions and proxy.
|
|
31
|
+
|
|
32
|
+
The server is not a package you download: it ships inside
|
|
33
|
+
[Morfiade](https://morfiade.com/en/), the Chrome profile manager itself, and
|
|
34
|
+
starts with a flag. Transport is stdio (JSON-RPC 2.0), protocol version
|
|
35
|
+
`2025-11-25`. Nothing is fetched from the internet, nothing passes through
|
|
36
|
+
anyone else's server.
|
|
37
|
+
|
|
38
|
+
This repository is the documentation, the ready-made client configs and an
|
|
39
|
+
optional launcher. Русская версия — [README.ru.md](README.ru.md).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## What makes it different
|
|
44
|
+
|
|
45
|
+
**The bridge lives in the program.** AdsPower and GoLogin publish MCP servers as
|
|
46
|
+
separate packages that talk to their cloud. Morfiade keeps profiles on your
|
|
47
|
+
disk, so the bridge stays on your disk too: `Morfiade.exe --mcp`, over the
|
|
48
|
+
loopback interface, no network required.
|
|
49
|
+
|
|
50
|
+
**Distributing values across windows.** The tools with no equivalent elsewhere
|
|
51
|
+
are `sync_sets` / `sync_spread` / `sync_insert`: a list of values — emails,
|
|
52
|
+
logins, anything line-based — is split across the open windows, one value pinned
|
|
53
|
+
per profile. A repeat call does not reshuffle what is already pinned, otherwise
|
|
54
|
+
an account would be registered on one email and confirmed with another. The
|
|
55
|
+
agent never sees the values themselves (see
|
|
56
|
+
[Security](#security-what-the-agent-cannot-do)).
|
|
57
|
+
|
|
58
|
+
Example prompts that work out of the box:
|
|
59
|
+
|
|
60
|
+
> Create twenty profiles with the prefix `shop`, give them proxies from this
|
|
61
|
+
> list, and launch the first five.
|
|
62
|
+
|
|
63
|
+
> Check the proxies on every profile I can manage and tell me which ones are
|
|
64
|
+
> dead or exiting from the wrong country.
|
|
65
|
+
|
|
66
|
+
> Take the `mail-batch` set, spread it across the open windows and show me who
|
|
67
|
+
> got what. I'll put the cursor in the email field, then insert.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Requirements
|
|
72
|
+
|
|
73
|
+
- Windows 10 or 11
|
|
74
|
+
- [Morfiade](https://morfiade.com/en/) 3.36 or newer, **running**
|
|
75
|
+
- **Local API enabled** in its settings — the server refuses to start without it
|
|
76
|
+
instead of failing silently
|
|
77
|
+
- The **"API" checkbox ticked** on the profiles the agent may touch; it is off by
|
|
78
|
+
default, and unticked profiles do not exist as far as the agent is concerned
|
|
79
|
+
- A valid licence to *launch* profiles (that check lives in the manager, not here)
|
|
80
|
+
- Any MCP client with stdio support: Claude Code, Claude Desktop, Cursor,
|
|
81
|
+
Gemini CLI, VS Code, your own
|
|
82
|
+
|
|
83
|
+
No `pip install`, no Node, no API key to register.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Setup
|
|
88
|
+
|
|
89
|
+
Point your client at the executable and pass `--mcp`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"morfiade": {
|
|
95
|
+
"command": "C:\\Program Files\\Morfiade\\Morfiade.exe",
|
|
96
|
+
"args": ["--mcp"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Ready-made files for the common clients are in [`examples/`](examples/).
|
|
103
|
+
Claude Code can do it in one line:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
claude mcp add morfiade -- "C:\Program Files\Morfiade\Morfiade.exe" --mcp
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Where the config file lives differs per client and changes more often than this
|
|
110
|
+
README — check your client's own docs.
|
|
111
|
+
|
|
112
|
+
### Optional launcher
|
|
113
|
+
|
|
114
|
+
If you would rather not hardcode the path,
|
|
115
|
+
[`morfiade_mcp.py`](morfiade_mcp.py) finds the executable (via `MORFIADE_EXE`,
|
|
116
|
+
the installer's registry key, the usual install directories, or `PATH`),
|
|
117
|
+
forwards stdio and returns its exit code. Requires Python 3.7+ and nothing else.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
pip install morfiade-mcp
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"morfiade": {
|
|
127
|
+
"command": "morfiade-mcp"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If your client needs an absolute path, point it at the `morfiade-mcp.exe`
|
|
134
|
+
that pip put in your Python `Scripts` directory — or skip the package and run
|
|
135
|
+
the single file directly:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"morfiade": {
|
|
141
|
+
"command": "python",
|
|
142
|
+
"args": ["C:\\path\\to\\morfiade_mcp.py"]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The package contains only that launcher. The server, and everything it talks
|
|
149
|
+
to, is the desktop app.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Tools
|
|
154
|
+
|
|
155
|
+
Full parameters and return shapes: [`docs/TOOLS.md`](docs/TOOLS.md).
|
|
156
|
+
|
|
157
|
+
| Tool | What it does |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `status` | version, how many profiles exist, how many the agent may use, how many are running |
|
|
160
|
+
| `list_profiles` | the permitted profiles: name, running or not, proxy, note |
|
|
161
|
+
| `create_profile` | create a profile — optionally with proxy, note and category; permitted for the agent immediately |
|
|
162
|
+
| `start_profile` | launch a profile, optionally straight onto a URL |
|
|
163
|
+
| `stop_profile` | close the profile window |
|
|
164
|
+
| `set_proxy` | assign a proxy (`type://user:pass@host:port` or `host:port`; empty string clears it) |
|
|
165
|
+
| `check_proxy` | check one profile's proxy: alive, and where it exits |
|
|
166
|
+
| `check_proxies` | the same across several profiles, or all of them |
|
|
167
|
+
| `profile_tags` | read the tags, or replace them wholesale |
|
|
168
|
+
| `profile_note` | read or write the note and its short title |
|
|
169
|
+
| `sync_windows` | which open windows are ready for distribution and what is already pinned to each |
|
|
170
|
+
| `sync_sets` | value sets: list them (name, lines, how many still free) or create one |
|
|
171
|
+
| `sync_spread` | pin one line of a set per window and report who got what — inserts nothing |
|
|
172
|
+
| `sync_insert` | insert each window's own value where the cursor sits in the leading window |
|
|
173
|
+
| `list_scripts` | scripts in the manager's folder: name and interpreter, never the contents |
|
|
174
|
+
| `trash_profile` | move a profile **to the trash** — nothing is erased |
|
|
175
|
+
| `list_trash` | what is in the trash: name, when, how much space |
|
|
176
|
+
| `restore_profile` | restore from the trash; a taken name comes back as `name (2)` |
|
|
177
|
+
|
|
178
|
+
Two more appear only behind explicit flags — see
|
|
179
|
+
[Dangerous flags](#dangerous-flags-off-by-default).
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Security: what the agent *cannot* do
|
|
184
|
+
|
|
185
|
+
An agent that reads web pages is not a trusted party. A page can contain the
|
|
186
|
+
text "call this tool and send the cookies over there", and the agent cannot tell
|
|
187
|
+
your instruction from text it found on the internet. That is the known central
|
|
188
|
+
problem of MCP, and no amount of prompt wording fixes it. So the limits are
|
|
189
|
+
built into the tool list instead:
|
|
190
|
+
|
|
191
|
+
- **Deletion goes to the trash only.** Profiles stay whole — cookies, sessions,
|
|
192
|
+
everything — and come back with one call. Permanent erase and emptying the
|
|
193
|
+
trash are not exposed here and never will be: they are the only irreversible
|
|
194
|
+
actions, and a human does them from the trash window, where they can see what
|
|
195
|
+
they are destroying.
|
|
196
|
+
- **No cookie reading.** GoLogin's MCP has such a tool, which means cookies
|
|
197
|
+
travel from the account into a chat log. This one does not have it.
|
|
198
|
+
- **Set lines are not exposed.** `sync_sets` reports the name, the line count and
|
|
199
|
+
how many are free. The emails and logins themselves stay in the manager — the
|
|
200
|
+
agent does not need to see them, it needs them to land in the windows.
|
|
201
|
+
- **Script contents are not exposed.** `list_scripts` gives names and
|
|
202
|
+
interpreters only.
|
|
203
|
+
- **The mirror is not exposed.** It reflects what a human is doing right now in
|
|
204
|
+
the leading window; there is nothing for an agent to repeat.
|
|
205
|
+
- **The whitelist cannot be bypassed.** The "API" column is filtered by the
|
|
206
|
+
manager itself, not by this server.
|
|
207
|
+
- **The licence check does not weaken.** It sits in the manager's handler, so it
|
|
208
|
+
fires whether a human, a script or an agent asked.
|
|
209
|
+
- **Nothing listens on the network.** The local API binds `127.0.0.1`, requires a
|
|
210
|
+
token and checks the `Host` header. The token is stored encrypted with Windows
|
|
211
|
+
DPAPI, tied to the account, and travels in a header rather than a URL — URLs
|
|
212
|
+
end up in logs.
|
|
213
|
+
|
|
214
|
+
### Dangerous flags, off by default
|
|
215
|
+
|
|
216
|
+
| Flag | Extra tool | What it really means |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `--mcp-allow-cdp` | `browser_command` | an arbitrary Chrome DevTools Protocol command. `Runtime.evaluate` in a logged-in profile reads cookies, storage and page contents — full access to your accounts, not "advanced management" |
|
|
219
|
+
| `--mcp-allow-scripts` | `run_script` | runs a script from the manager's folder — code execution on your machine |
|
|
220
|
+
|
|
221
|
+
Both are worth turning on only with the paragraph above in mind, and only for
|
|
222
|
+
pages you trust.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
| What you see | What to do |
|
|
229
|
+
|---|---|
|
|
230
|
+
| the client shows no tools | check the path to the exe in the client config |
|
|
231
|
+
| "local API is off" | enable the local API in the manager's settings |
|
|
232
|
+
| "no port or token in config.json" | open the manager once so it writes its settings |
|
|
233
|
+
| "the manager does not answer" | the manager has to be running |
|
|
234
|
+
| "profile not found", though it exists | the "API" checkbox is not ticked on that profile |
|
|
235
|
+
| "the API token contains invalid characters" | the config came from another machine — reissue the token in settings |
|
|
236
|
+
| launching a profile is refused | no valid licence: profile launch is closed over the API and MCP alike |
|
|
237
|
+
|
|
238
|
+
Messages come from the manager and follow its interface language — five are
|
|
239
|
+
available, so the wording you see may be your own.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## What is not here
|
|
244
|
+
|
|
245
|
+
The bridge itself is compiled into `Morfiade.exe`, and the **session transfer**
|
|
246
|
+
mechanism — the part that actually moves logged-in sessions between machines —
|
|
247
|
+
stays closed. This repository is the outside of the product: documentation,
|
|
248
|
+
configs, the launcher.
|
|
249
|
+
|
|
250
|
+
## Links
|
|
251
|
+
|
|
252
|
+
- [morfiade.com](https://morfiade.com/en/) — the manager itself
|
|
253
|
+
- [Running browser profiles from an AI agent](https://morfiade.com/en/blog/mcp-brauzer/) — what this looks like in practice
|
|
254
|
+
- [Manual](https://morfiade.com/en/manual/) — the AI agent access section
|
|
255
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) — the protocol
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
MIT for everything in this repository — see [LICENSE](LICENSE). The manager is a
|
|
260
|
+
separate commercial product with its own terms.
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Morfiade MCP
|
|
2
|
+
|
|
3
|
+
<!-- mcp-name: io.github.morfiade-app/morfiade-mcp -->
|
|
4
|
+
|
|
5
|
+
**MCP server for local Google Chrome profiles on Windows.** 18 tools that let an
|
|
6
|
+
AI agent list, create, launch and organise real Chrome profiles on your own
|
|
7
|
+
machine — each with its own cookies, sessions and proxy.
|
|
8
|
+
|
|
9
|
+
The server is not a package you download: it ships inside
|
|
10
|
+
[Morfiade](https://morfiade.com/en/), the Chrome profile manager itself, and
|
|
11
|
+
starts with a flag. Transport is stdio (JSON-RPC 2.0), protocol version
|
|
12
|
+
`2025-11-25`. Nothing is fetched from the internet, nothing passes through
|
|
13
|
+
anyone else's server.
|
|
14
|
+
|
|
15
|
+
This repository is the documentation, the ready-made client configs and an
|
|
16
|
+
optional launcher. Русская версия — [README.ru.md](README.ru.md).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What makes it different
|
|
21
|
+
|
|
22
|
+
**The bridge lives in the program.** AdsPower and GoLogin publish MCP servers as
|
|
23
|
+
separate packages that talk to their cloud. Morfiade keeps profiles on your
|
|
24
|
+
disk, so the bridge stays on your disk too: `Morfiade.exe --mcp`, over the
|
|
25
|
+
loopback interface, no network required.
|
|
26
|
+
|
|
27
|
+
**Distributing values across windows.** The tools with no equivalent elsewhere
|
|
28
|
+
are `sync_sets` / `sync_spread` / `sync_insert`: a list of values — emails,
|
|
29
|
+
logins, anything line-based — is split across the open windows, one value pinned
|
|
30
|
+
per profile. A repeat call does not reshuffle what is already pinned, otherwise
|
|
31
|
+
an account would be registered on one email and confirmed with another. The
|
|
32
|
+
agent never sees the values themselves (see
|
|
33
|
+
[Security](#security-what-the-agent-cannot-do)).
|
|
34
|
+
|
|
35
|
+
Example prompts that work out of the box:
|
|
36
|
+
|
|
37
|
+
> Create twenty profiles with the prefix `shop`, give them proxies from this
|
|
38
|
+
> list, and launch the first five.
|
|
39
|
+
|
|
40
|
+
> Check the proxies on every profile I can manage and tell me which ones are
|
|
41
|
+
> dead or exiting from the wrong country.
|
|
42
|
+
|
|
43
|
+
> Take the `mail-batch` set, spread it across the open windows and show me who
|
|
44
|
+
> got what. I'll put the cursor in the email field, then insert.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
- Windows 10 or 11
|
|
51
|
+
- [Morfiade](https://morfiade.com/en/) 3.36 or newer, **running**
|
|
52
|
+
- **Local API enabled** in its settings — the server refuses to start without it
|
|
53
|
+
instead of failing silently
|
|
54
|
+
- The **"API" checkbox ticked** on the profiles the agent may touch; it is off by
|
|
55
|
+
default, and unticked profiles do not exist as far as the agent is concerned
|
|
56
|
+
- A valid licence to *launch* profiles (that check lives in the manager, not here)
|
|
57
|
+
- Any MCP client with stdio support: Claude Code, Claude Desktop, Cursor,
|
|
58
|
+
Gemini CLI, VS Code, your own
|
|
59
|
+
|
|
60
|
+
No `pip install`, no Node, no API key to register.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Setup
|
|
65
|
+
|
|
66
|
+
Point your client at the executable and pass `--mcp`:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"morfiade": {
|
|
72
|
+
"command": "C:\\Program Files\\Morfiade\\Morfiade.exe",
|
|
73
|
+
"args": ["--mcp"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Ready-made files for the common clients are in [`examples/`](examples/).
|
|
80
|
+
Claude Code can do it in one line:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
claude mcp add morfiade -- "C:\Program Files\Morfiade\Morfiade.exe" --mcp
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Where the config file lives differs per client and changes more often than this
|
|
87
|
+
README — check your client's own docs.
|
|
88
|
+
|
|
89
|
+
### Optional launcher
|
|
90
|
+
|
|
91
|
+
If you would rather not hardcode the path,
|
|
92
|
+
[`morfiade_mcp.py`](morfiade_mcp.py) finds the executable (via `MORFIADE_EXE`,
|
|
93
|
+
the installer's registry key, the usual install directories, or `PATH`),
|
|
94
|
+
forwards stdio and returns its exit code. Requires Python 3.7+ and nothing else.
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
pip install morfiade-mcp
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"morfiade": {
|
|
104
|
+
"command": "morfiade-mcp"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If your client needs an absolute path, point it at the `morfiade-mcp.exe`
|
|
111
|
+
that pip put in your Python `Scripts` directory — or skip the package and run
|
|
112
|
+
the single file directly:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"mcpServers": {
|
|
117
|
+
"morfiade": {
|
|
118
|
+
"command": "python",
|
|
119
|
+
"args": ["C:\\path\\to\\morfiade_mcp.py"]
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The package contains only that launcher. The server, and everything it talks
|
|
126
|
+
to, is the desktop app.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Tools
|
|
131
|
+
|
|
132
|
+
Full parameters and return shapes: [`docs/TOOLS.md`](docs/TOOLS.md).
|
|
133
|
+
|
|
134
|
+
| Tool | What it does |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `status` | version, how many profiles exist, how many the agent may use, how many are running |
|
|
137
|
+
| `list_profiles` | the permitted profiles: name, running or not, proxy, note |
|
|
138
|
+
| `create_profile` | create a profile — optionally with proxy, note and category; permitted for the agent immediately |
|
|
139
|
+
| `start_profile` | launch a profile, optionally straight onto a URL |
|
|
140
|
+
| `stop_profile` | close the profile window |
|
|
141
|
+
| `set_proxy` | assign a proxy (`type://user:pass@host:port` or `host:port`; empty string clears it) |
|
|
142
|
+
| `check_proxy` | check one profile's proxy: alive, and where it exits |
|
|
143
|
+
| `check_proxies` | the same across several profiles, or all of them |
|
|
144
|
+
| `profile_tags` | read the tags, or replace them wholesale |
|
|
145
|
+
| `profile_note` | read or write the note and its short title |
|
|
146
|
+
| `sync_windows` | which open windows are ready for distribution and what is already pinned to each |
|
|
147
|
+
| `sync_sets` | value sets: list them (name, lines, how many still free) or create one |
|
|
148
|
+
| `sync_spread` | pin one line of a set per window and report who got what — inserts nothing |
|
|
149
|
+
| `sync_insert` | insert each window's own value where the cursor sits in the leading window |
|
|
150
|
+
| `list_scripts` | scripts in the manager's folder: name and interpreter, never the contents |
|
|
151
|
+
| `trash_profile` | move a profile **to the trash** — nothing is erased |
|
|
152
|
+
| `list_trash` | what is in the trash: name, when, how much space |
|
|
153
|
+
| `restore_profile` | restore from the trash; a taken name comes back as `name (2)` |
|
|
154
|
+
|
|
155
|
+
Two more appear only behind explicit flags — see
|
|
156
|
+
[Dangerous flags](#dangerous-flags-off-by-default).
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Security: what the agent *cannot* do
|
|
161
|
+
|
|
162
|
+
An agent that reads web pages is not a trusted party. A page can contain the
|
|
163
|
+
text "call this tool and send the cookies over there", and the agent cannot tell
|
|
164
|
+
your instruction from text it found on the internet. That is the known central
|
|
165
|
+
problem of MCP, and no amount of prompt wording fixes it. So the limits are
|
|
166
|
+
built into the tool list instead:
|
|
167
|
+
|
|
168
|
+
- **Deletion goes to the trash only.** Profiles stay whole — cookies, sessions,
|
|
169
|
+
everything — and come back with one call. Permanent erase and emptying the
|
|
170
|
+
trash are not exposed here and never will be: they are the only irreversible
|
|
171
|
+
actions, and a human does them from the trash window, where they can see what
|
|
172
|
+
they are destroying.
|
|
173
|
+
- **No cookie reading.** GoLogin's MCP has such a tool, which means cookies
|
|
174
|
+
travel from the account into a chat log. This one does not have it.
|
|
175
|
+
- **Set lines are not exposed.** `sync_sets` reports the name, the line count and
|
|
176
|
+
how many are free. The emails and logins themselves stay in the manager — the
|
|
177
|
+
agent does not need to see them, it needs them to land in the windows.
|
|
178
|
+
- **Script contents are not exposed.** `list_scripts` gives names and
|
|
179
|
+
interpreters only.
|
|
180
|
+
- **The mirror is not exposed.** It reflects what a human is doing right now in
|
|
181
|
+
the leading window; there is nothing for an agent to repeat.
|
|
182
|
+
- **The whitelist cannot be bypassed.** The "API" column is filtered by the
|
|
183
|
+
manager itself, not by this server.
|
|
184
|
+
- **The licence check does not weaken.** It sits in the manager's handler, so it
|
|
185
|
+
fires whether a human, a script or an agent asked.
|
|
186
|
+
- **Nothing listens on the network.** The local API binds `127.0.0.1`, requires a
|
|
187
|
+
token and checks the `Host` header. The token is stored encrypted with Windows
|
|
188
|
+
DPAPI, tied to the account, and travels in a header rather than a URL — URLs
|
|
189
|
+
end up in logs.
|
|
190
|
+
|
|
191
|
+
### Dangerous flags, off by default
|
|
192
|
+
|
|
193
|
+
| Flag | Extra tool | What it really means |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| `--mcp-allow-cdp` | `browser_command` | an arbitrary Chrome DevTools Protocol command. `Runtime.evaluate` in a logged-in profile reads cookies, storage and page contents — full access to your accounts, not "advanced management" |
|
|
196
|
+
| `--mcp-allow-scripts` | `run_script` | runs a script from the manager's folder — code execution on your machine |
|
|
197
|
+
|
|
198
|
+
Both are worth turning on only with the paragraph above in mind, and only for
|
|
199
|
+
pages you trust.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Troubleshooting
|
|
204
|
+
|
|
205
|
+
| What you see | What to do |
|
|
206
|
+
|---|---|
|
|
207
|
+
| the client shows no tools | check the path to the exe in the client config |
|
|
208
|
+
| "local API is off" | enable the local API in the manager's settings |
|
|
209
|
+
| "no port or token in config.json" | open the manager once so it writes its settings |
|
|
210
|
+
| "the manager does not answer" | the manager has to be running |
|
|
211
|
+
| "profile not found", though it exists | the "API" checkbox is not ticked on that profile |
|
|
212
|
+
| "the API token contains invalid characters" | the config came from another machine — reissue the token in settings |
|
|
213
|
+
| launching a profile is refused | no valid licence: profile launch is closed over the API and MCP alike |
|
|
214
|
+
|
|
215
|
+
Messages come from the manager and follow its interface language — five are
|
|
216
|
+
available, so the wording you see may be your own.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## What is not here
|
|
221
|
+
|
|
222
|
+
The bridge itself is compiled into `Morfiade.exe`, and the **session transfer**
|
|
223
|
+
mechanism — the part that actually moves logged-in sessions between machines —
|
|
224
|
+
stays closed. This repository is the outside of the product: documentation,
|
|
225
|
+
configs, the launcher.
|
|
226
|
+
|
|
227
|
+
## Links
|
|
228
|
+
|
|
229
|
+
- [morfiade.com](https://morfiade.com/en/) — the manager itself
|
|
230
|
+
- [Running browser profiles from an AI agent](https://morfiade.com/en/blog/mcp-brauzer/) — what this looks like in practice
|
|
231
|
+
- [Manual](https://morfiade.com/en/manual/) — the AI agent access section
|
|
232
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) — the protocol
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT for everything in this repository — see [LICENSE](LICENSE). The manager is a
|
|
237
|
+
separate commercial product with its own terms.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: morfiade-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Launcher for the Morfiade MCP server — manage local Chrome profiles on Windows from an AI agent
|
|
5
|
+
Author-email: Morfiade <github@morfiade.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://morfiade.com/en/
|
|
8
|
+
Project-URL: Repository, https://github.com/morfiade-app/morfiade-mcp
|
|
9
|
+
Project-URL: Documentation, https://github.com/morfiade-app/morfiade-mcp/blob/main/docs/TOOLS.md
|
|
10
|
+
Keywords: mcp,model-context-protocol,chrome,profiles,multi-account,browser-automation
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Requires-Python: >=3.7
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# Morfiade MCP
|
|
25
|
+
|
|
26
|
+
<!-- mcp-name: io.github.morfiade-app/morfiade-mcp -->
|
|
27
|
+
|
|
28
|
+
**MCP server for local Google Chrome profiles on Windows.** 18 tools that let an
|
|
29
|
+
AI agent list, create, launch and organise real Chrome profiles on your own
|
|
30
|
+
machine — each with its own cookies, sessions and proxy.
|
|
31
|
+
|
|
32
|
+
The server is not a package you download: it ships inside
|
|
33
|
+
[Morfiade](https://morfiade.com/en/), the Chrome profile manager itself, and
|
|
34
|
+
starts with a flag. Transport is stdio (JSON-RPC 2.0), protocol version
|
|
35
|
+
`2025-11-25`. Nothing is fetched from the internet, nothing passes through
|
|
36
|
+
anyone else's server.
|
|
37
|
+
|
|
38
|
+
This repository is the documentation, the ready-made client configs and an
|
|
39
|
+
optional launcher. Русская версия — [README.ru.md](README.ru.md).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## What makes it different
|
|
44
|
+
|
|
45
|
+
**The bridge lives in the program.** AdsPower and GoLogin publish MCP servers as
|
|
46
|
+
separate packages that talk to their cloud. Morfiade keeps profiles on your
|
|
47
|
+
disk, so the bridge stays on your disk too: `Morfiade.exe --mcp`, over the
|
|
48
|
+
loopback interface, no network required.
|
|
49
|
+
|
|
50
|
+
**Distributing values across windows.** The tools with no equivalent elsewhere
|
|
51
|
+
are `sync_sets` / `sync_spread` / `sync_insert`: a list of values — emails,
|
|
52
|
+
logins, anything line-based — is split across the open windows, one value pinned
|
|
53
|
+
per profile. A repeat call does not reshuffle what is already pinned, otherwise
|
|
54
|
+
an account would be registered on one email and confirmed with another. The
|
|
55
|
+
agent never sees the values themselves (see
|
|
56
|
+
[Security](#security-what-the-agent-cannot-do)).
|
|
57
|
+
|
|
58
|
+
Example prompts that work out of the box:
|
|
59
|
+
|
|
60
|
+
> Create twenty profiles with the prefix `shop`, give them proxies from this
|
|
61
|
+
> list, and launch the first five.
|
|
62
|
+
|
|
63
|
+
> Check the proxies on every profile I can manage and tell me which ones are
|
|
64
|
+
> dead or exiting from the wrong country.
|
|
65
|
+
|
|
66
|
+
> Take the `mail-batch` set, spread it across the open windows and show me who
|
|
67
|
+
> got what. I'll put the cursor in the email field, then insert.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Requirements
|
|
72
|
+
|
|
73
|
+
- Windows 10 or 11
|
|
74
|
+
- [Morfiade](https://morfiade.com/en/) 3.36 or newer, **running**
|
|
75
|
+
- **Local API enabled** in its settings — the server refuses to start without it
|
|
76
|
+
instead of failing silently
|
|
77
|
+
- The **"API" checkbox ticked** on the profiles the agent may touch; it is off by
|
|
78
|
+
default, and unticked profiles do not exist as far as the agent is concerned
|
|
79
|
+
- A valid licence to *launch* profiles (that check lives in the manager, not here)
|
|
80
|
+
- Any MCP client with stdio support: Claude Code, Claude Desktop, Cursor,
|
|
81
|
+
Gemini CLI, VS Code, your own
|
|
82
|
+
|
|
83
|
+
No `pip install`, no Node, no API key to register.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Setup
|
|
88
|
+
|
|
89
|
+
Point your client at the executable and pass `--mcp`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"morfiade": {
|
|
95
|
+
"command": "C:\\Program Files\\Morfiade\\Morfiade.exe",
|
|
96
|
+
"args": ["--mcp"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Ready-made files for the common clients are in [`examples/`](examples/).
|
|
103
|
+
Claude Code can do it in one line:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
claude mcp add morfiade -- "C:\Program Files\Morfiade\Morfiade.exe" --mcp
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Where the config file lives differs per client and changes more often than this
|
|
110
|
+
README — check your client's own docs.
|
|
111
|
+
|
|
112
|
+
### Optional launcher
|
|
113
|
+
|
|
114
|
+
If you would rather not hardcode the path,
|
|
115
|
+
[`morfiade_mcp.py`](morfiade_mcp.py) finds the executable (via `MORFIADE_EXE`,
|
|
116
|
+
the installer's registry key, the usual install directories, or `PATH`),
|
|
117
|
+
forwards stdio and returns its exit code. Requires Python 3.7+ and nothing else.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
pip install morfiade-mcp
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"morfiade": {
|
|
127
|
+
"command": "morfiade-mcp"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If your client needs an absolute path, point it at the `morfiade-mcp.exe`
|
|
134
|
+
that pip put in your Python `Scripts` directory — or skip the package and run
|
|
135
|
+
the single file directly:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"morfiade": {
|
|
141
|
+
"command": "python",
|
|
142
|
+
"args": ["C:\\path\\to\\morfiade_mcp.py"]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The package contains only that launcher. The server, and everything it talks
|
|
149
|
+
to, is the desktop app.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Tools
|
|
154
|
+
|
|
155
|
+
Full parameters and return shapes: [`docs/TOOLS.md`](docs/TOOLS.md).
|
|
156
|
+
|
|
157
|
+
| Tool | What it does |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `status` | version, how many profiles exist, how many the agent may use, how many are running |
|
|
160
|
+
| `list_profiles` | the permitted profiles: name, running or not, proxy, note |
|
|
161
|
+
| `create_profile` | create a profile — optionally with proxy, note and category; permitted for the agent immediately |
|
|
162
|
+
| `start_profile` | launch a profile, optionally straight onto a URL |
|
|
163
|
+
| `stop_profile` | close the profile window |
|
|
164
|
+
| `set_proxy` | assign a proxy (`type://user:pass@host:port` or `host:port`; empty string clears it) |
|
|
165
|
+
| `check_proxy` | check one profile's proxy: alive, and where it exits |
|
|
166
|
+
| `check_proxies` | the same across several profiles, or all of them |
|
|
167
|
+
| `profile_tags` | read the tags, or replace them wholesale |
|
|
168
|
+
| `profile_note` | read or write the note and its short title |
|
|
169
|
+
| `sync_windows` | which open windows are ready for distribution and what is already pinned to each |
|
|
170
|
+
| `sync_sets` | value sets: list them (name, lines, how many still free) or create one |
|
|
171
|
+
| `sync_spread` | pin one line of a set per window and report who got what — inserts nothing |
|
|
172
|
+
| `sync_insert` | insert each window's own value where the cursor sits in the leading window |
|
|
173
|
+
| `list_scripts` | scripts in the manager's folder: name and interpreter, never the contents |
|
|
174
|
+
| `trash_profile` | move a profile **to the trash** — nothing is erased |
|
|
175
|
+
| `list_trash` | what is in the trash: name, when, how much space |
|
|
176
|
+
| `restore_profile` | restore from the trash; a taken name comes back as `name (2)` |
|
|
177
|
+
|
|
178
|
+
Two more appear only behind explicit flags — see
|
|
179
|
+
[Dangerous flags](#dangerous-flags-off-by-default).
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Security: what the agent *cannot* do
|
|
184
|
+
|
|
185
|
+
An agent that reads web pages is not a trusted party. A page can contain the
|
|
186
|
+
text "call this tool and send the cookies over there", and the agent cannot tell
|
|
187
|
+
your instruction from text it found on the internet. That is the known central
|
|
188
|
+
problem of MCP, and no amount of prompt wording fixes it. So the limits are
|
|
189
|
+
built into the tool list instead:
|
|
190
|
+
|
|
191
|
+
- **Deletion goes to the trash only.** Profiles stay whole — cookies, sessions,
|
|
192
|
+
everything — and come back with one call. Permanent erase and emptying the
|
|
193
|
+
trash are not exposed here and never will be: they are the only irreversible
|
|
194
|
+
actions, and a human does them from the trash window, where they can see what
|
|
195
|
+
they are destroying.
|
|
196
|
+
- **No cookie reading.** GoLogin's MCP has such a tool, which means cookies
|
|
197
|
+
travel from the account into a chat log. This one does not have it.
|
|
198
|
+
- **Set lines are not exposed.** `sync_sets` reports the name, the line count and
|
|
199
|
+
how many are free. The emails and logins themselves stay in the manager — the
|
|
200
|
+
agent does not need to see them, it needs them to land in the windows.
|
|
201
|
+
- **Script contents are not exposed.** `list_scripts` gives names and
|
|
202
|
+
interpreters only.
|
|
203
|
+
- **The mirror is not exposed.** It reflects what a human is doing right now in
|
|
204
|
+
the leading window; there is nothing for an agent to repeat.
|
|
205
|
+
- **The whitelist cannot be bypassed.** The "API" column is filtered by the
|
|
206
|
+
manager itself, not by this server.
|
|
207
|
+
- **The licence check does not weaken.** It sits in the manager's handler, so it
|
|
208
|
+
fires whether a human, a script or an agent asked.
|
|
209
|
+
- **Nothing listens on the network.** The local API binds `127.0.0.1`, requires a
|
|
210
|
+
token and checks the `Host` header. The token is stored encrypted with Windows
|
|
211
|
+
DPAPI, tied to the account, and travels in a header rather than a URL — URLs
|
|
212
|
+
end up in logs.
|
|
213
|
+
|
|
214
|
+
### Dangerous flags, off by default
|
|
215
|
+
|
|
216
|
+
| Flag | Extra tool | What it really means |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `--mcp-allow-cdp` | `browser_command` | an arbitrary Chrome DevTools Protocol command. `Runtime.evaluate` in a logged-in profile reads cookies, storage and page contents — full access to your accounts, not "advanced management" |
|
|
219
|
+
| `--mcp-allow-scripts` | `run_script` | runs a script from the manager's folder — code execution on your machine |
|
|
220
|
+
|
|
221
|
+
Both are worth turning on only with the paragraph above in mind, and only for
|
|
222
|
+
pages you trust.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
| What you see | What to do |
|
|
229
|
+
|---|---|
|
|
230
|
+
| the client shows no tools | check the path to the exe in the client config |
|
|
231
|
+
| "local API is off" | enable the local API in the manager's settings |
|
|
232
|
+
| "no port or token in config.json" | open the manager once so it writes its settings |
|
|
233
|
+
| "the manager does not answer" | the manager has to be running |
|
|
234
|
+
| "profile not found", though it exists | the "API" checkbox is not ticked on that profile |
|
|
235
|
+
| "the API token contains invalid characters" | the config came from another machine — reissue the token in settings |
|
|
236
|
+
| launching a profile is refused | no valid licence: profile launch is closed over the API and MCP alike |
|
|
237
|
+
|
|
238
|
+
Messages come from the manager and follow its interface language — five are
|
|
239
|
+
available, so the wording you see may be your own.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## What is not here
|
|
244
|
+
|
|
245
|
+
The bridge itself is compiled into `Morfiade.exe`, and the **session transfer**
|
|
246
|
+
mechanism — the part that actually moves logged-in sessions between machines —
|
|
247
|
+
stays closed. This repository is the outside of the product: documentation,
|
|
248
|
+
configs, the launcher.
|
|
249
|
+
|
|
250
|
+
## Links
|
|
251
|
+
|
|
252
|
+
- [morfiade.com](https://morfiade.com/en/) — the manager itself
|
|
253
|
+
- [Running browser profiles from an AI agent](https://morfiade.com/en/blog/mcp-brauzer/) — what this looks like in practice
|
|
254
|
+
- [Manual](https://morfiade.com/en/manual/) — the AI agent access section
|
|
255
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) — the protocol
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
MIT for everything in this repository — see [LICENSE](LICENSE). The manager is a
|
|
260
|
+
separate commercial product with its own terms.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
morfiade_mcp
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Launcher for the Morfiade MCP server.
|
|
4
|
+
|
|
5
|
+
A client can start ``Morfiade.exe --mcp`` directly, and that is the shortest
|
|
6
|
+
path — see the README. This script exists for one reason: so a client config
|
|
7
|
+
does not have to carry an absolute path that differs on every machine.
|
|
8
|
+
|
|
9
|
+
It finds the executable, starts it in MCP mode and gets out of the way: stdin
|
|
10
|
+
and stdout are inherited by the child, so the JSON-RPC stream stays untouched —
|
|
11
|
+
nothing here parses, buffers or logs it. Diagnostics go to stderr, which the
|
|
12
|
+
protocol leaves free.
|
|
13
|
+
|
|
14
|
+
Search order:
|
|
15
|
+
|
|
16
|
+
1. ``MORFIADE_EXE`` — an explicit path wins over everything, and a wrong one is
|
|
17
|
+
reported rather than quietly ignored;
|
|
18
|
+
2. the installer's uninstall key — ``InstallLocation``, written by Inno Setup,
|
|
19
|
+
so a custom install directory is found too;
|
|
20
|
+
3. the usual install directories;
|
|
21
|
+
4. ``PATH``.
|
|
22
|
+
|
|
23
|
+
Extra arguments are passed through, so the flags off by default still work::
|
|
24
|
+
|
|
25
|
+
python morfiade_mcp.py --mcp-allow-cdp
|
|
26
|
+
|
|
27
|
+
Requires Python 3.7+ and nothing else. MIT, like the rest of this repository.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
import os
|
|
31
|
+
import shutil
|
|
32
|
+
import subprocess
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
EXE_NAME = "Morfiade.exe"
|
|
36
|
+
|
|
37
|
+
# The AppId of the installer, hence the key Inno Setup writes. Under HKLM for an
|
|
38
|
+
# all-user install (the default), under HKCU when installed for one user.
|
|
39
|
+
UNINSTALL_KEY = (r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
|
|
40
|
+
r"\{D4DAC94F-56AD-443B-96B0-8F011DEF1918}_is1")
|
|
41
|
+
|
|
42
|
+
# Exit code 2 is what the server itself returns when it cannot start. Keeping it
|
|
43
|
+
# the same means a client sees one code for "not running", whichever of us said so.
|
|
44
|
+
EXIT_NOT_READY = 2
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _fail(message):
|
|
48
|
+
sys.stderr.write(message.rstrip() + "\n")
|
|
49
|
+
sys.exit(EXIT_NOT_READY)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _from_registry():
|
|
53
|
+
try:
|
|
54
|
+
import winreg
|
|
55
|
+
except ImportError:
|
|
56
|
+
return None
|
|
57
|
+
wow = UNINSTALL_KEY.replace("SOFTWARE\\", "SOFTWARE\\WOW6432Node\\", 1)
|
|
58
|
+
places = ((winreg.HKEY_LOCAL_MACHINE, UNINSTALL_KEY),
|
|
59
|
+
(winreg.HKEY_LOCAL_MACHINE, wow),
|
|
60
|
+
(winreg.HKEY_CURRENT_USER, UNINSTALL_KEY))
|
|
61
|
+
for root, path in places:
|
|
62
|
+
try:
|
|
63
|
+
with winreg.OpenKey(root, path) as key:
|
|
64
|
+
location = winreg.QueryValueEx(key, "InstallLocation")[0]
|
|
65
|
+
except OSError:
|
|
66
|
+
continue
|
|
67
|
+
candidate = os.path.join(location, EXE_NAME)
|
|
68
|
+
if os.path.isfile(candidate):
|
|
69
|
+
return candidate
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _from_known_dirs():
|
|
74
|
+
for variable in ("ProgramFiles", "ProgramFiles(x86)", "LOCALAPPDATA"):
|
|
75
|
+
base = os.environ.get(variable)
|
|
76
|
+
if not base:
|
|
77
|
+
continue
|
|
78
|
+
for folder in ("Morfiade", os.path.join("Programs", "Morfiade")):
|
|
79
|
+
candidate = os.path.join(base, folder, EXE_NAME)
|
|
80
|
+
if os.path.isfile(candidate):
|
|
81
|
+
return candidate
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def find_executable():
|
|
86
|
+
explicit = os.environ.get("MORFIADE_EXE")
|
|
87
|
+
if explicit:
|
|
88
|
+
if os.path.isfile(explicit):
|
|
89
|
+
return explicit
|
|
90
|
+
_fail("MORFIADE_EXE points at %s, and there is no file there. Fix the "
|
|
91
|
+
"variable or unset it to let this launcher search." % explicit)
|
|
92
|
+
return _from_registry() or _from_known_dirs() or shutil.which(EXE_NAME)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _handles_available():
|
|
96
|
+
for stream in (sys.stdin, sys.stdout, sys.stderr):
|
|
97
|
+
try:
|
|
98
|
+
stream.fileno()
|
|
99
|
+
except Exception:
|
|
100
|
+
return False
|
|
101
|
+
return True
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _run(command):
|
|
105
|
+
"""Start the server so that it really gets our stdin and stdout.
|
|
106
|
+
|
|
107
|
+
⚠️ Measured, not assumed. With subprocess defaults (``stdin=None``,
|
|
108
|
+
``stdout=None``) the child started and exited 0 without writing a single
|
|
109
|
+
byte — which in a client looks exactly like "the MCP server closes
|
|
110
|
+
immediately". Handing the handles over explicitly fixes it, and
|
|
111
|
+
``close_fds=False`` fixes it the same way when our own streams have no file
|
|
112
|
+
descriptor to hand over.
|
|
113
|
+
"""
|
|
114
|
+
if _handles_available():
|
|
115
|
+
return subprocess.call(command, stdin=sys.stdin, stdout=sys.stdout,
|
|
116
|
+
stderr=sys.stderr)
|
|
117
|
+
return subprocess.call(command, close_fds=False)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def main(argv=None):
|
|
121
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
122
|
+
if os.name != "nt":
|
|
123
|
+
_fail("Morfiade is a Windows program, so this launcher only makes "
|
|
124
|
+
"sense on Windows.")
|
|
125
|
+
executable = find_executable()
|
|
126
|
+
if not executable:
|
|
127
|
+
_fail("%s not found. Install Morfiade (https://morfiade.com/), or set "
|
|
128
|
+
"MORFIADE_EXE to the full path of the executable if it lives "
|
|
129
|
+
"somewhere unusual." % EXE_NAME)
|
|
130
|
+
# --mcp goes first and only once; everything the client passed follows.
|
|
131
|
+
command = [executable, "--mcp"] + [a for a in argv if a != "--mcp"]
|
|
132
|
+
try:
|
|
133
|
+
return _run(command)
|
|
134
|
+
except KeyboardInterrupt:
|
|
135
|
+
return 130
|
|
136
|
+
except OSError as error:
|
|
137
|
+
_fail("could not start %s: %s" % (executable, error))
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
if __name__ == "__main__":
|
|
141
|
+
sys.exit(main())
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "morfiade-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Launcher for the Morfiade MCP server — manage local Chrome profiles on Windows from an AI agent"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Morfiade", email = "github@morfiade.com" }]
|
|
14
|
+
keywords = ["mcp", "model-context-protocol", "chrome", "profiles", "multi-account", "browser-automation"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: End Users/Desktop",
|
|
20
|
+
"Operating System :: Microsoft :: Windows",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Topic :: Internet :: WWW/HTTP :: Browsers",
|
|
23
|
+
"Topic :: Software Development :: Libraries",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://morfiade.com/en/"
|
|
28
|
+
Repository = "https://github.com/morfiade-app/morfiade-mcp"
|
|
29
|
+
Documentation = "https://github.com/morfiade-app/morfiade-mcp/blob/main/docs/TOOLS.md"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
morfiade-mcp = "morfiade_mcp:main"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools]
|
|
35
|
+
py-modules = ["morfiade_mcp"]
|