fagun 0.2.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.
- fagun-0.2.0/.github/workflows/ci.yml +38 -0
- fagun-0.2.0/.github/workflows/publish.yml +40 -0
- fagun-0.2.0/.gitignore +7 -0
- fagun-0.2.0/LICENSE +21 -0
- fagun-0.2.0/PKG-INFO +162 -0
- fagun-0.2.0/README.md +148 -0
- fagun-0.2.0/install.md +87 -0
- fagun-0.2.0/pyproject.toml +27 -0
- fagun-0.2.0/skills/fagun/SKILL.md +151 -0
- fagun-0.2.0/src/fagun/__init__.py +3 -0
- fagun-0.2.0/src/fagun/__main__.py +29 -0
- fagun-0.2.0/src/fagun/browser.py +143 -0
- fagun-0.2.0/src/fagun/install.py +81 -0
- fagun-0.2.0/src/fagun/qa.py +285 -0
- fagun-0.2.0/src/fagun/report.py +55 -0
- fagun-0.2.0/src/fagun/server.py +238 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
smoke:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.12"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- name: Install
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install --upgrade pip
|
|
23
|
+
pip install -e .
|
|
24
|
+
- name: Import + tool registration smoke test
|
|
25
|
+
run: |
|
|
26
|
+
python -c "
|
|
27
|
+
import asyncio
|
|
28
|
+
from fagun.server import mcp
|
|
29
|
+
async def main():
|
|
30
|
+
tools = await mcp.list_tools()
|
|
31
|
+
names = {t.name for t in tools}
|
|
32
|
+
assert 'deep_test' in names and 'test_forms' in names, names
|
|
33
|
+
assert len(tools) >= 19, len(tools)
|
|
34
|
+
prompts = await mcp.list_prompts()
|
|
35
|
+
assert any(p.name == 'fagun' for p in prompts)
|
|
36
|
+
print(f'OK: {len(tools)} tools, {len(prompts)} prompts')
|
|
37
|
+
asyncio.run(main())
|
|
38
|
+
"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Ships to PyPI whenever you push a version tag, e.g.:
|
|
4
|
+
# git tag v0.2.0 && git push origin v0.2.0
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
workflow_dispatch: {}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- name: Build sdist + wheel
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade build twine
|
|
21
|
+
python -m build
|
|
22
|
+
twine check dist/*
|
|
23
|
+
- uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment: pypi
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write # OIDC — no API token stored in the repo
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/download-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
- name: Publish to PyPI
|
|
40
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
fagun-0.2.0/.gitignore
ADDED
fagun-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mejbaur Bahar Fagun
|
|
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.
|
fagun-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fagun
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Fagun — one MCP server that lets any AI tool (Claude, Cursor, Codex, Antigravity, Windsurf) drive a browser, hunt bugs, and run a full QA sweep.
|
|
5
|
+
Project-URL: Homepage, https://github.com/fagun-dev/fagun
|
|
6
|
+
Author-email: Mejbaur Bahar Fagun <mejbaur@markopolo.ai>
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: ai,browser,claude,codex,cursor,mcp,playwright,qa,testing
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Requires-Dist: mcp>=1.2.0
|
|
12
|
+
Requires-Dist: playwright>=1.44.0
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# 🦊 Fagun
|
|
16
|
+
|
|
17
|
+
**One MCP server. Every AI tool. Type `fagun` and it drives a browser + runs full QA.**
|
|
18
|
+
|
|
19
|
+
Fagun is an [MCP](https://modelcontextprotocol.io) server that lets any AI coding
|
|
20
|
+
tool — **Claude Code / Desktop, Cursor, Codex, Antigravity, Windsurf, Cline, VS Code** —
|
|
21
|
+
control a real browser, debug it (console, network, DOM, screenshots, JS eval), and
|
|
22
|
+
run an automated quality sweep (broken requests, console errors, accessibility,
|
|
23
|
+
performance, SEO) with a Markdown report.
|
|
24
|
+
|
|
25
|
+
You set it up once. Then inside any of those tools you just say **`fagun`** (or `/fagun`) and it starts.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## One-line setup (paste into your AI tool)
|
|
30
|
+
|
|
31
|
+
Tell your AI agent (Claude, Cursor, Codex, Antigravity, …) exactly this:
|
|
32
|
+
|
|
33
|
+
> Install or upgrade **fagun** to the latest stable version with `uv` using Python
|
|
34
|
+
> 3.12, register the skill from `fagun skill`, and connect it to my browser. Follow
|
|
35
|
+
> https://github.com/mejbaurbahar/fagun/blob/main/install.md if setup or connection fails.
|
|
36
|
+
|
|
37
|
+
The agent follows [`install.md`](install.md) and wires everything up. Then just type
|
|
38
|
+
**`/fagun`** and describe what to test.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Setup (once, ~2 min)
|
|
43
|
+
|
|
44
|
+
**1. Install the runner + browser engine**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install uv
|
|
48
|
+
uvx --from fagun python -m playwright install chromium
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`uvx` runs Fagun without a permanent install and always uses the latest version.
|
|
52
|
+
|
|
53
|
+
**2. Add Fagun to your AI tool**
|
|
54
|
+
|
|
55
|
+
Print ready-to-paste config for every tool:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uvx fagun install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or let Fagun write the file for you:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uvx fagun install cursor # writes ~/.cursor/mcp.json
|
|
65
|
+
uvx fagun install claude # writes Claude Desktop config
|
|
66
|
+
uvx fagun install vscode # writes .vscode/mcp.json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Manual config is identical everywhere — command `uvx`, args `["fagun"]`:
|
|
70
|
+
|
|
71
|
+
| Tool | Where |
|
|
72
|
+
|------|-------|
|
|
73
|
+
| **Claude Code** | `claude mcp add fagun -- uvx fagun` |
|
|
74
|
+
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
75
|
+
| **Cursor** | `~/.cursor/mcp.json` |
|
|
76
|
+
| **Windsurf / Cline / Antigravity** | their MCP settings (same JSON as Cursor) |
|
|
77
|
+
| **VS Code (Copilot)** | `.vscode/mcp.json` |
|
|
78
|
+
| **Codex CLI** | `~/.codex/config.toml` |
|
|
79
|
+
|
|
80
|
+
```jsonc
|
|
81
|
+
// Claude Desktop / Cursor / Windsurf / Cline / Antigravity
|
|
82
|
+
{ "mcpServers": { "fagun": { "command": "uvx", "args": ["fagun"] } } }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```toml
|
|
86
|
+
# Codex ~/.codex/config.toml
|
|
87
|
+
[mcp_servers.fagun]
|
|
88
|
+
command = "uvx"
|
|
89
|
+
args = ["fagun"]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**3. Restart the tool. Say `fagun`.**
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Use it
|
|
97
|
+
|
|
98
|
+
Inside any tool, just talk:
|
|
99
|
+
|
|
100
|
+
- *"fagun"* → shows the menu and starts up
|
|
101
|
+
- *"go to example.com and screenshot it"*
|
|
102
|
+
- *"run QA on https://example.com"*
|
|
103
|
+
- *"full QA sweep of https://example.com, write the report to ./qa.md"*
|
|
104
|
+
- *"show me the console errors"* · *"any failed network requests?"*
|
|
105
|
+
- *"click Sign in, type me@x.com into email, press Enter"*
|
|
106
|
+
|
|
107
|
+
- *"deep test https://example.com and write the report to ./report.md"* — the full sweep
|
|
108
|
+
|
|
109
|
+
## The `/fagun` skill — autonomous bug hunter
|
|
110
|
+
|
|
111
|
+
`skills/fagun/SKILL.md` is a full QA methodology the AI follows: it hunts **real,
|
|
112
|
+
reproducible** bugs across 10 scenario classes — functional, JS/runtime errors,
|
|
113
|
+
network/API, form validation, auth/session/authorization, accessibility,
|
|
114
|
+
performance, visual/responsive, security posture, and edge cases — with an
|
|
115
|
+
evidence-or-it-didn't-happen rule and impact-based severity. Register it (see
|
|
116
|
+
`install.md` Step 5) to get the `/fagun` slash command.
|
|
117
|
+
|
|
118
|
+
## What it exposes (MCP tools)
|
|
119
|
+
|
|
120
|
+
`fagun_start` · `open_browser` · `navigate` · `click` · `fill` · `press_key` ·
|
|
121
|
+
`screenshot` · `evaluate_js` · `get_console` · `get_network` · `crawl` · `run_qa` ·
|
|
122
|
+
`check_links` · `test_forms` · `security_headers` · `deep_test` · `full_qa_sweep` ·
|
|
123
|
+
`write_report` · `close_browser`
|
|
124
|
+
|
|
125
|
+
Plus a **`fagun` prompt** — appears as a slash command in tools that surface MCP prompts.
|
|
126
|
+
|
|
127
|
+
## Options (env vars)
|
|
128
|
+
|
|
129
|
+
| Var | Default | Meaning |
|
|
130
|
+
|-----|---------|---------|
|
|
131
|
+
| `FAGUN_HEADLESS` | `1` | `0` shows the browser window |
|
|
132
|
+
| `FAGUN_BROWSER` | `chromium` | `chromium` \| `firefox` \| `webkit` |
|
|
133
|
+
| `FAGUN_CDP_URL` | — | Attach to a running Chrome, e.g. `http://127.0.0.1:9222` |
|
|
134
|
+
|
|
135
|
+
## Local dev
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
git clone <repo> && cd fagun
|
|
139
|
+
pip install -e .
|
|
140
|
+
python -m playwright install chromium
|
|
141
|
+
python -m fagun # starts the MCP server on stdio
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Releasing to PyPI (maintainer)
|
|
145
|
+
|
|
146
|
+
Auto-publish is wired via GitHub Actions using **PyPI Trusted Publishing** (OIDC —
|
|
147
|
+
no API token stored). One-time setup on [pypi.org](https://pypi.org/manage/account/publishing/):
|
|
148
|
+
|
|
149
|
+
- Project: `fagun` · Owner: `mejbaurbahar` · Repo: `fagun`
|
|
150
|
+
- Workflow: `publish.yml` · Environment: `pypi`
|
|
151
|
+
|
|
152
|
+
Then every release is just a tag:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# bump version in pyproject.toml + src/fagun/__init__.py first
|
|
156
|
+
git tag v0.2.0 && git push origin v0.2.0
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The `Publish to PyPI` workflow builds, checks, and uploads automatically. Build
|
|
160
|
+
locally to verify anytime: `python -m build && twine check dist/*`.
|
|
161
|
+
|
|
162
|
+
MIT © Mejbaur Bahar Fagun
|
fagun-0.2.0/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# 🦊 Fagun
|
|
2
|
+
|
|
3
|
+
**One MCP server. Every AI tool. Type `fagun` and it drives a browser + runs full QA.**
|
|
4
|
+
|
|
5
|
+
Fagun is an [MCP](https://modelcontextprotocol.io) server that lets any AI coding
|
|
6
|
+
tool — **Claude Code / Desktop, Cursor, Codex, Antigravity, Windsurf, Cline, VS Code** —
|
|
7
|
+
control a real browser, debug it (console, network, DOM, screenshots, JS eval), and
|
|
8
|
+
run an automated quality sweep (broken requests, console errors, accessibility,
|
|
9
|
+
performance, SEO) with a Markdown report.
|
|
10
|
+
|
|
11
|
+
You set it up once. Then inside any of those tools you just say **`fagun`** (or `/fagun`) and it starts.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## One-line setup (paste into your AI tool)
|
|
16
|
+
|
|
17
|
+
Tell your AI agent (Claude, Cursor, Codex, Antigravity, …) exactly this:
|
|
18
|
+
|
|
19
|
+
> Install or upgrade **fagun** to the latest stable version with `uv` using Python
|
|
20
|
+
> 3.12, register the skill from `fagun skill`, and connect it to my browser. Follow
|
|
21
|
+
> https://github.com/mejbaurbahar/fagun/blob/main/install.md if setup or connection fails.
|
|
22
|
+
|
|
23
|
+
The agent follows [`install.md`](install.md) and wires everything up. Then just type
|
|
24
|
+
**`/fagun`** and describe what to test.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Setup (once, ~2 min)
|
|
29
|
+
|
|
30
|
+
**1. Install the runner + browser engine**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install uv
|
|
34
|
+
uvx --from fagun python -m playwright install chromium
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`uvx` runs Fagun without a permanent install and always uses the latest version.
|
|
38
|
+
|
|
39
|
+
**2. Add Fagun to your AI tool**
|
|
40
|
+
|
|
41
|
+
Print ready-to-paste config for every tool:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uvx fagun install
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or let Fagun write the file for you:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
uvx fagun install cursor # writes ~/.cursor/mcp.json
|
|
51
|
+
uvx fagun install claude # writes Claude Desktop config
|
|
52
|
+
uvx fagun install vscode # writes .vscode/mcp.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Manual config is identical everywhere — command `uvx`, args `["fagun"]`:
|
|
56
|
+
|
|
57
|
+
| Tool | Where |
|
|
58
|
+
|------|-------|
|
|
59
|
+
| **Claude Code** | `claude mcp add fagun -- uvx fagun` |
|
|
60
|
+
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
61
|
+
| **Cursor** | `~/.cursor/mcp.json` |
|
|
62
|
+
| **Windsurf / Cline / Antigravity** | their MCP settings (same JSON as Cursor) |
|
|
63
|
+
| **VS Code (Copilot)** | `.vscode/mcp.json` |
|
|
64
|
+
| **Codex CLI** | `~/.codex/config.toml` |
|
|
65
|
+
|
|
66
|
+
```jsonc
|
|
67
|
+
// Claude Desktop / Cursor / Windsurf / Cline / Antigravity
|
|
68
|
+
{ "mcpServers": { "fagun": { "command": "uvx", "args": ["fagun"] } } }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```toml
|
|
72
|
+
# Codex ~/.codex/config.toml
|
|
73
|
+
[mcp_servers.fagun]
|
|
74
|
+
command = "uvx"
|
|
75
|
+
args = ["fagun"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**3. Restart the tool. Say `fagun`.**
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Use it
|
|
83
|
+
|
|
84
|
+
Inside any tool, just talk:
|
|
85
|
+
|
|
86
|
+
- *"fagun"* → shows the menu and starts up
|
|
87
|
+
- *"go to example.com and screenshot it"*
|
|
88
|
+
- *"run QA on https://example.com"*
|
|
89
|
+
- *"full QA sweep of https://example.com, write the report to ./qa.md"*
|
|
90
|
+
- *"show me the console errors"* · *"any failed network requests?"*
|
|
91
|
+
- *"click Sign in, type me@x.com into email, press Enter"*
|
|
92
|
+
|
|
93
|
+
- *"deep test https://example.com and write the report to ./report.md"* — the full sweep
|
|
94
|
+
|
|
95
|
+
## The `/fagun` skill — autonomous bug hunter
|
|
96
|
+
|
|
97
|
+
`skills/fagun/SKILL.md` is a full QA methodology the AI follows: it hunts **real,
|
|
98
|
+
reproducible** bugs across 10 scenario classes — functional, JS/runtime errors,
|
|
99
|
+
network/API, form validation, auth/session/authorization, accessibility,
|
|
100
|
+
performance, visual/responsive, security posture, and edge cases — with an
|
|
101
|
+
evidence-or-it-didn't-happen rule and impact-based severity. Register it (see
|
|
102
|
+
`install.md` Step 5) to get the `/fagun` slash command.
|
|
103
|
+
|
|
104
|
+
## What it exposes (MCP tools)
|
|
105
|
+
|
|
106
|
+
`fagun_start` · `open_browser` · `navigate` · `click` · `fill` · `press_key` ·
|
|
107
|
+
`screenshot` · `evaluate_js` · `get_console` · `get_network` · `crawl` · `run_qa` ·
|
|
108
|
+
`check_links` · `test_forms` · `security_headers` · `deep_test` · `full_qa_sweep` ·
|
|
109
|
+
`write_report` · `close_browser`
|
|
110
|
+
|
|
111
|
+
Plus a **`fagun` prompt** — appears as a slash command in tools that surface MCP prompts.
|
|
112
|
+
|
|
113
|
+
## Options (env vars)
|
|
114
|
+
|
|
115
|
+
| Var | Default | Meaning |
|
|
116
|
+
|-----|---------|---------|
|
|
117
|
+
| `FAGUN_HEADLESS` | `1` | `0` shows the browser window |
|
|
118
|
+
| `FAGUN_BROWSER` | `chromium` | `chromium` \| `firefox` \| `webkit` |
|
|
119
|
+
| `FAGUN_CDP_URL` | — | Attach to a running Chrome, e.g. `http://127.0.0.1:9222` |
|
|
120
|
+
|
|
121
|
+
## Local dev
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone <repo> && cd fagun
|
|
125
|
+
pip install -e .
|
|
126
|
+
python -m playwright install chromium
|
|
127
|
+
python -m fagun # starts the MCP server on stdio
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Releasing to PyPI (maintainer)
|
|
131
|
+
|
|
132
|
+
Auto-publish is wired via GitHub Actions using **PyPI Trusted Publishing** (OIDC —
|
|
133
|
+
no API token stored). One-time setup on [pypi.org](https://pypi.org/manage/account/publishing/):
|
|
134
|
+
|
|
135
|
+
- Project: `fagun` · Owner: `mejbaurbahar` · Repo: `fagun`
|
|
136
|
+
- Workflow: `publish.yml` · Environment: `pypi`
|
|
137
|
+
|
|
138
|
+
Then every release is just a tag:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# bump version in pyproject.toml + src/fagun/__init__.py first
|
|
142
|
+
git tag v0.2.0 && git push origin v0.2.0
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The `Publish to PyPI` workflow builds, checks, and uploads automatically. Build
|
|
146
|
+
locally to verify anytime: `python -m build && twine check dist/*`.
|
|
147
|
+
|
|
148
|
+
MIT © Mejbaur Bahar Fagun
|
fagun-0.2.0/install.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Fagun — install & connect (for the AI agent to follow)
|
|
2
|
+
|
|
3
|
+
You are an AI coding tool (Claude, Cursor, Codex, Antigravity, Windsurf, Cline, …).
|
|
4
|
+
The user asked you to install and connect **Fagun**. Do the steps below in order.
|
|
5
|
+
If any step fails, read the "Troubleshooting" section and retry.
|
|
6
|
+
|
|
7
|
+
## The command users give you
|
|
8
|
+
|
|
9
|
+
> Install or upgrade **fagun** to the latest stable version with `uv` using Python
|
|
10
|
+
> 3.12, register the skill from `fagun skill`, and connect it to my browser. Follow
|
|
11
|
+
> https://github.com/mejbaurbahar/fagun/blob/main/install.md if setup or connection
|
|
12
|
+
> fails.
|
|
13
|
+
|
|
14
|
+
## Step 1 — ensure `uv` exists
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
uv --version || curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Step 2 — install / upgrade Fagun with Python 3.12
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv tool install --python 3.12 --upgrade fagun
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If `fagun` is not on PyPI yet, install from GitHub:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uv tool install --python 3.12 --upgrade "git+https://github.com/mejbaurbahar/fagun"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Step 3 — install the browser engine (once)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv tool run --from fagun python -m playwright install chromium
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Step 4 — register Fagun as an MCP server (pick the user's tool)
|
|
39
|
+
|
|
40
|
+
The config is identical everywhere: **command `uvx`, args `["fagun"]`**.
|
|
41
|
+
|
|
42
|
+
- **Claude Code:** `claude mcp add fagun -- uvx fagun`
|
|
43
|
+
- **Cursor / Windsurf / Cline / Antigravity** — `~/.cursor/mcp.json` (or equivalent):
|
|
44
|
+
```json
|
|
45
|
+
{ "mcpServers": { "fagun": { "command": "uvx", "args": ["fagun"] } } }
|
|
46
|
+
```
|
|
47
|
+
- **VS Code (Copilot MCP)** — `.vscode/mcp.json`:
|
|
48
|
+
```json
|
|
49
|
+
{ "servers": { "fagun": { "type": "stdio", "command": "uvx", "args": ["fagun"] } } }
|
|
50
|
+
```
|
|
51
|
+
- **Codex CLI** — `~/.codex/config.toml`:
|
|
52
|
+
```toml
|
|
53
|
+
[mcp_servers.fagun]
|
|
54
|
+
command = "uvx"
|
|
55
|
+
args = ["fagun"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Shortcut — let Fagun write the file: `uvx fagun install cursor` (or `claude`, `vscode`).
|
|
59
|
+
|
|
60
|
+
## Step 5 — register the skill
|
|
61
|
+
|
|
62
|
+
Copy `skills/fagun/SKILL.md` from this repo into the tool's skills directory
|
|
63
|
+
(e.g. `~/.claude/skills/fagun/SKILL.md`). This makes `/fagun` available as a
|
|
64
|
+
slash command. For tools without skills, the `fagun` MCP prompt is the entry point.
|
|
65
|
+
|
|
66
|
+
## Step 6 — connect to the browser & verify
|
|
67
|
+
|
|
68
|
+
Restart the AI tool, then call the `fagun_start` tool (or say `fagun`). Fagun
|
|
69
|
+
launches its own Chromium. To attach to an already-running Chrome instead, set:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export FAGUN_CDP_URL=http://127.0.0.1:9222 # Chrome started with --remote-debugging-port=9222
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Verify: ask *"go to https://example.com and screenshot it"*.
|
|
76
|
+
|
|
77
|
+
## Troubleshooting
|
|
78
|
+
|
|
79
|
+
- **`uv` not found** → re-run Step 1, then `source ~/.bashrc` / open a new shell.
|
|
80
|
+
- **`playwright` browser missing / launch error** → re-run Step 3. On Linux add deps:
|
|
81
|
+
`uv tool run --from fagun python -m playwright install-deps chromium`.
|
|
82
|
+
- **Tool doesn't see `fagun`** → fully restart the AI tool after editing MCP config;
|
|
83
|
+
confirm the JSON is valid (no trailing commas).
|
|
84
|
+
- **Want to see the browser** → set `FAGUN_HEADLESS=0`.
|
|
85
|
+
- **Corporate proxy / SSL** → set `HTTPS_PROXY`; for CDP connect use `FAGUN_CDP_URL`.
|
|
86
|
+
- **Firefox/WebKit instead of Chrome** → `FAGUN_BROWSER=firefox` (run the matching
|
|
87
|
+
`playwright install firefox` first).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "fagun"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Fagun — one MCP server that lets any AI tool (Claude, Cursor, Codex, Antigravity, Windsurf) drive a browser, hunt bugs, and run a full QA sweep."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Mejbaur Bahar Fagun", email = "mejbaur@markopolo.ai" }]
|
|
13
|
+
keywords = ["mcp", "browser", "qa", "testing", "playwright", "ai", "claude", "cursor", "codex"]
|
|
14
|
+
|
|
15
|
+
dependencies = [
|
|
16
|
+
"mcp>=1.2.0",
|
|
17
|
+
"playwright>=1.44.0",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
fagun = "fagun.__main__:main"
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/fagun-dev/fagun"
|
|
25
|
+
|
|
26
|
+
[tool.hatch.build.targets.wheel]
|
|
27
|
+
packages = ["src/fagun"]
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fagun
|
|
3
|
+
description: >
|
|
4
|
+
Fagun — autonomous browser QA + real-bug hunting. Use whenever the user wants to
|
|
5
|
+
test a website/web app for REAL, reproducible bugs, errors, or issues: functional
|
|
6
|
+
breakage, console/JS errors, failed network requests, broken links, form
|
|
7
|
+
validation gaps, auth/session flaws, accessibility violations, performance
|
|
8
|
+
regressions, visual/layout breakage, security-header/misconfig issues, and edge
|
|
9
|
+
cases. Drives the `fagun` MCP browser tools. Triggers: "/fagun", "test this site",
|
|
10
|
+
"find bugs on <url>", "QA <url>", "deep test", "audit <url>", "is <url> broken".
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Fagun — Autonomous Bug-Hunting QA Agent
|
|
14
|
+
|
|
15
|
+
You drive a real browser through the `fagun` MCP server and hunt for **real,
|
|
16
|
+
reproducible** defects. Never guess or hallucinate a bug — every finding must be
|
|
17
|
+
observed via a tool result (a console error, a status code, a DOM fact, a timing
|
|
18
|
+
number). If you can't reproduce it, don't report it.
|
|
19
|
+
|
|
20
|
+
## Golden rules
|
|
21
|
+
1. **Evidence or it didn't happen.** Each finding = what you did + what you saw
|
|
22
|
+
(tool output) + why it's wrong + how to reproduce.
|
|
23
|
+
2. **Severity is impact-based:** 🔴 high = broken/insecure/data-loss · 🟠 medium =
|
|
24
|
+
degraded/partial · 🟡 low = polish/best-practice. No inflation.
|
|
25
|
+
3. **Non-destructive by default.** Don't submit real data, delete, pay, or spam.
|
|
26
|
+
Ask before any state-changing action on a production site.
|
|
27
|
+
4. **Scope discipline.** Stay on the target host unless the user widens scope.
|
|
28
|
+
5. **Deduplicate.** Same root cause across pages = one finding with a page list.
|
|
29
|
+
|
|
30
|
+
## Workflow
|
|
31
|
+
|
|
32
|
+
### 0. Scope
|
|
33
|
+
Confirm the target URL(s) and whether it's staging or production. Ask what matters
|
|
34
|
+
most (functional? security? a11y? perf?) if unclear — otherwise run the full sweep.
|
|
35
|
+
|
|
36
|
+
### 1. Recon
|
|
37
|
+
- `open_browser` → `navigate(url)` → `screenshot`.
|
|
38
|
+
- `crawl(url, max_pages)` to map the surface. Note page types (auth, forms,
|
|
39
|
+
listings, detail, checkout, dashboard).
|
|
40
|
+
|
|
41
|
+
### 2. Broad sweep (fast, high yield)
|
|
42
|
+
Run and collect:
|
|
43
|
+
- `deep_test(url)` — crawl + per-page QA + forms + security headers in one pass.
|
|
44
|
+
This is your baseline. Read every finding.
|
|
45
|
+
- `check_links(url)` — broken links / dead resources.
|
|
46
|
+
|
|
47
|
+
### 3. Targeted hunting (per scenario — see taxonomy below)
|
|
48
|
+
For each page/flow, pick the relevant scenarios, drive them with
|
|
49
|
+
`click` / `fill` / `press_key` / `evaluate_js`, and after EACH interaction check
|
|
50
|
+
`get_console(only_errors=True)` and `get_network(only_problems=True)`. A clean UI
|
|
51
|
+
that throws console errors or 500s under the hood is a real bug.
|
|
52
|
+
|
|
53
|
+
### 4. Reproduce & confirm
|
|
54
|
+
Re-run the exact steps a second time. A finding that doesn't reproduce is dropped
|
|
55
|
+
or downgraded to "flaky — needs investigation".
|
|
56
|
+
|
|
57
|
+
### 5. Report
|
|
58
|
+
Call `write_report` / `deep_test(report_path=...)` for the Markdown artifact, then
|
|
59
|
+
summarize to the user grouped by severity, each with repro steps.
|
|
60
|
+
|
|
61
|
+
## Test taxonomy — the scenarios to cover
|
|
62
|
+
|
|
63
|
+
### A. Functional / behavioral
|
|
64
|
+
- Core user journeys complete end to end (search → result → detail; add → cart →
|
|
65
|
+
checkout up to the pay step; login → dashboard → logout).
|
|
66
|
+
- Buttons/links do what their label says. Nav goes where it claims.
|
|
67
|
+
- State persists correctly across navigation and reload.
|
|
68
|
+
- Empty states, zero-results, and "no data" render without errors.
|
|
69
|
+
|
|
70
|
+
### B. JavaScript / runtime errors
|
|
71
|
+
- `get_console(only_errors=True)` after load AND after every interaction.
|
|
72
|
+
- Unhandled promise rejections, `undefined is not a function`, null derefs.
|
|
73
|
+
- Errors that only fire on interaction (click handlers, lazy chunks failing to load).
|
|
74
|
+
|
|
75
|
+
### C. Network / API
|
|
76
|
+
- `get_network(only_problems=True)`: 4xx/5xx, failed/timed-out, CORS errors.
|
|
77
|
+
- Requests firing on wrong events, duplicate/N+1 calls, missing loading states.
|
|
78
|
+
- Mixed content (https page loading http resources).
|
|
79
|
+
|
|
80
|
+
### D. Forms & input validation (use `test_forms`, then drive manually)
|
|
81
|
+
- Required fields not enforced; submit with empties.
|
|
82
|
+
- Type validation: bad email, negative/huge numbers, wrong date formats.
|
|
83
|
+
- Boundary/edge: max length, unicode/emoji, whitespace-only, leading zeros.
|
|
84
|
+
- Injection-shaped INPUT for robustness (NOT attacking): `'"><b>x`, `{{7*7}}`,
|
|
85
|
+
`../../`, very long strings — the app must sanitize/escape, never reflect raw
|
|
86
|
+
or 500. Observe the response; report reflection/errors, don't exploit further.
|
|
87
|
+
- Double-submit / rapid re-submit; disabled-button-then-click races.
|
|
88
|
+
- Client vs server validation mismatch.
|
|
89
|
+
|
|
90
|
+
### E. Authentication / session / authorization
|
|
91
|
+
- Login with wrong password → clear error, no crash, no user enumeration.
|
|
92
|
+
- Session persists on reload; logout truly clears session.
|
|
93
|
+
- Access a protected URL while logged out → redirect, not a leak.
|
|
94
|
+
- IDOR smell: change an id in the URL/param — do you see someone else's data?
|
|
95
|
+
(Report the observation; do not enumerate at scale.)
|
|
96
|
+
- Password field over GET / over http → high severity (also caught by `test_forms`).
|
|
97
|
+
|
|
98
|
+
### F. Accessibility (WCAG signals)
|
|
99
|
+
- Images without `alt`, form fields without labels (`run_qa` / `test_forms`).
|
|
100
|
+
- Keyboard: `press_key("Tab")` through the page — focus visible? traps? skip link?
|
|
101
|
+
- Color-only meaning, missing landmarks, empty links/buttons.
|
|
102
|
+
- `evaluate_js` to check heading order and `aria-*` correctness.
|
|
103
|
+
|
|
104
|
+
### G. Performance
|
|
105
|
+
- `run_qa` load time; flag > 4s.
|
|
106
|
+
- Oversized images, render-blocking resources, layout thrash.
|
|
107
|
+
- Long tasks / jank after interaction. Report worst offenders with numbers.
|
|
108
|
+
|
|
109
|
+
### H. Visual / responsive / layout
|
|
110
|
+
- `screenshot` at desktop; if `resize`-capable, check mobile widths.
|
|
111
|
+
- Overflow, overlap, cut-off text, broken images, invisible-on-hover.
|
|
112
|
+
- Dark mode / zoom 200% breakage.
|
|
113
|
+
|
|
114
|
+
### I. Security posture (surface-level, non-exploit)
|
|
115
|
+
- `security_headers`: missing CSP/HSTS/X-Frame-Options/nosniff, version leaks.
|
|
116
|
+
- Secrets in JS/HTML: `evaluate_js` grep page source for `api_key`, `token`,
|
|
117
|
+
`AKIA`, private URLs. Report presence, don't use them.
|
|
118
|
+
- Verbose error pages / stack traces exposed → high.
|
|
119
|
+
- Autocomplete on sensitive fields, forms posting cross-origin.
|
|
120
|
+
|
|
121
|
+
### J. Edge cases & resilience
|
|
122
|
+
- Reload mid-flow; back/forward button after actions.
|
|
123
|
+
- Slow/offline network behavior (does UI hang or handle gracefully?).
|
|
124
|
+
- Duplicate tabs / concurrent sessions.
|
|
125
|
+
- Special characters and RTL/i18n content.
|
|
126
|
+
- Very large inputs / long lists / pagination boundaries.
|
|
127
|
+
|
|
128
|
+
## Finding format (use this exactly)
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
[🔴|🟠|🟡] <short title>
|
|
132
|
+
Where: <url> — <element/flow>
|
|
133
|
+
Steps: 1) … 2) … 3) …
|
|
134
|
+
Observed: <tool output — exact console text / status / DOM fact>
|
|
135
|
+
Expected: <what should happen>
|
|
136
|
+
Impact: <user/business consequence>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Anti-patterns (do NOT do)
|
|
140
|
+
- No "could potentially" / "might be" findings. Prove it with a tool result.
|
|
141
|
+
- No attacking third parties, no DoS, no mass enumeration, no data destruction.
|
|
142
|
+
- No reporting framework defaults or intentional design as bugs.
|
|
143
|
+
- Don't stop at the first bug — sweep the whole taxonomy, then rank.
|
|
144
|
+
|
|
145
|
+
## MCP tools you have
|
|
146
|
+
`fagun_start` · `open_browser` · `navigate` · `click` · `fill` · `press_key` ·
|
|
147
|
+
`screenshot` · `evaluate_js` · `get_console` · `get_network` · `crawl` · `run_qa` ·
|
|
148
|
+
`check_links` · `test_forms` · `security_headers` · `deep_test` · `full_qa_sweep` ·
|
|
149
|
+
`write_report` · `close_browser`
|
|
150
|
+
|
|
151
|
+
When done, always `close_browser`.
|