generate-tech-stack-mcp 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ generate-tech-stack MCP Server
4
+ Universal — works with Claude Desktop, VS Code (Copilot via MCP), Cursor,
5
+ Zed, Windsurf, Continue, Antigravity, and any MCP-compatible host.
6
+
7
+ Install: pip install generate-tech-stack-mcp
8
+ Run: generate-tech-stack-mcp
9
+
10
+ Add to your MCP host config (e.g. claude_desktop_config.json):
11
+ {
12
+ "mcpServers": {
13
+ "generate-tech-stack": { "command": "generate-tech-stack-mcp" }
14
+ }
15
+ }
16
+
17
+ Then ask: /generate-tech-stack or "generate my tech stack"
18
+ """
19
+
20
+ import asyncio
21
+ import json
22
+ import os
23
+ import sys
24
+ from pathlib import Path
25
+
26
+ try:
27
+ from mcp.server import Server
28
+ from mcp.server.stdio import stdio_server
29
+ import mcp.types as types
30
+ except ImportError:
31
+ print("ERROR: mcp package not found. Run: pip install mcp", file=sys.stderr)
32
+ sys.exit(1)
33
+
34
+ from generate_tech_stack_mcp import analyze as _analyze
35
+
36
+ server = Server("generate-tech-stack")
37
+
38
+
39
+ @server.list_tools()
40
+ async def handle_list_tools() -> list[types.Tool]:
41
+ return [
42
+ types.Tool(
43
+ name="generate_tech_stack",
44
+ description=(
45
+ "Scan a project directory and generate a TECH_STACK.html visual page. "
46
+ "Includes a stat row, layered architecture diagram, bar chart summary, "
47
+ "and colour-coded tool cards. Detects languages, frameworks, databases, "
48
+ "AI SDKs, testing, observability, security, and infrastructure tools."
49
+ ),
50
+ inputSchema={
51
+ "type": "object",
52
+ "properties": {
53
+ "project_dir": {
54
+ "type": "string",
55
+ "description": "Absolute path to the project root. Defaults to cwd.",
56
+ },
57
+ "output_file": {
58
+ "type": "string",
59
+ "description": "Path for the output HTML. Defaults to <project_dir>/TECH_STACK.html.",
60
+ },
61
+ "open_browser": {
62
+ "type": "boolean",
63
+ "description": "Open the file in the default browser after creation.",
64
+ "default": True,
65
+ },
66
+ },
67
+ "required": [],
68
+ },
69
+ ),
70
+ types.Tool(
71
+ name="list_tech_stack",
72
+ description=(
73
+ "Scan a project and return the tech stack as structured JSON "
74
+ "(no HTML file written). Good for programmatic use."
75
+ ),
76
+ inputSchema={
77
+ "type": "object",
78
+ "properties": {
79
+ "project_dir": {
80
+ "type": "string",
81
+ "description": "Absolute path to the project root.",
82
+ },
83
+ },
84
+ "required": [],
85
+ },
86
+ ),
87
+ ]
88
+
89
+
90
+ @server.call_tool()
91
+ async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
92
+ project_dir = Path(arguments.get("project_dir") or os.getcwd()).resolve()
93
+
94
+ if not project_dir.exists():
95
+ return [types.TextContent(type="text", text=f"ERROR: Directory not found: {project_dir}")]
96
+
97
+ if name == "list_tech_stack":
98
+ tools = _analyze.collect(project_dir)
99
+ total = sum(len(v) for v in tools.values())
100
+ result = {
101
+ "project": project_dir.name,
102
+ "total_tools": total,
103
+ "categories": {
104
+ cat: [{"name": t["name"], "desc": t["desc"]} for t in items]
105
+ for cat, items in tools.items()
106
+ },
107
+ }
108
+ return [types.TextContent(type="text", text=json.dumps(result, indent=2))]
109
+
110
+ if name == "generate_tech_stack":
111
+ output_file = Path(
112
+ arguments.get("output_file") or (project_dir / "TECH_STACK.html")
113
+ ).resolve()
114
+
115
+ tools = _analyze.collect(project_dir)
116
+ if not tools:
117
+ return [types.TextContent(type="text",
118
+ text=f"No recognizable dependency files found in: {project_dir}")]
119
+
120
+ project_name = project_dir.name.replace("-", " ").replace("_", " ").title()
121
+ output_file.write_text(_analyze.render_html(tools, project_name))
122
+
123
+ total = sum(len(v) for v in tools.values())
124
+ lines = [
125
+ f"Tech stack generated: {output_file}",
126
+ f"Detected {total} tools across {len(tools)} categories:",
127
+ ]
128
+ for cat, items in tools.items():
129
+ meta = _analyze.CATEGORY_META.get(cat, _analyze.CATEGORY_META["other"])
130
+ names = ", ".join(t["name"] for t in items)
131
+ lines.append(f" {meta['icon']} {meta['label']}: {names}")
132
+
133
+ if arguments.get("open_browser", True):
134
+ import subprocess
135
+ for cmd in ["xdg-open", "open", "start"]:
136
+ try:
137
+ subprocess.Popen([cmd, str(output_file)],
138
+ stdout=subprocess.DEVNULL,
139
+ stderr=subprocess.DEVNULL)
140
+ break
141
+ except FileNotFoundError:
142
+ continue
143
+
144
+ return [types.TextContent(type="text", text="\n".join(lines))]
145
+
146
+ return [types.TextContent(type="text", text=f"Unknown tool: {name}")]
147
+
148
+
149
+ async def _run():
150
+ async with stdio_server() as (read_stream, write_stream):
151
+ await server.run(
152
+ read_stream,
153
+ write_stream,
154
+ server.create_initialization_options(),
155
+ )
156
+
157
+
158
+ def main():
159
+ asyncio.run(_run())
160
+
161
+
162
+ if __name__ == "__main__":
163
+ main()
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: generate-tech-stack-mcp
3
+ Version: 0.2.0
4
+ Summary: Generate a visual technology-stack inventory (TECH_STACK.html) from any codebase — languages, frameworks, databases, AI SDKs, testing, and infra. CLI + MCP server, stdlib-only scanner.
5
+ Author: Ashutosh Kumar
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/askuma/generate-tech-stack
8
+ Project-URL: Repository, https://github.com/askuma/generate-tech-stack
9
+ Project-URL: Live Demo, https://askuma.github.io/generate-tech-stack/
10
+ Keywords: mcp,mcp-server,tech-stack,dependencies,inventory,static-analysis,claude
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Software Development :: Documentation
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: mcp>=1.0.0
20
+ Dynamic: license-file
21
+
22
+ # generate-tech-stack
23
+
24
+ <!-- mcp-name: io.github.askuma/generate-tech-stack -->
25
+
26
+ Scan any project and generate a visual `TECH_STACK.html` page — dark-mode, auto-adapting, zero config.
27
+
28
+ Works as a **Claude Code skill**, **MCP server**, or **GitHub Copilot Extension**.
29
+
30
+ **[Live demo →](https://askuma.github.io/generate-tech-stack/)** — generated from
31
+ [fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template), unmodified.
32
+
33
+ ![TECH_STACK.html generated for full-stack-fastapi-template](https://raw.githubusercontent.com/askuma/generate-tech-stack/main/docs/preview.png)
34
+
35
+ ---
36
+
37
+ ## What it produces
38
+
39
+ Every generated page contains:
40
+
41
+ | Section | Description |
42
+ |---|---|
43
+ | **Stat row** | Total tools · Categories · AI Backends · Data Stores |
44
+ | **Architecture diagram** | Layered flow diagram (Consumer → API → AI/NLP → Data/Obs/Frontend) |
45
+ | **Bar chart** | Horizontal bars per category, colour-matched |
46
+ | **Tool cards** | One card per category; each tool shows a dot, name, description, and badge |
47
+ | **Badge legend** | Explains `pip`, `dep`, `optional`, `core`, `deploy`, `ci`, etc. |
48
+ | **Footer** | Project name · tool count · generation date |
49
+
50
+ ---
51
+
52
+ ## Repository layout
53
+
54
+ ```
55
+ ~/.claude/skills/generate-tech-stack/
56
+ ├── SKILL.md ← Claude Code skill definition
57
+ ├── INSTALL.md ← detailed per-platform installation guide
58
+ ├── README.md ← this file
59
+ ├── scripts/
60
+ │ └── analyze.py ← core scanner + HTML renderer (no dependencies)
61
+ ├── mcp/
62
+ │ ├── server.py ← MCP stdio server (pip install mcp)
63
+ │ └── requirements.txt
64
+ └── copilot/
65
+ ├── index.js ← GitHub Copilot Extension (Express)
66
+ ├── package.json
67
+ └── openai_function.json ← OpenAI / Antigravity function definition
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Usage
73
+
74
+ ### pip (CLI + MCP server)
75
+
76
+ ```bash
77
+ pip install generate-tech-stack-mcp
78
+
79
+ generate-tech-stack . TECH_STACK.html # CLI: scan and write the report
80
+ generate-tech-stack-mcp # stdio MCP server
81
+ ```
82
+
83
+ With pip installed, any MCP host config reduces to:
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "generate-tech-stack": { "command": "generate-tech-stack-mcp" }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Claude Code
94
+
95
+ ```
96
+ /generate-tech-stack
97
+ ```
98
+
99
+ Run it from any project directory. The skill calls `scripts/analyze.py` and opens the result in your browser.
100
+
101
+ ### MCP (Claude Desktop, VS Code, Cursor, Zed, Windsurf, Continue)
102
+
103
+ ```bash
104
+ pip install mcp
105
+ ```
106
+
107
+ Add to your host's MCP config (replace the path with your actual home directory):
108
+
109
+ ```json
110
+ {
111
+ "mcpServers": {
112
+ "generate-tech-stack": {
113
+ "command": "python3",
114
+ "args": ["/home/<you>/.claude/skills/generate-tech-stack/mcp/server.py"]
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ Then ask: `generate my tech stack` or `/generate-tech-stack`.
121
+
122
+ **MCP tools exposed:**
123
+ - `generate_tech_stack` — scans a project, writes `TECH_STACK.html`, opens in browser
124
+ - `list_tech_stack` — returns a JSON summary, no file written
125
+
126
+ ### GitHub Copilot Extension
127
+
128
+ ```bash
129
+ cd copilot
130
+ npm install
131
+ npm start # listens on port 3000
132
+ ngrok http 3000 # expose for GitHub to reach
133
+ ```
134
+
135
+ Register a GitHub App with **Copilot Extension** enabled, set the Agent URL to `https://your-url/agent`, and install it on your account. Then in Copilot Chat:
136
+
137
+ ```
138
+ @generate-tech-stack /generate-tech-stack
139
+ @generate-tech-stack /generate-tech-stack /path/to/project
140
+ ```
141
+
142
+ ### Command line (standalone)
143
+
144
+ ```bash
145
+ python3 ~/.claude/skills/generate-tech-stack/scripts/analyze.py /path/to/project
146
+ # output: /path/to/project/TECH_STACK.html
147
+
148
+ # custom output path:
149
+ python3 scripts/analyze.py . ~/Desktop/TECH_STACK.html
150
+ ```
151
+
152
+ `analyze.py` has no third-party dependencies — just Python 3.8+.
153
+
154
+ ---
155
+
156
+ ## What gets detected
157
+
158
+ | Source file | Detected tools |
159
+ |---|---|
160
+ | `requirements.txt` / `pyproject.toml` | Python packages (web, DB, AI, testing, observability, security…) |
161
+ | `package.json` | Node / npm packages (frameworks, frontend, DB drivers, tooling) |
162
+ | `go.mod` | Go language |
163
+ | `Cargo.toml` | Rust language |
164
+ | `pom.xml` / `build.gradle` | Java / Kotlin |
165
+ | `Gemfile` | Ruby |
166
+ | `composer.json` | PHP |
167
+ | `**/*.py` source | Optional/dynamic SDKs via `importlib.find_spec()` patterns |
168
+ | `docker-compose.yml` / `.env` | PostgreSQL, Redis, MongoDB, SQLite connection strings |
169
+ | `Dockerfile` | Docker |
170
+ | `docker-compose.yml` | Docker Compose |
171
+ | `.github/workflows/` | GitHub Actions |
172
+ | `.gitlab-ci.yml` | GitLab CI |
173
+ | `alembic.ini` | Alembic migrations |
174
+ | `nginx.conf` / `Caddyfile` | Reverse proxy |
175
+ | `tsconfig.json` / `src/**/*.ts` | TypeScript |
176
+
177
+ ---
178
+
179
+ ## Detected categories
180
+
181
+ | Category | Colour | Examples |
182
+ |---|---|---|
183
+ | Language & Runtime | Green | Python, Go, Rust, TypeScript |
184
+ | Web / API Framework | Purple | FastAPI, Express, Django, Next.js |
185
+ | Database / Storage | Green | SQLAlchemy, Prisma, Redis, ChromaDB |
186
+ | AI Guardrail SDKs | Blue | GuardrailsAI, NVIDIA NeMo, Presidio, Lakera |
187
+ | NLP / ML | Teal | spaCy, Transformers, Sentence Transformers |
188
+ | Observability | Teal | Prometheus, OpenTelemetry, Sentry, Loguru |
189
+ | Testing | Yellow | pytest, Jest, Cypress, Playwright |
190
+ | Security / Auth | Rose | PyJWT, bcrypt, Authlib, Helmet |
191
+ | Infrastructure / Deploy | Orange | Docker, Kubernetes, Celery, Boto3 |
192
+ | Frontend / Dashboard | Gray | React, Vue, Tailwind, Recharts |
193
+ | Messaging / Comms | Blue | Kafka, RabbitMQ, Socket.io |
194
+ | Dev Tools | Gray | ESLint, Prettier, Vite, TypeScript |
195
+
196
+ ---
197
+
198
+ ## Design
199
+
200
+ Dark-mode only. Fonts: **IBM Plex Sans** (body) + **JetBrains Mono** (code/badges), loaded from Google Fonts. No JavaScript — pure HTML + CSS. Self-contained single file, opens in any browser offline.
201
+
202
+ ---
203
+
204
+ ## See also
205
+
206
+ - [INSTALL.md](INSTALL.md) — per-platform setup instructions
207
+ - [SKILL.md](SKILL.md) — Claude Code skill specification
@@ -0,0 +1,9 @@
1
+ generate_tech_stack_mcp/__init__.py,sha256=pzTcB3QF1p03CzooQO79pnfS2UBzps_YfudDFxJEix0,106
2
+ generate_tech_stack_mcp/analyze.py,sha256=3moRyfsLWuAOd5lNo77QHwX3whmq2UYK3axZaaLTEt4,50294
3
+ generate_tech_stack_mcp/server.py,sha256=bBBvzgASW5SKj9BQgEimliAJ8lJ6EhWp5nlT9QmfB_c,5568
4
+ generate_tech_stack_mcp-0.2.0.dist-info/licenses/LICENSE,sha256=k1Mx2UUhlahBiae3uzw2oGHhMN98awy7RztDPeJwIvI,1071
5
+ generate_tech_stack_mcp-0.2.0.dist-info/METADATA,sha256=AZcTmD5yS-F5cTx3eSjNJmL3z1F4mEniO5osYWvryg0,6846
6
+ generate_tech_stack_mcp-0.2.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
7
+ generate_tech_stack_mcp-0.2.0.dist-info/entry_points.txt,sha256=bAZhRj-mjrrYtu4pUy7CzYwgeMlkLxCe3PaBy6Hda8g,139
8
+ generate_tech_stack_mcp-0.2.0.dist-info/top_level.txt,sha256=s8p9Nz7Dtk9vE_UTs6vTAl3vsPBU4COqRW_XytwuHYA,24
9
+ generate_tech_stack_mcp-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ generate-tech-stack = generate_tech_stack_mcp.analyze:main
3
+ generate-tech-stack-mcp = generate_tech_stack_mcp.server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ashutosh Kumar
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 @@
1
+ generate_tech_stack_mcp