# Tech Ecosystem Analysis MCP (`ryanclinton/tech-ecosystem-analysis-mcp`) Actor

Technology intelligence for mapping tech ecosystems, tracking adoption trends, detecting vulnerabilities, and analyzing developer sentiment.

- **URL**: https://apify.com/ryanclinton/tech-ecosystem-analysis-mcp.md
- **Developed by:** [ryan clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Tech Ecosystem Analysis MCP

Tech ecosystem analysis for AI agents and LLM workflows — maps technology relationships, tracks adoption curves, detects CVE vulnerabilities, and scores tech stack risk across 6 live data sources. Connect once via the Model Context Protocol and your AI assistant can evaluate any framework, language, or tool with structured, data-driven intelligence.

This MCP server runs on the Apify platform in Standby mode and exposes 8 tools that orchestrate GitHub, NVD CVE database, StackExchange, Hacker News, Wikipedia, and a live Tech Stack Detector in parallel. Each tool returns structured JSON with per-technology scores, trend classifications, and actionable recommendations — ready to drop into any agent workflow.

### ⬇️ What data can you access?

| Data Point | Source | Example |
|---|---|---|
| 📦 Repository count, stars, forks, contributor activity | GitHub Search | React: 45,231 stars across top repos |
| 🔐 CVE IDs, CVSS scores, severity levels, affected versions | NVD CVE Database | CVE-2024-21490, CVSS 9.8, CRITICAL |
| 💬 Q&A volume, answer rates, tag popularity, community score | StackExchange | TypeScript: 94% answer rate, 12,400 questions |
| 📰 Discussion engagement, upvote patterns, trending sentiment | Hacker News | Rust: avg 312 points, 187 comments/post |
| 📖 Technology history, ecosystem context, maturity indicators | Wikipedia | Go: first appeared 2009, 15 years ago |
| 🌐 Detected frameworks, CMSs, CDNs, analytics tools from live URLs | Tech Stack Detector | acmecorp.com: Next.js, Vercel, Cloudflare |
| 📈 Adoption phase classification (emerging/growing/mature/declining) | Composite scoring | SvelteKit: growing, momentum 74/100 |
| ⚠️ Weighted exposure score (critical CVEs × 3, high CVEs × 2) | Composite scoring | OpenSSL: exposure score 60/100 |

### MCP tools

| Tool | Price | What it returns |
|------|-------|-----------------|
| `map_tech_ecosystem` | $0.045 | Degree-centrality network graph with nodes, edges, graph density, and top technologies |
| `assess_tech_adoption` | $0.045 | GitHub star totals, SO question volume, answer rates, growth rate, trend direction |
| `detect_tech_vulnerabilities` | $0.045 | CVE list with CVSS scores, severity, weighted exposure score per technology |
| `analyze_developer_sentiment` | $0.045 | HN engagement (points + comments) + SO quality (answer rate, score) per technology |
| `score_tech_stack_risk` | $0.045 | Weighted risk score: CVE exposure (40%) + inverse community (35%) + inverse maturity (25%) |
| `track_framework_trends` | $0.045 | S-curve phase (emerging/growing/mature/declining), momentum score, fork/star velocity |
| `assess_tech_maturity` | $0.045 | 6-factor maturity model: age, community size, docs quality, enterprise adoption, ecosystem breadth, stability |
| `generate_tech_report` | $0.045 | Full report combining all 7 analyses with summary, critical findings, and recommendations |

### Why use Tech Ecosystem Analysis MCP?

Engineering teams, security analysts, and CTOs make multi-year technology bets with incomplete information. Manual research across GitHub, StackOverflow, CVE databases, and Hacker News takes hours per framework and goes stale immediately. Consulting analysts charge thousands for reports that are already weeks out of date.

This MCP automates the entire research pipeline. Your AI agent can invoke a single tool call and get live adoption data, CVE exposure, developer sentiment, and maturity classification — all in one structured response. The data is fetched at query time from the source databases, not a cached snapshot.

Platform benefits when running on Apify:
- **Scheduling** — run weekly ecosystem checks to track how your tech stack's risk profile changes over time
- **API access** — trigger assessments from CI/CD pipelines, Slack bots, or any HTTP client
- **Parallel execution** — up to 6 actor calls run simultaneously per tool invocation, reducing latency
- **Spending limits** — set a per-run budget cap; the server returns a graceful error when the limit is reached
- **Integrations** — connect results to Zapier, Make, webhooks, or push directly to Notion or Confluence

### Data sources

#### GitHub Search
Queries repository metadata including star counts, fork counts, primary language, creation date, last update date, and repository topics. The actor collects up to 30 results per query and filters them per technology by matching against `language`, `name`, and `description` fields. Star totals drive adoption scoring (50% weight) and community support scoring.

#### NVD CVE Database
Fetches live vulnerability records from the National Vulnerability Database. Each CVE includes its ID, CVSS base score, severity level (LOW/MEDIUM/HIGH/CRITICAL), affected products list, description, and published date. The vulnerability exposure formula weights critical CVEs at 3x, high CVEs at 2x, and others at 1x — capped at 100. Risk level thresholds: CRITICAL at CVSS >= 9.0 or any critical CVE present; HIGH at CVSS >= 7.0; MEDIUM at CVSS >= 4.0.

#### StackExchange
Retrieves Q&A threads with question titles, tags, community score, answered/unanswered status, and creation date. Answer rates contribute to both adoption scoring (20% weight) and sentiment scoring (50% weight). The 30-day question window measures current momentum versus historical activity.

#### Hacker News
Pulls discussion threads matched to each technology. Engagement signals — upvote points and comment counts — feed the sentiment formula: HN engagement accounts for 50% of sentiment score (points: 40%, comments: 10%). The top 5 posts by points are returned per technology.

#### Wikipedia
Extracts article text and parses it for release year patterns (`released in YYYY`, `first appeared YYYY`, `created YYYY`). This estimated age drives the maturity model (20% weight in composite maturity score) and provides ecosystem context for the network graph.

#### Tech Stack Detector
Scans live websites via the `ryanclinton/website-tech-stack-detector` actor. Returns detected technologies with names, categories, confidence scores, and detected versions. Used in `map_tech_ecosystem`, `detect_tech_vulnerabilities`, and `generate_tech_report` when URLs are provided. Detected technologies are automatically added to the CVE scan.

### How the scoring algorithms work

#### Adoption Score (0–100)
GitHub star contribution (50% weight): `min(totalStars / 50,000, 1) × 50`. StackOverflow contribution (50% weight): question volume `min(count / 100, 1) × 30` plus answer rate `× 20`. Growth rate is measured as the fraction of SO questions created in the last 30 days — above 30% classifies as `rising`, below 5% as `declining`.

#### Vulnerability Exposure Score (0–100)
Weighted severity sum: `(criticalCVEs × 3 + highCVEs × 2 + otherCVEs × 1) × 10`, capped at 100. Risk level classification: CRITICAL when avg CVSS >= 9 or any critical CVE present; HIGH when avg CVSS >= 7; MEDIUM when avg CVSS >= 4; LOW when CVEs exist but avg is below 4.

#### Developer Sentiment Score (0–100)
HN component (50%): `min(avgPoints / 100, 1) × 40 + min(avgComments / 50, 1) × 10`. SO component (50%): `min(avgScore / 10, 1) × 30 + (1 - unansweredRatio) × 20`. Overall classification: positive >= 60, negative < 30, neutral in between.

#### Tech Stack Risk Score (0–100)
Three-factor weighted combination: CVE exposure score × 0.40 + (100 − community support score) × 0.35 + (100 − maturity score) × 0.25. Community support: GitHub stars (40%), SO coverage (30%), repos updated in last 90 days (30%). Risk thresholds: critical >= 75, high >= 50, medium >= 25, low below 25.

#### Maturity Score (0–100) and S-Curve Classification
Six indicators: technology age `min(ageYears / 15, 1) × 20` + community size `min(totalStars / 100,000, 1) × 20` + documentation quality `× 0.20` + enterprise adoption (repos > 1K stars) `× 0.15` + ecosystem breadth (unique topics) `× 0.15` + stability index `× 0.10`. Classification: mature when score >= 70 and age >= 8 years; growing when score >= 45 or age >= 3 with community > 10K; declining when score < 25, age > 10, and < 2 recent updates; emerging otherwise.

#### Ecosystem Network (Degree Centrality)
Builds a directed graph with node types: `technology`, `repo`, `discussion`, `vulnerability`, `article`, `website`. Edge types: `implements` (repo → technology, weighted by normalized star count), `describes` (article → technology, weight 0.5), `uses` (website → technology, weighted by detection confidence). Degree centrality = node degree / (N − 1). Graph density = 2E / (N × (N − 1)).

### Use cases for tech ecosystem analysis

#### Engineering team technology selection
CTOs and engineering leads evaluating a new framework need more than a blog post. Feed your candidate stack into `score_tech_stack_risk` to get a CVE-weighted, community-adjusted risk score before committing engineering resources. Compare React vs Vue vs Svelte on a single tool call.

#### Security team CVE mapping
Security engineers running quarterly vulnerability reviews can provide a list of production technologies (or their web application URLs for auto-detection) to `detect_tech_vulnerabilities`. The tool returns a ranked CVE list with CVSS scores and exposure weights, ready to feed into remediation prioritization workflows.

#### VC and M&A technology due diligence
Investment analysts assessing a company's technical moat or liability need to understand whether the target's stack is on a growth curve or approaching end of community support. `generate_tech_report` produces a full analysis — adoption trends, maturity stages, CVE exposure, and sentiment — in a single AI agent call.

#### Developer relations and content strategy
DevRel teams deciding where to invest conference talks, tutorials, and community sponsorship can use `track_framework_trends` to identify which frameworks are in the growing phase with high momentum scores. This replaces expensive survey research with live data.

#### Framework migration planning
Teams building a business case for migrating from an aging framework need data on whether the candidate is truly mature or still volatile. `assess_tech_maturity` produces a 6-factor maturity model with enterprise adoption proxy, ecosystem breadth, and stability index — structured evidence for migration decisions.

#### AI agent continuous monitoring
Engineering organizations using AI coding assistants can wire this MCP into a scheduled Apify run. Weekly calls to `score_tech_stack_risk` across the production stack automatically surface new CVEs or community health drops before they become incidents.

### How to connect this MCP server

#### Claude Desktop
Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "tech-ecosystem-analysis": {
      "url": "https://tech-ecosystem-analysis-mcp.apify.actor/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_APIFY_TOKEN"
      }
    }
  }
}
````

#### Cursor / Windsurf / Cline

Add the same URL and Authorization header in your MCP client settings. The server uses the Streamable HTTP transport — no SSE configuration required.

#### HTTP directly

```bash
curl -X POST "https://tech-ecosystem-analysis-mcp.apify.actor/mcp" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "assess_tech_adoption",
      "arguments": {
        "technologies": ["TypeScript", "Rust", "Go"]
      }
    },
    "id": 1
  }'
```

#### Python (via openai-agents or any MCP client)

```python
import httpx

response = httpx.post(
    "https://tech-ecosystem-analysis-mcp.apify.actor/mcp",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_APIFY_TOKEN",
    },
    json={
        "jsonrpc": "2.0",
        "method": "tools/call",
        "params": {
            "name": "score_tech_stack_risk",
            "arguments": {
                "technologies": ["Django", "Flask", "FastAPI"]
            }
        },
        "id": 1,
    }
)

result = response.json()
for tech in result["result"]["content"]:
    print(tech["text"])
```

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `port` | integer | No | 3054 | Port number for the MCP server (1024–65535). Used when running outside Standby mode. |

The MCP server has no other actor-level inputs. All configuration is passed per tool call as tool arguments.

### Tool arguments reference

#### map\_tech\_ecosystem

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to map, e.g. `["React", "Node.js", "PostgreSQL"]` |
| `urls` | string\[] | No | Website URLs to detect additional technologies from |

#### assess\_tech\_adoption

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to assess, e.g. `["TypeScript", "Rust", "Go"]` |

#### detect\_tech\_vulnerabilities

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to check against NVD CVE database |
| `urls` | string\[] | No | Website URLs — auto-detected technologies are added to the CVE scan |

#### analyze\_developer\_sentiment

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to measure sentiment for |

#### score\_tech\_stack\_risk

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to score for composite risk |

#### track\_framework\_trends

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `frameworks` | string\[] | Yes | Frameworks to track, e.g. `["Next.js", "SvelteKit", "Remix"]` |

#### assess\_tech\_maturity

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to place on the S-curve lifecycle model |

#### generate\_tech\_report

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `technologies` | string\[] | Yes | Technologies to include in the full report |
| `urls` | string\[] | No | Website URLs for tech stack auto-detection |

### ⬆️ Output examples

#### assess\_tech\_adoption — sample output

```json
[
  {
    "technology": "TypeScript",
    "githubMetrics": {
      "totalRepos": 18,
      "totalStars": 98421,
      "avgStars": 5468,
      "topRepos": [
        { "name": "microsoft/TypeScript", "stars": 98421, "url": "https://github.com/microsoft/TypeScript" },
        { "name": "type-challenges/type-challenges", "stars": 43102, "url": "https://github.com/type-challenges/type-challenges" }
      ]
    },
    "stackOverflowMetrics": {
      "totalQuestions": 84,
      "avgScore": 4.2,
      "answerRate": 0.94,
      "recentActivity": 31
    },
    "adoptionScore": 79,
    "trend": "rising",
    "growthRate": 0.37
  }
]
```

#### score\_tech\_stack\_risk — sample output

```json
[
  {
    "technology": "Log4j",
    "cveExposure": {
      "score": 89,
      "totalCves": 7,
      "criticalCves": 2,
      "highCves": 3
    },
    "communitySupport": {
      "score": 42,
      "githubStars": 3210,
      "soQuestions": 14,
      "recentActivity": 1
    },
    "maturityFactor": {
      "score": 58,
      "ageYears": 18,
      "releaseFrequency": "infrequent"
    },
    "overallRisk": 76,
    "riskLevel": "critical",
    "recommendation": "Log4j has critical risk. Immediate review: 7 CVEs (2 critical) with limited community support."
  }
]
```

#### generate\_tech\_report — sample output (abbreviated)

```json
{
  "title": "Technology Ecosystem Report: React, TypeScript, PostgreSQL",
  "generatedAt": "2026-03-21T09:14:02.341Z",
  "technologies": ["React", "TypeScript", "PostgreSQL"],
  "summary": "Analyzed 3 technologies. Ecosystem contains 47 nodes and 83 relationships. Graph density: 0.076. Top technologies: TypeScript, React, PostgreSQL. Overall risk assessment: LOW — stack is healthy.",
  "sections": {
    "adoption": [
      { "technology": "React", "adoptionScore": 88, "trend": "stable" },
      { "technology": "TypeScript", "adoptionScore": 79, "trend": "rising" },
      { "technology": "PostgreSQL", "adoptionScore": 71, "trend": "stable" }
    ],
    "vulnerabilities": [
      { "technology": "React", "riskLevel": "low", "totalCves": 2, "avgCvss": 4.3, "exposureScore": 20 },
      { "technology": "TypeScript", "riskLevel": "none", "totalCves": 0, "avgCvss": 0, "exposureScore": 0 },
      { "technology": "PostgreSQL", "riskLevel": "medium", "totalCves": 6, "avgCvss": 6.1, "exposureScore": 40 }
    ],
    "maturity": [
      { "technology": "React", "maturityLevel": "mature", "maturityScore": 87 },
      { "technology": "TypeScript", "maturityLevel": "growing", "maturityScore": 61 },
      { "technology": "PostgreSQL", "maturityLevel": "mature", "maturityScore": 91 }
    ]
  },
  "recommendations": [
    "Technology stack appears healthy. Continue regular security audits and dependency updates."
  ],
  "riskSummary": {
    "overallRisk": "LOW — stack is healthy",
    "criticalFindings": [],
    "positiveIndicators": [
      "React: positive developer sentiment (score: 74/100)",
      "TypeScript: strong growth momentum (82/100)"
    ]
  }
}
```

### Output fields

#### assess\_tech\_adoption

| Field | Type | Description |
|-------|------|-------------|
| `technology` | string | Technology name |
| `githubMetrics.totalRepos` | number | Repos matched to this technology |
| `githubMetrics.totalStars` | number | Sum of stars across matched repos |
| `githubMetrics.avgStars` | number | Mean stars per repo |
| `githubMetrics.topRepos` | array | Top 5 repos by stars with name, stars, url |
| `stackOverflowMetrics.totalQuestions` | number | SO questions matched to this technology |
| `stackOverflowMetrics.avgScore` | number | Mean community score of matched questions |
| `stackOverflowMetrics.answerRate` | number | Fraction of questions with accepted answers (0–1) |
| `stackOverflowMetrics.recentActivity` | number | Questions created in the last 30 days |
| `adoptionScore` | number | Weighted adoption score (0–100) |
| `trend` | string | `rising`, `stable`, or `declining` |
| `growthRate` | number | Ratio of recent to total SO activity (0–1) |

#### detect\_tech\_vulnerabilities

| Field | Type | Description |
|-------|------|-------------|
| `technology` | string | Technology name (includes auto-detected from URLs) |
| `cves` | array | CVE records with id, severity, cvssScore, description, publishedDate |
| `riskLevel` | string | `critical`, `high`, `medium`, `low`, or `none` |
| `totalCves` | number | Total matched CVEs |
| `avgCvss` | number | Mean CVSS base score |
| `exposureScore` | number | Weighted exposure score (0–100) |

#### score\_tech\_stack\_risk

| Field | Type | Description |
|-------|------|-------------|
| `technology` | string | Technology name |
| `cveExposure.score` | number | CVE exposure component (0–100) |
| `cveExposure.criticalCves` | number | Count of CRITICAL severity CVEs |
| `cveExposure.highCves` | number | Count of HIGH severity CVEs |
| `communitySupport.score` | number | Community health component (0–100) |
| `communitySupport.githubStars` | number | Total GitHub stars for matched repos |
| `communitySupport.soQuestions` | number | Matched SO questions |
| `communitySupport.recentActivity` | number | Repos updated in last 90 days |
| `maturityFactor.score` | number | Maturity component (0–100) |
| `maturityFactor.ageYears` | number | Estimated age from Wikipedia |
| `maturityFactor.releaseFrequency` | string | `frequent`, `regular`, or `infrequent` |
| `overallRisk` | number | Composite risk score (0–100) |
| `riskLevel` | string | `critical`, `high`, `medium`, or `low` |
| `recommendation` | string | Plain-language action recommendation |

#### assess\_tech\_maturity

| Field | Type | Description |
|-------|------|-------------|
| `technology` | string | Technology name |
| `maturityLevel` | string | `emerging`, `growing`, `mature`, or `declining` |
| `indicators.age` | string | Formatted age string, e.g. "15 years (since 2009)" |
| `indicators.communitySize` | number | Total GitHub stars across matched repos |
| `indicators.documentationQuality` | number | Docs score (0–100): Wikipedia presence + SO answer rate |
| `indicators.enterpriseAdoption` | number | Proxy score based on repos with > 1K stars (0–100) |
| `indicators.ecosystemBreadth` | number | Unique GitHub topics across repos, scaled to 100 |
| `indicators.stabilityIndex` | number | Answer rate + recent update ratio (0–100) |
| `maturityScore` | number | Composite maturity score (0–100) |
| `description` | string | Plain-language maturity description |

#### track\_framework\_trends

| Field | Type | Description |
|-------|------|-------------|
| `framework` | string | Framework name |
| `githubTrend.stars` | number | Total stars across matched repos |
| `githubTrend.forks` | number | Total forks across matched repos |
| `githubTrend.recentRepos` | number | Repos created in the last 6 months |
| `githubTrend.growthRate` | number | % of repos created in the last 6 months |
| `stackOverflowTrend.questionCount` | number | Total matched SO questions |
| `stackOverflowTrend.recentQuestions` | number | SO questions in the last 30 days |
| `stackOverflowTrend.trendDirection` | string | `up`, `stable`, or `down` |
| `adoptionPhase` | string | S-curve phase: `emerging`, `growing`, `mature`, `declining` |
| `momentum` | number | Composite momentum score (0–100) |

### How much does it cost to run tech ecosystem analysis?

This MCP uses **pay-per-event pricing** — every tool call costs **$0.045**. All 8 tools are priced identically. Platform compute is included.

| Scenario | Tool calls | Cost per call | Total cost |
|----------|-----------|---------------|------------|
| Quick vulnerability scan (1 technology) | 1 | $0.045 | $0.045 |
| Adoption check for 3 frameworks | 1 | $0.045 | $0.045 |
| Full 8-tool suite on one tech stack | 8 | $0.045 | $0.36 |
| Weekly monitoring (8 tools × 4 weeks) | 32 | $0.045 | $1.44 |
| Team usage — 10 reports/month | 80 | $0.045 | $3.60 |

Apify's free plan includes $5 of monthly credits — enough for 110 individual tool calls or 13 full 8-tool ecosystem reports with no subscription required. You can set a **maximum spending limit** per run to control costs.

Compare this to manual research or analyst reports: a single technology due diligence report from a consultancy typically costs $2,000–5,000 and takes 2–3 weeks. With this MCP, your AI agent produces the same structured data in seconds for $0.045.

### How Tech Ecosystem Analysis MCP works

#### Step 1: Tool invocation and charge

When an MCP client calls a tool, the server charges the `Actor.charge()` event immediately. If a spending limit has been set and is reached, the tool returns a structured error JSON rather than proceeding — preventing surprise overspend.

#### Step 2: Parallel actor execution

`runActorsParallel()` launches all required data source actors simultaneously via the Apify client. Each actor runs with 256 MB memory and a 180-second timeout. Results are collected via `dataset.listItems({ limit: 500 })`. Failed actors return empty arrays — the scoring functions handle missing data gracefully without throwing.

Data sources per tool:

- `map_tech_ecosystem`: GitHub (20 results) + Wikipedia (5 results) + Tech Stack Detector per URL
- `assess_tech_adoption`: GitHub (30) + StackExchange (30)
- `detect_tech_vulnerabilities`: NVD CVE (30) + Tech Stack Detector per URL
- `analyze_developer_sentiment`: Hacker News (30) + StackExchange (30)
- `score_tech_stack_risk`: NVD CVE (30) + GitHub (20) + StackExchange (20) + Wikipedia (5)
- `track_framework_trends`: GitHub (30) + StackExchange (30)
- `assess_tech_maturity`: GitHub (20) + StackExchange (20) + Wikipedia (5)
- `generate_tech_report`: all 5 sources (30 results each) + Tech Stack Detector per URL

#### Step 3: Scoring and classification

Each scoring function filters the raw actor results per technology using case-insensitive substring matching on `language`, `name`, `description`, `title`, and `tags` fields. Scores are computed in-process with no external API calls. All intermediate scores are clamped between 0 and 100. The `generateReport` function calls all 7 scoring functions sequentially on the same data object and assembles the combined output.

#### Step 4: Response

Results are serialized as pretty-printed JSON and returned as an MCP content block with type `text`. The Streamable HTTP transport handles per-request session lifecycle — the server creates a new `McpServer` instance per POST to `/mcp`, avoiding shared state between requests.

### Tips for best results

1. **Provide 2–5 technologies per call for richer network graphs.** Single-technology calls work for vulnerability checks but ecosystem mapping needs co-occurrence data to build meaningful edges.

2. **Use `generate_tech_report` for due diligence, individual tools for monitoring.** The full report calls all 6 data sources and runs all 7 scoring functions — ideal for one-off analysis. For weekly automated checks, call `score_tech_stack_risk` and `detect_tech_vulnerabilities` only to minimize cost.

3. **Add website URLs to vulnerability scans.** Pass your production application URLs to `detect_tech_vulnerabilities` or `generate_tech_report`. The Tech Stack Detector identifies technologies you may not have listed, and they are automatically added to the CVE scan.

4. **Interpret maturity scores alongside growth rates.** A technology can be `growing` phase (high momentum) but still have a low maturity score — meaning it is gaining adoption but the ecosystem is still volatile. Both signals together tell the full story.

5. **Use `track_framework_trends` before `assess_tech_maturity` when comparing candidates.** Trends data tells you where a framework is heading; maturity tells you where it is now. For migration decisions, you want both.

6. **Set a spending limit on your Apify run** if you are exposing this MCP to multiple users or an agent that may call tools in loops. The server handles limit-reached events cleanly and returns a parseable error.

7. **Cache `generate_tech_report` results in your agent memory.** The full report is comprehensive — your agent does not need to re-run it more than once per session unless technologies change. Individual tools like `detect_tech_vulnerabilities` benefit from fresh runs when assessing newly disclosed CVEs.

### Combine with other Apify actors and MCPs

| Actor / MCP | How to combine |
|-------------|---------------|
| [Website Tech Stack Detector](https://apify.com/ryanclinton/website-tech-stack-detector) | Run standalone to audit competitor websites before feeding detected technologies into `detect_tech_vulnerabilities` |
| [Company Deep Research](https://apify.com/ryanclinton/company-deep-research) | Combine company intelligence with tech stack risk to assess a vendor or acquisition target holistically |
| [OSS Dependency Risk MCP](https://apify.com/ryanclinton/oss-dependency-risk-mcp) | Pair CVE exposure from this MCP with supply chain dependency analysis for full open source risk coverage |
| [Website Content to Markdown](https://apify.com/ryanclinton/website-content-to-markdown) | Convert technology documentation sites to markdown for LLM-assisted analysis of API stability and breaking changes |
| [NVD CVE Vulnerability Search](https://apify.com/ryanclinton/nvd-cve-vulnerability-search) | Run direct CVE queries for specific CVE IDs surfaced in `detect_tech_vulnerabilities` results |
| [GitHub Repo Search](https://apify.com/ryanclinton/github-repo-search) | Query specific repositories in depth after ecosystem mapping identifies key projects |
| [Startup Due Diligence](https://apify.com/ryanclinton/startup-due-diligence) | Use tech ecosystem risk scores as an input signal in startup technology risk assessments |

### Limitations

- **Data recency depends on source APIs.** GitHub and StackExchange results reflect current state at query time. NVD CVE data reflects publicly disclosed vulnerabilities — zero-days are not in the database by definition.
- **Scoring is signal-based, not authoritative.** The maturity and adoption scores are derived from public activity signals. A technology can have high GitHub stars but poor enterprise production quality, or low stars but strong institutional use.
- **Technology name matching uses substring search.** Querying "Go" will also match "Django", "MongoDB", etc. Use specific names like "Golang" or "Go programming language" for better filtering accuracy.
- **Wikipedia age extraction depends on article text patterns.** If Wikipedia does not contain a release year in a recognized format, `ageYears` defaults to 5 and maturity scores will be less accurate.
- **No historical trend data.** Scores reflect a point-in-time snapshot. The tool cannot show you a star growth chart or 12-month CVE history — it shows current state only.
- **CVE matching is text-based, not CPE-based.** The NVD actor matches CVEs by description and affected product name. This can produce false positives for common technology names and miss CVEs with non-obvious product naming.
- **Parallel actor calls have a 180-second timeout.** For large technology lists (10+ technologies), some actors may timeout under heavy Apify platform load, returning partial data.
- **Website tech stack detection requires publicly accessible URLs.** Password-protected, IP-allowlisted, or bot-blocked sites will return no technology data.

### Integrations

- [Apify API](https://docs.apify.com/api/v2) — Trigger assessment runs from CI/CD pipelines or security tooling via HTTP
- [Webhooks](https://docs.apify.com/platform/integrations/webhooks) — Fire alerts when a `generate_tech_report` run detects critical CVEs or risk level changes
- [Zapier](https://apify.com/integrations/zapier) — Connect ecosystem analysis results to Jira ticket creation for CVE remediation workflows
- [Make](https://apify.com/integrations/make) — Build automated weekly tech stack health dashboards delivered to Slack or email
- [Google Sheets](https://apify.com/integrations/google-sheets) — Export adoption scores and maturity classifications to a shared team spreadsheet for tech radar maintenance
- [LangChain / LlamaIndex](https://docs.apify.com/platform/integrations) — Use this MCP as a tool within ReAct agents for autonomous technology research and recommendation workflows

### Troubleshooting

**Tool call returns empty arrays for all technologies.** This usually means all parallel actor calls timed out or the Apify token has insufficient credits. Check your Apify account balance and ensure the token passed in the Authorization header has `Actor:run` permissions. Each tool call requires credits to run the underlying actors.

**CVE results seem incomplete or include unrelated vulnerabilities.** The NVD actor uses text matching. Try more specific technology names — use "Apache Log4j" instead of "Log4j", or "OpenSSL" instead of "SSL". Broad terms like "Java" or "Python" will match thousands of unrelated CVEs and flood the results.

**`assess_tech_maturity` returns `ageYears: 5` for all technologies.** Wikipedia article extraction did not find a release year in a recognized pattern. This is common for technologies whose Wikipedia articles describe history differently. The score still works but age contribution defaults to the minimum. Use the other maturity indicators to interpret the result.

**`map_tech_ecosystem` returns a sparse graph with few edges.** Sparse graphs occur when technologies have little co-occurrence in the GitHub results. Use related technologies that are commonly used together — for example, `["React", "TypeScript", "Tailwind", "Vite"]` rather than unrelated technologies like `["React", "Kubernetes", "PostgreSQL"]`.

**Spending limit reached error during `generate_tech_report`.** The full report is the most expensive single call (one charge event). If this error appears, your run-level spending limit is set too low. Increase it in the Apify Console run settings, or set `maxTotalChargeUsd` higher when calling the actor via API.

### Responsible use

- This MCP accesses only publicly available data from open databases (GitHub, NVD, StackExchange, Hacker News, Wikipedia).
- CVE data from NVD is U.S. government public domain — no restrictions on use.
- GitHub, StackExchange, and Hacker News data is subject to their respective API terms of service.
- Do not use vulnerability data to exploit systems. CVE information is provided for defensive security research and risk assessment.
- For guidance on web scraping legality, see [Apify's guide](https://blog.apify.com/is-web-scraping-legal/).

### ❓ FAQ

**How many technologies can I analyze in a single tool call?**
There is no hard limit. The scoring functions process every technology in the input array. In practice, 1–10 technologies per call produces the best signal-to-noise ratio. Very large lists (20+) dilute GitHub and SO query results because all technologies are combined into a single search query.

**Can tech ecosystem analysis detect vulnerabilities in my own codebase?**
No — this MCP analyzes the technology itself (the framework, language, or library), not your specific version or configuration. It fetches all publicly known CVEs for a named technology. Use it to identify which components in your stack have known CVEs, then cross-reference with your actual dependency versions.

**How current is the CVE vulnerability data?**
CVE data is fetched live from the National Vulnerability Database at the time of each tool call. There is no caching — every call to `detect_tech_vulnerabilities` or `score_tech_stack_risk` reflects the current published CVE database state.

**Does tech ecosystem analysis work for proprietary or internal technologies?**
Technologies must have a presence on GitHub, StackOverflow, or NVD to return meaningful data. Internal tools or unpublished libraries will return empty results. It works for any public framework, language, database, cloud service, or open source library.

**How is this different from Snyk or Dependabot?**
Snyk and Dependabot analyze specific dependency versions in your lock files. This MCP analyzes the technology ecosystem at the community and security intelligence level — adoption trends, maturity stages, developer sentiment, and ecosystem health. They are complementary: use Snyk for version-specific CVE patching, use this MCP for strategic technology selection and risk scoring.

**Can I schedule this MCP to run automatically?**
Yes. You can trigger the actor via the Apify API on a schedule (Apify Scheduler or any cron service). Each scheduled run connects to the MCP server and calls the tools you configure. This is useful for weekly tech stack health monitoring where you want alerts if new critical CVEs appear.

**What is the typical response time per tool call?**
Each tool call runs up to 4 parallel actor executions with a 180-second timeout each. Typical latency is 15–45 seconds depending on data source response times. `generate_tech_report` is the slowest, running all 6 sources simultaneously.

**Is it legal to scrape GitHub, StackOverflow, and Hacker News for this?**
All data sources are accessed via their official public APIs, not via web scraping. GitHub Search API, NVD's REST API, StackExchange API, and Hacker News Firebase API are all publicly available. See [Apify's guide on web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

**Can I use the output in commercial products or reports?**
Yes. NVD data is U.S. government public domain. GitHub and StackExchange API data is generally permissible for analysis and reporting under their terms of service. Review each source's terms for your specific use case before redistribution.

**What happens if one of the underlying actors fails during a tool call?**
The `runActorsParallel` function catches errors per actor and returns an empty array for that source. Scoring functions handle missing data gracefully — they simply contribute zero to the relevant score components rather than throwing. The tool always returns a result; it may just have lower confidence when some sources failed.

**How is the S-curve phase different from the trend direction?**
Trend direction (`up`/`stable`/`down`) reflects short-term momentum based on the last 30 days of StackOverflow activity relative to total history. Adoption phase (`emerging`/`growing`/`mature`/`declining`) is a lifecycle classification combining star count thresholds and growth rates over a 6-month window. A technology can be `mature` with a `stable` or even `down` trend — that is normal for established technologies.

### Help us improve

If you encounter issues, you can help us debug faster by enabling run sharing in your Apify account:

1. Go to [Account Settings > Privacy](https://console.apify.com/account/privacy)
2. Enable **Share runs with public Actor creators**

This lets us see your run details when something goes wrong, so we can fix issues faster. Your data is only visible to the actor developer, not publicly.

### Support

Found a bug or have a feature request? Open an issue in the [Issues tab](https://console.apify.com/actors/tech-ecosystem-analysis-mcp/issues) on this actor's page. For custom scoring algorithms, additional data sources, or enterprise integrations, reach out through the Apify platform.

# Actor input Schema

## `port` (type: `integer`):

Port number for the MCP SSE server.

## Actor input object example

```json
{
  "port": 3054
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/tech-ecosystem-analysis-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/tech-ecosystem-analysis-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call ryanclinton/tech-ecosystem-analysis-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/tech-ecosystem-analysis-mcp",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Tech Ecosystem Analysis MCP",
        "description": "Technology intelligence for mapping tech ecosystems, tracking adoption trends, detecting vulnerabilities, and analyzing developer sentiment.",
        "version": "1.0",
        "x-build-id": "Hat8UNXt9nXGGYPaI"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ryanclinton~tech-ecosystem-analysis-mcp/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ryanclinton-tech-ecosystem-analysis-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ryanclinton~tech-ecosystem-analysis-mcp/runs": {
            "post": {
                "operationId": "runs-sync-ryanclinton-tech-ecosystem-analysis-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ryanclinton~tech-ecosystem-analysis-mcp/run-sync": {
            "post": {
                "operationId": "run-sync-ryanclinton-tech-ecosystem-analysis-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "port": {
                        "title": "MCP Server Port",
                        "minimum": 1024,
                        "maximum": 65535,
                        "type": "integer",
                        "description": "Port number for the MCP SSE server.",
                        "default": 3054
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
