Science MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Science MCPlook up OrbDot and show its direct dependencies"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Science MCP
A local Python MCP server for ecosyste.ms Science. It searches software names, looks up identifiers, and reads descriptions, languages, package metadata, and dependencies through the Science API. Metadata extraction stays in Science.
Run locally
Install Python and uv, then run from this checkout:
uv sync --locked
uv run --locked science-mcpThe server communicates over stdio and waits for an MCP client. Set SCIENCE_API_URL to use another API base, such as a local Science instance. The default is https://science.ecosyste.ms/api/v1.
No local database or catalogue download is required. API lookup and search use Science's /software/lookup and /software/search endpoints; the service operator must deploy these routes and populate the search fields before they can return results. An HTTP 404 from either route means it is unavailable on the configured service.
Related MCP server: devenv-cache
Tools
Tool | What it returns |
| Exact matches for a name, DOI, repository URL, homepage URL, or PURL |
| Names containing at least three characters, including aliases and package names |
| One page of live search seeds, with the next page number |
| Live project summary, or a page of published packages or direct dependencies |
Start with lookup_software(query="orbdot") or search_software(query="orbit"), then pass a returned project_id to get_project_context. Use section="packages" or section="direct_dependencies" for details. Follow next_offset with the same section and project.
API lookup and search return matching evidence grouped in projects. Preserve those sources and any competing identities. Follow next_after_id using the same query and kind until it is null; the API cursor is a project ID. Names use lowercase Unicode NFC, DOI URLs are accepted, and URL paths retain case. API PURL lookup removes versions and subpaths. Search matches literal substrings without fuzzy matching or confidence scores.
A missing match is not proof that software is absent from Science. Live responses include retrieval time and source timestamps; index updates are asynchronous and pagination can change as metadata changes. Direct dependencies are project-level observations and do not imply that every package published by the project has those dependencies.
Tool pages contain at most 25 matches or context items, and seed pages at most 10 projects. Long text and nested arrays have explicit truncations entries. Serialized result data is limited to 64 KiB; a larger result returns an error asking for a smaller page. The API still returns the full context to the adapter before it selects a page. Requests have a 15-second socket timeout and a 10 MiB response limit.
Connect a client
Replace the absolute paths below. Use the full path to uv if the client cannot find it. These commands register the server in the chosen client's configuration.
For Claude Code:
claude mcp add --transport stdio --scope user science \
-- uv run --directory /absolute/path/to/science-mcp --locked science-mcpFor Codex:
codex mcp add science \
-- uv run --directory /absolute/path/to/science-mcp --locked science-mcpRestart the client session, then ask it to look up OrbDot and retrieve its project context. Each client starts its own stdio server process with the same tools.
Optional local snapshot
Set SCIENCE_SEEDS_DB only if you want lookup_software to read a fixed SQLite export instead of the API. Search and context tools still use the live API. There is no published snapshot download yet; creating an export requires a Science checkout with a populated local PostgreSQL database and its Ruby dependencies installed. See Science development setup and the export guide.
From the Science checkout, using its rbenv Ruby installation:
RBENV_VERSION="$(cat .ruby-version)" /opt/homebrew/bin/rbenv exec bundle exec ruby --version
OUTPUT=tmp/search-seeds.sqlite3 RBENV_VERSION="$(cat .ruby-version)" /opt/homebrew/bin/rbenv exec bundle exec rake search_seeds:exportThe task prints a JSON summary with the output path and counts. It refuses to overwrite an existing file. Add LIMIT=1000 for a small preview, or omit it for the full eligible catalogue. An empty local Science database produces no useful lookup data; the MCP server does not import the public catalogue into it.
Keep the completed file at a stable path, then verify it from the MCP checkout:
mkdir -p "$HOME/.local/share/science"
cp /absolute/path/to/science/tmp/search-seeds.sqlite3 "$HOME/.local/share/science/search-seeds.sqlite3"
SCIENCE_SEEDS_DB="$HOME/.local/share/science/search-seeds.sqlite3" uv run --locked python scripts/smoke.pyFor a client, add --env SCIENCE_SEEDS_DB=/absolute/path/to/search-seeds.sqlite3 before -- in its registration command above and restart the client session. Both schema versions 1 and 2 are supported, and the file is opened read-only. A configured but missing or invalid file returns an error instead of switching sources.
Snapshot lookup returns matches as evidence rows, with a row ID cursor, snapshot ID, completion time, and selection rules. Several rows may describe the same project. Keep the same file throughout pagination; snapshot PURLs must be supplied in canonical versionless form. To refresh, export to a new filename, update the client's configured path, and restart its session. Unset SCIENCE_SEEDS_DB to return to API lookup.
Checks
uv run --locked python -m unittest discover -s tests -v
uv run --locked ruff check src tests scripts
uv run --locked ruff format --check src tests scripts
uv run --locked python scripts/smoke.pyThe tests start stdio subprocesses and a local HTTP fixture server. CI runs the suite on Python 3.11 through 3.14, with Ruff and zizmor checks. Dependabot checks Python dependencies and GitHub Actions weekly. The smoke script makes read-only requests to the configured Science API and, when configured, queries the local snapshot.
Released under the MIT License.
Available Tools
4 toolsget_project_contextARead-onlyIdempotent
Read live Science context for one project.
Summary returns descriptions, languages and counts. Choose packages or direct_dependencies for paginated details. Empty dependencies with a null indexing timestamp mean unknown coverage. Dependencies belong to the project, not necessarily to every package it publishes. Inspect truncations for omitted text.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| section | No | summary | |
| project_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds real behavioral context beyond them: empty dependencies with a null indexing timestamp mean unknown coverage, dependencies belong to the project but not necessarily every package, and truncations should be inspected for omitted text. These are non-obvious caveats an agent would otherwise miss.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then compact sentences covering sections, empty-result semantics, ownership scope, and truncation. No filler, though the fragment style makes it slightly terse rather than flowing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return burden and does so reasonably: it names the summary contents (descriptions, languages, counts) and flags truncation and unknown-coverage cases. It stops short of explaining limit/offset behavior, but the essentials for correct invocation are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning, and it partially does by explaining the three section values and that packages/direct_dependencies are paginated. It says nothing about limit/offset ranges or the project_id semantics, leaving meaningful gaps at 0% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read live Science context for one project'), which clearly separates it from the software search/lookup siblings and the project-listing sibling. It is clear what the tool does, though it never explicitly names a sibling as an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete routing guidance for the section parameter ('Choose packages or direct_dependencies for paginated details'), which tells the agent when to pick each mode. It lacks explicit when-not-to-use guidance or a named alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_seed_projectsARead-onlyIdempotent
Read one small page from Science's live seed API.
This browses the catalogue; it does not search names. Follow next_page with the same per_page. Live pagination is not a frozen snapshot.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| per_page | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, openWorld and non-destructive, so the safety profile is handled. The description adds genuinely new behavioral context: the source is live and 'Live pagination is not a frozen snapshot,' warning that page contents can shift between calls. It stops short of describing result shape or pagination cursor semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Six short lines, front-loaded with the core action and scoping constraint, with no filler sentences. The terseness borders on cryptic ('seed API,' 'next_page') but every sentence aims at real caller behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read-only list tool the description is largely adequate, and annotations cover safety. However, with no output schema it should clarify the pagination contract (what 'next_page' is and where it comes from) and it leaves both parameters' semantics unstated, leaving the caller to infer how to walk pages reliably.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both parameters, so the description should carry the load, and it mostly does not – it never explains page or per_page ranges/defaults, only hinting that pages should be 'small'. Worse, it instructs the caller to 'Follow next_page,' a field that does not exist among the declared parameters and is undocumented anywhere, risking confusion about how to paginate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete verb+resource – reading one page of a 'seed API' catalogue – and explicitly contrasts with searching ('does not search names'), which helps separate it from the search_software sibling. It is clear but never quite names itself as a listing/browsing tool in a way that fully maps to 'list_seed_projects'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives the selecting condition ('This browses the catalogue; it does not search names'), implicitly routing search intent to search_software, and tells the caller how to continue ('Follow next_page with the same per_page'). No sibling is named explicitly, so the routing is implicit rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_softwareBRead-onlyIdempotent
Find exact software names or identifiers using Science's API.
No local database is needed. API results group matching evidence by project; follow next_after_id with the same query and kind. Names are case insensitive. If SCIENCE_SEEDS_DB is set, use that snapshot instead: results are evidence rows and its cursor is a row ID. Keep the same source throughout pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | name | |
| limit | No | ||
| query | Yes | ||
| after_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld). The description adds genuinely useful behavior beyond that: pagination must reuse the same query/kind, names are case-insensitive, results are grouped by project, and the cursor meaning differs per source. It stops short of describing return fields or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded, leading with the core purpose before the source/pagination caveats. Every sentence carries information, though the 'Science's API' phrasing is slightly awkward and the pagination/source rules could be grouped more tightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does some of the return-value work (evidence rows grouped by project, cursor is a row ID). But it omits the shape of an evidence row and any field names, leaving the agent partially blind on results despite the solid coverage of pagination mechanics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across four parameters, so the description must carry the load. It hints at 'query' and 'kind' and refers to the cursor only as 'next_after_id' (the actual parameter is 'after_id'), never explains 'limit' or its 25 max, and never enumerates the kind values (doi, repository_url, homepage_url, purl), which an agent needs to invoke correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: find exact software names or identifiers via the Science API. The word 'exact' implicitly separates it from the sibling search_software (a fuzzy search), but the description never names or contrasts that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives conditional guidance for choosing a source: 'If SCIENCE_SEEDS_DB is set, use that snapshot instead' and 'Keep the same source throughout pagination.' However, there is no explicit when-to-use-this-vs-search_software guidance, which is the most likely agent decision point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_softwareARead-onlyIdempotent
Search Science for names containing at least three characters.
Searches project names, aliases and published package names. Results contain matching evidence grouped by project, not relevance or confidence scores. Follow next_after_id with the same query. Always uses the live API.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| after_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/open-world/destructive, so the description's value-add is the disclosure that results are 'grouped by project, not relevance or confidence scores' and that the tool 'Always uses the live API' — genuinely useful expectations about output shape and freshness. One wrinkle: it tells the agent to follow 'next_after_id', while the schema parameter is named 'after_id', which could confuse pagination handling if the response field name differs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then scope, then result shape, then pagination — a logical order with no filler. Slightly choppy as four short sentences, and the live-API note is tacked on at the end rather than integrated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully characterizes the return (evidence grouped by project) and pagination, and annotations cover the safety profile. Remaining gaps — limit behavior, the after_id/next_after_id naming, and no sibling routing — keep it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It does explain the query constraint ('at least three characters' matching minLength=3) and what query is matched against, plus how to page, but it says nothing about limit (default 10, max 25) or what after_id actually is. Partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete verb+resource (search project names, aliases, and published package names) and disambiguates the search scope from a name lookup. However, it never names or contrasts itself with the sibling lookup_software, so the agent must infer that this is the fuzzy/partial search while lookup_software is the exact one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'Search ... for names' and there is useful pagination guidance ('Follow next_after_id with the same query'), but there is no explicit when-to-use vs lookup_software or when-not-to-use guidance. The agent gets the how-to-continue but not the routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
get_project_context - First observed
list_seed_projects - First observed
lookup_software - First observed
search_software
TDQS
Scored across 4 tools
search_software (substring/name search) and lookup_software (exact name or identifier) both retrieve software and could momentarily be confused, but the descriptions clearly distinguish fuzzy name search from exact lookup. list_seed_projects (catalogue browsing) and get_project_context (single-project detail retrieval) are clearly distinct.
All four tools follow a consistent snake_case verb_noun pattern: search_software, lookup_software, list_seed_projects, get_project_context. The verbs are predictable and map cleanly to their operations.
Four tools is a lean but reasonable set for a read-only discovery/lookup service covering search, exact lookup, catalogue listing, and project detail. It is slightly thin but each tool earns its place with a distinct operation.
The surface covers the main lifecycle of a catalogue server: discovery via search/lookup, browsing via seed listing, and detail retrieval via context. It lacks any cross-cutting query or export operation, but for a read-oriented search/lookup domain the core workflows are covered.
Maintenance
Related MCP Connectors
Repository knowledge graph MCP server for codebase understanding and debugging.
Public, read-only MCP server for FarmNeural company facts, packages, and capabilities.
MCP server for hex.pm and hexdocs.pm: search, inspect, compare, and audit Elixir packages
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceLocal-first MCP server for querying multi-repo engineering documentation artifacts from a SQLite corpus.5 npmAGPL 3.0
- FlicenseNot gradedqualityDmaintenanceProvides a local SQLite cache of package documentation and APIs, enabling AI coding assistants to access dependency context offline with sub-10ms latency via MCP.-
- AlicenseNot gradedqualityBmaintenancePrivate, local-first code intelligence MCP server that builds a static graph of repositories and exposes search, architecture, impact analysis, and review tools via MCP.MIT
- AlicenseAqualityAmaintenanceMCP server for local, offline-capable library documentation. It resolves library IDs and retrieves up-to-date docs via hybrid search from a persistent SQLite cache.31MIT