Skip to main content
Glama
ajwann

installed-api

.---------------------------------------.
|                                       |
|             _            _            |
|            / )          ( \           |
|           | |            | |          |
|          _| |     __     | |_         |
|         (_  |    (__)    |  _)        |
|           | |            | |          |
|           | |_          _| |          |
|     \\     \__)        (__/     //    |
|      \\                        //     |
|       \\__                  __//      |
|       |   ''--..      ..--''   |      |
|       |         ''--''         |      |
|       |           ||           |      |
|       |           ||           |      |
|       |           ||           |      |
|       '--..       ||       ..--'      |
|            ''--.. || ..--''           |
|                 ''--''                |
|                                       |
'---------------------------------------'

installed-api

tests version license Anthropic Directory

Stop letting your agent guess at APIs. Ask the code you actually installed.

installed-api is a Claude Code plugin (an MCP server, Python standard library only) that answers "what's the signature of X?", "does Y take that argument?" and "which version do we have?" from the packages installed in this project: your .venv, your node_modules. It doesn't answer from training data or from web docs written for some other version.

Why your Claude Code install needs this

The model's memory doesn't know your lockfile. Training data is a blend of many versions of every library, and web docs describe latest. Your project pins one specific version. That gap produces invented keyword arguments, calls to methods that were renamed two releases ago, wrong defaults, and then a round of run, read the traceback, fix, run again.

Looking it up the hard way burns tokens. When Claude isn't sure, it falls back to grepping site-packages or node_modules, cat-ing whole modules or bundled .d.ts files, or fetching doc pages. All of that text goes into your context window, and you pay for it on every turn after that. installed-api replaces it with one call that returns only the parts that matter.

To be clear about what it doesn't do: it doesn't search or index your own working directory. It saves tokens on looking up dependencies, the code your project calls but didn't write.

Without installed-api

With installed-api

grep -rn "def approx" .venv/ → open _pytest/python_api.py (922 lines, ~36 KB)

py_inspect pytest.approx → ~2 KB: signature, docstring, file:line, pytest 9.1.1

Fetch a docs page for whatever version the site documents

The declaration from the package your project resolves

cat node_modules/some-lib/dist/index.d.ts (often thousands of lines)

node_types some-lib createClient → that declaration with its JSDoc

Guess, run, read the traceback, retry

Correct the first time

The sizes in the first row were measured on one machine. Your savings depend on the library, but the output is always bounded: up to 80 members per inspect, 12,000 characters of source, 80-line declaration blocks, and at most 400 .d.ts files scanned per lookup.

For humans

  • Code that runs against the versions you pinned, not the ones the model remembers.

  • Smaller context, cheaper sessions. Targeted answers instead of whole files dumped into the conversation.

  • Nothing to install or configure. Python 3.11+ standard library only. It finds .venv/venv, $VIRTUAL_ENV, poetry and pdm environments, node_modules and @types/* on its own.

  • Private and read-only. It makes no network requests, sends nothing anywhere, and writes nothing.

  • Tested on Python 3.11 through 3.15 in CI on every push and PR.

For LLM agents reading this

If these tools are available to you, use them in preference to your memory for any third-party API:

  • Before you write a call to a library function or class, call py_inspect (Python) or node_types (JS/TS) on it. Use the returned signature and the installed version. Trust them over what you recall.

  • When the user asks "which version" or you're about to suggest version-specific code, call py_versions / node_versions.

  • When the docstring doesn't settle how something behaves, call py_source instead of grepping site-packages or reading whole files.

  • For the user's own package (./src layouts), pass include_project: true.

One call usually answers the question. Results include defined_at / file paths, so you can cite exactly where the answer came from.

Related MCP server: FastAPI Architect MCP

Tools

Tool

What it returns

py_inspect

Signature, docstring, members (for classes and modules), MRO, defining file:line and the distribution version (requests 2.32.3), from the project's own interpreter

py_source

The source of an installed function, class or module

py_versions

name==version for installed distributions matching a pattern

node_types

A symbol's TypeScript declaration with its JSDoc, from node_modules (falling back to @types/*), or a package's version and export list

node_versions

name@version for packages in the nearest node_modules

The interpreter is chosen in this order: .venv / venv (searched upward to the repo root), then $VIRTUAL_ENV, the poetry or pdm env, and finally python3. Python lookups import the target module in a subprocess (python -I), so they run that package's import-time code, as using it would. include_project: true also imports from ./src and ./.

Example (py_inspect with target: "pytest.approx", output trimmed):

{
 "target": "pytest.approx",
 "kind": "function",
 "version": "pytest 9.1.1",
 "defined_at": ".../site-packages/_pytest/python_api.py:646",
 "signature": "(expected: 'Any', rel: 'float | Decimal | timedelta | None' = None, abs: 'float | Decimal | timedelta | None' = None, nan_ok: 'bool' = False) -> 'ApproxBase'",
 "doc": "Assert that two numbers (or two ordered sequences of numbers) are equal to each other\nwithin some tolerance. ..."
}

Supported versions

installed-api supports the Python and Node.js release lines that still receive at least security updates; a line is dropped once it reaches end of life. As of October 2026 that is Python 3.11–3.15 and Node.js 22, 24 and 26. Node.js is never executed: node_types and node_versions read package.json and .d.ts files from node_modules.

Install

In Claude Code:

/plugin install installed-api --marketplace ajwann/installed-api

From Anthropic's plugin directory, once listed: search for installed-api in /plugin directory in Claude Code, or under Customize > Plugins on claude.ai.

To try it from a clone for one session: claude --plugin-dir /path/to/installed-api.

What it runs and stores

It is Python 3.11+ standard library only, makes no network requests, and sends nothing anywhere.

  • Runs the project's Python interpreter (python -I) to import and inspect the module you ask about, which runs that package's import-time code.

  • Reads .d.ts files and package.json under node_modules. It writes nothing.

Development

python3 -m pytest -q
claude plugin validate --strict .

License

MIT. See LICENSE.

Available Tools

5 tools
node_typesA

Read TypeScript declarations of a package installed in node_modules (falls back to @types/*). With symbol: the declaration(s) of that function/class/interface/type with JSDoc and file:line. Without: the package version and its exported names.

NameRequiredDescriptionDefault
symbolNo
packageYes
project_dirNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does substantial work: it discloses the @types/* fallback and the two distinct return shapes (declarations with JSDoc and file:line vs. version plus exported names). Still missing: read-only confirmation, error behavior when a package is not installed, and any size/truncation limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with the core action, then branching cleanly on the optional symbol parameter. No filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description does describe both return shapes reasonably. It falls short on project_dir and on failure modes for a 3-parameter tool, but the essentials needed to call it are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must explain parameters. It defines the symbol parameter's effect well and implies that package refers to an installed package, but project_dir is completely unexplained and its purpose (monorepo root? alternate install dir?) is left to guesswork.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: reading TypeScript declarations of a package installed in node_modules, with the @types fallback named. It is clearly different from py_* siblings and from node_versions, though it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The with/without-symbol branches imply what each mode is for, but there is no explicit when-to-use or when-not-to-use guidance, and no routing to node_versions or py_inspect. The agent must infer the choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

node_versionsB

List packages installed in the nearest node_modules (name@version) whose name contains pattern.

NameRequiredDescriptionDefault
patternNo
project_dirNo

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it usefully discloses two behavioral facts beyond the name: the search starts at the *nearest* node_modules (upward resolution) and results are rendered as name@version. It does not say what happens when no node_modules is found, whether matching is case-sensitive or regex, or how an absent pattern behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero waste, front-loading the verb and resource and packing output format and filter semantics in the same clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read tool with no annotations and no output schema, the description covers purpose, output format, and filter semantics reasonably. The unexplained project_dir and undefined empty-pattern/no-install behaviors leave meaningful gaps an agent would need to guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It does clarify that 'pattern' is a substring match on the package name, but 'project_dir' is left completely undefined — no hint whether it is a start directory, a path to a node_modules, or an absolute vs relative path.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb ('List') plus resource ('packages installed in the nearest node_modules') and even the output shape ('name@version'). It implicitly distinguishes itself from the py_* siblings by naming node_modules, though it never explicitly contrasts with py_versions or node_types.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No statement of when to use this versus py_versions/node_types, and no prerequisites or exclusions. The only usable signal is the implicit ecosystem cue from 'node_modules', leaving the agent to infer the rest.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

py_inspectA

Inspect a Python object as installed in the project's own interpreter: signature, docstring, members (for modules/classes), defining file:line and the installed distribution version. target is a dotted path such as 'requests.Session.request' or 'pandas.DataFrame.merge'.

NameRequiredDescriptionDefault
targetYes
max_membersNo
project_dirNo
include_projectNoalso import from the project's ./src and ./

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses that inspection happens in the project's live interpreter and reports the defining file:line and installed distribution version, but it says nothing about import side effects, failure behavior for unresolvable targets, or the effect of max_members truncation on results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, zero filler, with the scope constraint and return contents front-loaded and the parameter format example trailing as supporting detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description does the required work by enumerating the returned fields (signature, docstring, members, file:line, distribution version). It falls short only on error/truncation behavior for a 4-parameter introspection tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (only include_project is documented), so the description must compensate. It does add real value for `target` by giving dotted-path examples like 'requests.Session.request' and 'pandas.DataFrame.merge', but `max_members` (default 80, truncation semantics) and `project_dir` are left undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (inspect) plus a precise scope: 'a Python object as installed in the project's own interpreter', with an explicit enumeration of what is retrieved (signature, docstring, members, file:line, distribution version). That enumeration implicitly separates it from py_source (source bodies) and py_versions (version listing), but no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'as installed in the project's own interpreter' implies when to use it (runtime introspection of the actually-installed package rather than other environments or source files), but the description never states when not to use it or names py_source/py_versions as the alternative for source-reading or version-listing tasks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

py_sourceC

Return the source code of an installed Python function/class/module (truncated to max_chars).

NameRequiredDescriptionDefault
targetYes
max_charsNo
project_dirNo
include_projectNo

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It mentions truncation (max_chars) and that the target must be installed, but omits whether the operation is read-only (implied), what happens if the target is not found, and other behavioral traits like error handling or return format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with zero waste. It starts with the core action and includes the truncation note without unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and zero schema description coverage for four parameters, the description is far too sparse. It lacks usage guidance and fails to explain two of the four parameters, leaving significant gaps for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It only explains max_chars via '(truncated to max_chars)' and indirectly describes 'target' as an installed Python function/class/module, but leaves project_dir and include_project completely unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Return) and resource (source code) with a clear scope (installed Python function/class/module). It does not explicitly differentiate from siblings like py_inspect, but an agent can infer the distinction without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives such as py_inspect or py_versions. The description only states what it does, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

py_versionsA

List installed Python distributions (name==version) in the project's interpreter whose name contains pattern (empty pattern lists all).

NameRequiredDescriptionDefault
patternNo
project_dirNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full burden. It discloses the important behavioral scope (reads the project's interpreter, not the ambient environment) and the "name==version" output form, but says nothing about failure modes (missing interpreter), cost, or whether output is ordered/filtered further.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence: verb first, parenthetical output format, then the parameter caveat. Nothing wasted and no postamble.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-param read-only listing tool with no output schema, the description covers the core behavior adequately, but leaves one of two parameters (project_dir) and the return shape (list of strings? structure?) undocumented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate: it fully specifies `pattern` (substring match, empty means all). `project_dir` is only obliquely implied by "the project's interpreter" — its purpose, default, and accepted format are never stated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ("List") plus a precise resource ("installed Python distributions") and scope ("in the project's interpreter"). The Python-specific framing clearly separates it from node_versions/node_types siblings, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"empty pattern lists all" is useful call-time guidance for the optional pattern, but there is no when-to-use/when-not guidance and no reference to the sibling tools (py_inspect, py_source, node_versions) that an agent could confuse it with.

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.

  1. 5 tool updatesv0.1.0
    • First observednode_types
    • First observednode_versions
    • First observedpy_inspect
    • First observedpy_source
    • First observedpy_versions

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct resource+action: metadata inspection (py_inspect), raw source (py_source), and version listing (py_versions) for Python; declarations (node_types) and version listing (node_versions) for Node. The py_/node_ split makes cross-language selection unambiguous, and the inspect-vs-source boundary is clear from the descriptions.

Naming Consistency5/5

All five tools follow a strict <lang>_<noun/verb> pattern (py_inspect, py_source, py_versions, node_types, node_versions). Prefixes group by ecosystem and suffixes consistently denote the operation, making the set highly predictable.

Tool Count5/5

Five tools is well-scoped for a dual-ecosystem introspection server: three for Python, two for Node, each earning its place with no redundant members. Nothing feels padded or thin for the stated purpose.

Completeness3/5

The Python side has both metadata inspection and source retrieval, but the Node side only offers type declarations and versions — there is no equivalent of py_source for reading installed JS implementation code. This asymmetry leaves a notable gap for agents debugging Node packages, though version and type coverage is solid.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that publishes CLI tools on your machine for discoverability by LLMs
    5 npm
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    An MCP server that gives Claude Code IDE-level intelligence for FastAPI projects — semantic code navigation, safe renaming, route inspection, dependency trees, and Pydantic model analysis. Instead of Claude reading files blindly, it calls structured tools backed by Jedi (Python language server) and Python's AST.
    19
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A dead simple MCP server for exposing your app functions to AI agents like Claude Desktop.
    5 npm
    6
    MIT