A Model Control Protocol (MCP) server providing field-level access to ecosyste.ms package ecosystem data. Connect this server to Claude Desktop, Claude Code, ChatGPT, or any MCP-compatible LLM to build package analysis workflows using raw data.
get_package_basic_info - Basic package info (id, name, ecosystem, description, homepage, licenses)get_package_dates - Creation and update datesget_package_repository_info - Repository URL and social metrics (stars, forks)get_package_versions_info - Version count and latest release infoget_package_keywords - Keywords and categoriesget_package_urls - Ecosyste.ms URLs and related linksget_package_metrics - Downloads, dependents, stars, forks, rankings, maintainersget_funding_links - Funding linksget_latest_version - Latest version informationget_version_info - Specific version metadata (published_at, downloads, author, checksum, size)get_version_dependencies - Dependencies for a specific version (requires PURL with version)get_package_dependencies - Dependencies for latest versionget_package_versions - Complete version list with paginationget_package_version_numbers - Simple version number list (lightweight)get_related_packages - Related packages with paginationget_dependent_packages - Packages that depend on this oneget_package_maintainers - Maintainer list with detailsget_maintainer_packages - Packages by a specific maintainerget_version_urls - URLs for specific version analysisAll repository tools accept either direct URLs (e.g. github.com/numpy/numpy) or PURLs (e.g. pkg:pypi/numpy). When given a PURL, the tool resolves the package's repository URL automatically.
get_repo_basic_info - Basic info (id, full_name, owner, description, archived, fork)get_repo_activity - Activity metrics (pushed_at, size, last_synced_at)get_repo_community - Community metrics (stars, forks, subscribers, open_issues)get_repo_metadata - Metadata (topics, language, license, default_branch)get_repo_dependencies - Dependencies from manifest files (Gemfile, package.json, etc.)get_repo_metafiles - Interesting metadata files (LICENSE, README, etc.)get_repo_files - Complete file list via archives APIget_repo_file_contents - Specific file contents via archives APIget_repo_readme - README content via archives APIget_repo_changelog - Changelog with parsed version entriesget_repo_repomix - AI-friendly concatenated repository contentsget_repo_tags - Tags with paginationget_repo_releases - Releases with paginationget_repo_sbom - Software Bill of Materialsget_repo_owner - Owner informationget_repo_scorecard - Security scorecardget_repo_urls - Ecosyste.ms URLs across all platformsget_repo_package_names - Package names associated with a repositoryget_issue_counts - Issue and PR counts (total, closed)get_issue_timing - Average time to close issues and PRsget_maintainer_info - Maintainer lists (all-time and active)get_contributor_counts - Contributor counts for PRs and issuesget_past_year_activity - Past year issue and PR activityget_commit_overview - Repository commit overviewget_committer_list - Complete list of committers with countsget_top_committers - Top N committers by countget_vulnerability_list - Detailed vulnerability list with CVE detailsget_vulnerability_counts_by_severity - Counts grouped by severityget_latest_vulnerability_date - Date of most recent vulnerabilityget_registry_list - All available package registriesAdd to your claude_desktop_config.json:
{
"mcpServers": {
"ecosystems": {
"command": "curl",
"args": [
"-X", "POST",
"http://localhost:3000/mcp",
"-H", "Content-Type: application/json",
"-d", "@-"
]
}
}
}
Start the server first with rails server, then add it:
claude mcp add ecosystems http://localhost:3000/mcp -t http
Or add manually to your Claude Code settings:
{
"mcp.servers": {
"ecosystems": {
"url": "http://localhost:3000/mcp"
}
}
}
Create a GPT Action with this OpenAPI spec:
openapi: 3.0.0
info:
title: Ecosystems MCP Server
version: 1.0.0
servers:
- url: http://localhost:3000
paths:
/mcp:
post:
operationId: callMcpTool
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
jsonrpc:
type: string
default: "2.0"
method:
type: string
enum: ["tools/list", "tools/call"]
params:
type: object
responses:
'200':
description: MCP response
Connect to http://localhost:3000/mcp using JSON-RPC 2.0. Methods: tools/list, tools/call.
git clone https://github.com/ecosyste-ms/mcp-server
cd mcp-server
bundle install
rails server
Test it:
# Health check
curl http://localhost:3000/mcp/health
# List available tools
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
# Analyze a package
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "assess_importance", "arguments": {"purl": "pkg:pypi/numpy"}}}'
Run these commands from the repository root with Docker running. The image runs Rails and needs a PostgreSQL database. The example keeps database files in a named volume and binds the HTTP port to localhost.
docker build -t ecosystems-mcp .
docker network create ecosystems-mcp
docker volume create ecosystems-mcp-data
export DATABASE_PASSWORD="$(openssl rand -hex 32)"
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
docker run -d --name ecosystems-mcp-db \
--network ecosystems-mcp --restart unless-stopped \
-e POSTGRES_USER=mcp \
-e POSTGRES_PASSWORD="$DATABASE_PASSWORD" \
-e POSTGRES_DB=mcp_production \
-v ecosystems-mcp-data:/var/lib/postgresql/data \
postgres:17
docker run -d --name ecosystems-mcp-app \
--network ecosystems-mcp --restart unless-stopped \
-p 127.0.0.1:3000:3000 \
-e RAILS_ENV=production \
-e SECRET_KEY_BASE \
-e DATABASE_HOST=ecosystems-mcp-db \
-e DATABASE_USERNAME=mcp \
-e DATABASE_PASSWORD \
ecosystems-mcp
Save the generated secrets securely before leaving the shell. Reuse them when recreating containers; changing POSTGRES_PASSWORD does not change the password in an existing database volume. The startup script waits for PostgreSQL, creates mcp_production if needed, and runs migrations before starting Rails on port 3000.
For an existing PostgreSQL server, skip the database container and set DATABASE_HOST, DATABASE_USERNAME, and DATABASE_PASSWORD to its connection details. Set DATABASE_PORT if it differs from 5432. The database user needs permission to create mcp_production if it does not exist, and to run migrations. To send an ecosyste.ms API key with upstream requests, export ECOSYSTEMS_API_KEY and add -e ECOSYSTEMS_API_KEY to the application command.
Check startup logs and the HTTP endpoints:
docker logs -f ecosystems-mcp-app
Once Rails is listening, run these in another terminal:
curl --fail http://localhost:3000/mcp/health
curl --fail http://localhost:3000/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The health response should contain "status":"healthy", and the JSON-RPC response should contain result.tools. Local clients can connect to http://localhost:3000/mcp. For remote hosting, put an HTTPS reverse proxy in front of port 3000 and use its /mcp URL. Production mode assumes TLS terminates at that proxy and sets secure cookies and HSTS headers. Restrict access at the proxy as needed, including /mcp/admin, which exposes tool-call logs without application authentication.
To stop and start the containers without removing database files:
docker stop ecosystems-mcp-app ecosystems-mcp-db
docker start ecosystems-mcp-db ecosystems-mcp-app
Once connected, try these:
Analyze numpy's dependencies and vulnerabilities
Use the MCP tools to:
1. Get basic info for pkg:pypi/numpy
2. Get its latest dependencies
3. Check vulnerability counts by severity
4. Show the top 5 committers for the numpy/numpy repository
Compare packages across ecosystems
Compare package metadata between:
- pkg:pypi/requests (Python)
- pkg:npm/axios (Node.js)
- pkg:cargo/reqwest (Rust)
Use tools to get basic info, repository metrics, and latest versions for each.
Analyze repository activity
For github.com/microsoft/vscode:
1. Get repository community metrics
2. Get dependencies from manifest files
3. Get issue counts and timing
4. Show maintainer information
Dependency tree analysis
Get dependencies for pkg:cargo/tokio and then analyze the dependencies
of its top 3 normal (non-dev) dependencies using the version-specific tools.
Explore repository files
For github.com/numpy/numpy:
1. Get metadata files using get_repo_metafiles
2. Get complete file list using get_repo_files
3. Get README content using get_repo_readme
4. Get changelog with parsed versions using get_repo_changelog
5. Get AI-friendly concatenated codebase using get_repo_repomix
6. Get contents of specific files using get_repo_file_contents
The server consists of three main components:
SimpleMcpServer handles the JSON-RPC 2.0 protocol. EcosystemsClient wraps the ecosyste.ms APIs with 24-hour caching. PackageInfoService handles data extraction and normalization.
API endpoints used:
packages.ecosyste.ms - Package metadata, versions, dependencies via PURL lookupsrepos.ecosyste.ms - Repository metadata, manifests, dependency analysisadvisories.ecosyste.ms - Vulnerability data with CVE detailsissues.ecosyste.ms - Issue tracking, maintainer activity, PR metricscommits.ecosyste.ms - Commit activity, contributor analysisCaching uses Rails.cache with a 24-hour TTL. Cache keys are MD5 hashes of the URL. Cache misses are logged for monitoring.
# Unit tests
ruby -I test test/unit/services/
# Integration tests (requires network)
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/
# Specific integration tests
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/csv_workflow_test.rb
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/mcp_endpoint_test.rb
Manual testing:
curl http://localhost:3000/mcp/health
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "get_authors", "arguments": {"purl": "pkg:pypi/numpy"}}}'
Not currently planned, but could be interesting:
Contact ecosyste.ms about funding development of these.
get_unpatched_vulnerabilities and analyze_security_posture return placeholder responses. They show what could be built with additional data sources.
A Model Control Protocol (MCP) server providing field-level access to ecosyste.ms package ecosystem data. Connect this server to Claude Desktop, Claude Code, ChatGPT, or any MCP-compatible LLM to build package analysis workflows using raw data.
get_package_basic_info - Basic package info (id, name, ecosystem, description, homepage, licenses)get_package_dates - Creation and update datesget_package_repository_info - Repository URL and social metrics (stars, forks)get_package_versions_info - Version count and latest release infoget_package_keywords - Keywords and categoriesget_package_urls - Ecosyste.ms URLs and related linksget_package_metrics - Downloads, dependents, stars, forks, rankings, maintainersget_funding_links - Funding linksget_latest_version - Latest version informationget_version_info - Specific version metadata (published_at, downloads, author, checksum, size)get_version_dependencies - Dependencies for a specific version (requires PURL with version)get_package_dependencies - Dependencies for latest versionget_package_versions - Complete version list with paginationget_package_version_numbers - Simple version number list (lightweight)get_related_packages - Related packages with paginationget_dependent_packages - Packages that depend on this oneget_package_maintainers - Maintainer list with detailsget_maintainer_packages - Packages by a specific maintainerget_version_urls - URLs for specific version analysisAll repository tools accept either direct URLs (e.g. github.com/numpy/numpy) or PURLs (e.g. pkg:pypi/numpy). When given a PURL, the tool resolves the package's repository URL automatically.
get_repo_basic_info - Basic info (id, full_name, owner, description, archived, fork)get_repo_activity - Activity metrics (pushed_at, size, last_synced_at)get_repo_community - Community metrics (stars, forks, subscribers, open_issues)get_repo_metadata - Metadata (topics, language, license, default_branch)get_repo_dependencies - Dependencies from manifest files (Gemfile, package.json, etc.)get_repo_metafiles - Interesting metadata files (LICENSE, README, etc.)get_repo_files - Complete file list via archives APIget_repo_file_contents - Specific file contents via archives APIget_repo_readme - README content via archives APIget_repo_changelog - Changelog with parsed version entriesget_repo_repomix - AI-friendly concatenated repository contentsget_repo_tags - Tags with paginationget_repo_releases - Releases with paginationget_repo_sbom - Software Bill of Materialsget_repo_owner - Owner informationget_repo_scorecard - Security scorecardget_repo_urls - Ecosyste.ms URLs across all platformsget_repo_package_names - Package names associated with a repositoryget_issue_counts - Issue and PR counts (total, closed)get_issue_timing - Average time to close issues and PRsget_maintainer_info - Maintainer lists (all-time and active)get_contributor_counts - Contributor counts for PRs and issuesget_past_year_activity - Past year issue and PR activityget_commit_overview - Repository commit overviewget_committer_list - Complete list of committers with countsget_top_committers - Top N committers by countget_vulnerability_list - Detailed vulnerability list with CVE detailsget_vulnerability_counts_by_severity - Counts grouped by severityget_latest_vulnerability_date - Date of most recent vulnerabilityget_registry_list - All available package registriesAdd to your claude_desktop_config.json:
{
"mcpServers": {
"ecosystems": {
"command": "curl",
"args": [
"-X", "POST",
"http://localhost:3000/mcp",
"-H", "Content-Type: application/json",
"-d", "@-"
]
}
}
}
Start the server first with rails server, then add it:
claude mcp add ecosystems http://localhost:3000/mcp -t http
Or add manually to your Claude Code settings:
{
"mcp.servers": {
"ecosystems": {
"url": "http://localhost:3000/mcp"
}
}
}
Create a GPT Action with this OpenAPI spec:
openapi: 3.0.0
info:
title: Ecosystems MCP Server
version: 1.0.0
servers:
- url: http://localhost:3000
paths:
/mcp:
post:
operationId: callMcpTool
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
jsonrpc:
type: string
default: "2.0"
method:
type: string
enum: ["tools/list", "tools/call"]
params:
type: object
responses:
'200':
description: MCP response
Connect to http://localhost:3000/mcp using JSON-RPC 2.0. Methods: tools/list, tools/call.
git clone https://github.com/ecosyste-ms/mcp-server
cd mcp-server
bundle install
rails server
Test it:
# Health check
curl http://localhost:3000/mcp/health
# List available tools
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
# Analyze a package
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "assess_importance", "arguments": {"purl": "pkg:pypi/numpy"}}}'
Run these commands from the repository root with Docker running. The image runs Rails and needs a PostgreSQL database. The example keeps database files in a named volume and binds the HTTP port to localhost.
docker build -t ecosystems-mcp .
docker network create ecosystems-mcp
docker volume create ecosystems-mcp-data
export DATABASE_PASSWORD="$(openssl rand -hex 32)"
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
docker run -d --name ecosystems-mcp-db \
--network ecosystems-mcp --restart unless-stopped \
-e POSTGRES_USER=mcp \
-e POSTGRES_PASSWORD="$DATABASE_PASSWORD" \
-e POSTGRES_DB=mcp_production \
-v ecosystems-mcp-data:/var/lib/postgresql/data \
postgres:17
docker run -d --name ecosystems-mcp-app \
--network ecosystems-mcp --restart unless-stopped \
-p 127.0.0.1:3000:3000 \
-e RAILS_ENV=production \
-e SECRET_KEY_BASE \
-e DATABASE_HOST=ecosystems-mcp-db \
-e DATABASE_USERNAME=mcp \
-e DATABASE_PASSWORD \
ecosystems-mcp
Save the generated secrets securely before leaving the shell. Reuse them when recreating containers; changing POSTGRES_PASSWORD does not change the password in an existing database volume. The startup script waits for PostgreSQL, creates mcp_production if needed, and runs migrations before starting Rails on port 3000.
For an existing PostgreSQL server, skip the database container and set DATABASE_HOST, DATABASE_USERNAME, and DATABASE_PASSWORD to its connection details. Set DATABASE_PORT if it differs from 5432. The database user needs permission to create mcp_production if it does not exist, and to run migrations. To send an ecosyste.ms API key with upstream requests, export ECOSYSTEMS_API_KEY and add -e ECOSYSTEMS_API_KEY to the application command.
Check startup logs and the HTTP endpoints:
docker logs -f ecosystems-mcp-app
Once Rails is listening, run these in another terminal:
curl --fail http://localhost:3000/mcp/health
curl --fail http://localhost:3000/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The health response should contain "status":"healthy", and the JSON-RPC response should contain result.tools. Local clients can connect to http://localhost:3000/mcp. For remote hosting, put an HTTPS reverse proxy in front of port 3000 and use its /mcp URL. Production mode assumes TLS terminates at that proxy and sets secure cookies and HSTS headers. Restrict access at the proxy as needed, including /mcp/admin, which exposes tool-call logs without application authentication.
To stop and start the containers without removing database files:
docker stop ecosystems-mcp-app ecosystems-mcp-db
docker start ecosystems-mcp-db ecosystems-mcp-app
Once connected, try these:
Analyze numpy's dependencies and vulnerabilities
Use the MCP tools to:
1. Get basic info for pkg:pypi/numpy
2. Get its latest dependencies
3. Check vulnerability counts by severity
4. Show the top 5 committers for the numpy/numpy repository
Compare packages across ecosystems
Compare package metadata between:
- pkg:pypi/requests (Python)
- pkg:npm/axios (Node.js)
- pkg:cargo/reqwest (Rust)
Use tools to get basic info, repository metrics, and latest versions for each.
Analyze repository activity
For github.com/microsoft/vscode:
1. Get repository community metrics
2. Get dependencies from manifest files
3. Get issue counts and timing
4. Show maintainer information
Dependency tree analysis
Get dependencies for pkg:cargo/tokio and then analyze the dependencies
of its top 3 normal (non-dev) dependencies using the version-specific tools.
Explore repository files
For github.com/numpy/numpy:
1. Get metadata files using get_repo_metafiles
2. Get complete file list using get_repo_files
3. Get README content using get_repo_readme
4. Get changelog with parsed versions using get_repo_changelog
5. Get AI-friendly concatenated codebase using get_repo_repomix
6. Get contents of specific files using get_repo_file_contents
The server consists of three main components:
SimpleMcpServer handles the JSON-RPC 2.0 protocol. EcosystemsClient wraps the ecosyste.ms APIs with 24-hour caching. PackageInfoService handles data extraction and normalization.
API endpoints used:
packages.ecosyste.ms - Package metadata, versions, dependencies via PURL lookupsrepos.ecosyste.ms - Repository metadata, manifests, dependency analysisadvisories.ecosyste.ms - Vulnerability data with CVE detailsissues.ecosyste.ms - Issue tracking, maintainer activity, PR metricscommits.ecosyste.ms - Commit activity, contributor analysisCaching uses Rails.cache with a 24-hour TTL. Cache keys are MD5 hashes of the URL. Cache misses are logged for monitoring.
# Unit tests
ruby -I test test/unit/services/
# Integration tests (requires network)
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/
# Specific integration tests
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/csv_workflow_test.rb
RUN_INTEGRATION_TESTS=1 ruby -I test test/integration/mcp_endpoint_test.rb
Manual testing:
curl http://localhost:3000/mcp/health
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "get_authors", "arguments": {"purl": "pkg:pypi/numpy"}}}'
Not currently planned, but could be interesting:
Contact ecosyste.ms about funding development of these.
get_unpatched_vulnerabilities and analyze_security_posture return placeholder responses. They show what could be built with additional data sources.