Model Context Protocol (MCP) server - napistu/napistu GitHub Wiki

Napistu has a Model Context Protocol (MCP) server which allows AI tools to easily comb through its documentation, codebase, and call key functions.

🌐 Production MCP Server

A documentation server is deployed to Google Cloud Run as part of our Github Actions Workflows. Cursor, Claude and other GenAI tools can be directly configured to use this service.

The service is available at: https://napistu-mcp-server-844820030839.us-west1.run.app

A json config which works for Claude Desktop and Cursor is:

{
    "mcpServers": {
      "napistu": {
        "command": "npx", 
        "args": ["mcp-remote", "https://napistu-mcp-server-844820030839.us-west1.run.app/mcp/"]
      }
    }
  }

Creating local MCP servers or clients.

The core functionality for creating and querying MCP servers is included in the napistu.mcp subpackage which can be installed with:

uv pip install 'napistu[mcp]'

A FastMCP server or client can then be created using the napistu.mcp CLI. Here are some useful commands; detailed documentation can be found below.

# Start full development server (all components)
python -m napistu.mcp server full

# Quick health check on local development server (in another terminal)
python -m napistu.mcp health --url http://127.0.0.1:8765

# Quick health check on the remote docs server
python -m napistu.mcp health --url https://napistu-mcp-server-844820030839.us-west1.run.app

Components

Napistu MCP server functionality is divided into multiple components which can be included or excluded from a given server:

codebase describes the modules, functions, and classes in the napistu-py package. This information is extracted from the Napistu Read the Docs site. We elected to use this approach over indexing a local codebase (e.g., with Sphinx) because Napistu is a multi repository project and it may be annoying to pull the codebase into the same place in the future. The current approach is quick (runs in under a minute) and will allow us to index multiple packages within or outside the Napistu project (e.g., we could index igraph).

documentation aggregates the major sources of documentation for the project

  • READMEs - directly read as markdown from GitHub raw urls
  • Issues & PRs - read using the GitHub Python package from all project repositories
  • Wiki - loads the markdown pages from this Wiki

execution is meant to access and modify a user's Python environment. The scope and utility of this functionality is still being evaluated. Minimally, this could involve registering an sbml_dfs object and easily querying its attributes and structure. e.g., what species is BRCA. More ambitiously, we could expose methods for querying network graphs to support automated scientists.

tutorials indexes the Jupyter notebooks in tutorials. This involves downloading notebooks from raw GitHub urls and reading them as markdown using nbformat. Notebooks are cached locally in a napistu_data directory. This approach was used over reading local files because the mcp server can be run with just that napistu-py package and this approach avoids the need to clone the napistu repository into the serving environment.

health provides server monitoring and diagnostics capabilities. This component is always enabled and monitors the status of all other components. It exposes a napistu://health resource that returns JSON with overall server status, individual component health, timestamp, and version information. The health component initializes last and performs status checks on all enabled components to ensure they loaded properly.

Profiles

Different use cases will require different subsets of components. The components to include in an MCP server are defined in the napistu.mcp.profile.ServerProfile. A profile can be generated using napistu.mcp.profile.get_profile which takes a profile name and overrides as arguments. Profile names ("local" (execution), "remote" (codebase + documentation + tutorials), and "full" (codebase + documentation + execution + tutorials) provide basic templates while the overrides (e.g., enable_documentation) allow for further configuration.

The three main use cases we're supporting with MCP server are:

  • local - this functionality is in early development but it could enable agents to access and modify user's Python environments.
  • remote - hosts the live Cloud Run server serving Napistu documentation to AI agents and research tools.
  • full - combines all components for comprehensive local development and testing.

Setting up a Server

Registering components

napistu.mcp.server.create_server uses an napistu.mcp.profile.ServerProfile and FastMCP settings (e.g., host and port) to create a fastmcp.FastMCP object. Then, resources and tools for each of the components are registered so they are accessible by the MCP server. Resources and tools are defined in a register_components function in each components module (e.g., documentation.register_components(mcp) would register the documentation components. Individual components can be quite diverse, but the two categories used by Napistu are:

resources registers API endpoints For example, get_module_details registers an endpoint, "napistu://codebase/modules/{module_name}", which can be used to query module-level information.

tools behave much more likely standard Python functions. Most take an argument like as function_name and read from global dictionaries pull out relevant information. The globals that are used are:

  • component-level dicts storing results from component initialization (see below). For example, _codebase_cache contains a dict for modules, classes and functions which can be accessed during resource registration and on-the-fly tool use.
  • _session_context used by the execution component to access functions by name
  • _session_object used by the execution component to access object

Initializing components

Having defined what the server can do during component registration, napistu.mcp.server.initialize_components will now use the ServerProfile to populate the component-level caches of the enabled components. This is done by calling the initialize_components function for each enabled component. As an example, the initialize_components function for the codebase component looks like:

async def initialize_components() -> bool:
    """
    Initialize codebase components.
    """
    global _codebase_cache

    # Load documentation from the ReadTheDocs API
    _codebase_cache["modules"] = await codebase_utils.read_read_the_docs(NAPISTU_PY_READTHEDOCS_API)

    # Extract functions and classes from the modules
    _codebase_cache["functions"], _codebase_cache["classes"] = codebase_utils.extract_functions_and_classes_from_modules(_codebase_cache["modules"])

    return True

Each component has a separate utility library (e.g., codebase_utils.py) which contains component-level ETL functions.

Command Line Interface

Napistu provides a comprehensive CLI for managing MCP servers and clients through the python -m napistu.mcp command.

Server Commands

Start MCP servers with different configurations:

# Start server with custom profile and settings
python -m napistu.mcp server start --profile full --host 127.0.0.1 --port 8765

# Start local development server (execution components only)
python -m napistu.mcp server local

# Start full development server (all components)
python -m napistu.mcp server full

Client Commands

Test and interact with running MCP servers:

# Quick health check (local)
python -m napistu.mcp health --url http://127.0.0.1:8765

# Quick health check (live Cloud Run server)
python -m napistu.mcp health --url https://napistu-mcp-server-844820030839.us-west1.run.app

# List all available resources
python -m napistu.mcp resources --url http://127.0.0.1:8765

# Read a specific resource
python -m napistu.mcp read "napistu://health" --url http://127.0.0.1:8765

# Read and save resource to file
python -m napistu.mcp read "napistu://codebase/summary" --output codebase.txt

# Compare local and remote servers
python -m napistu.mcp compare --local-url http://127.0.0.1:8765 --remote-url https://napistu-mcp-server-844820030839.us-west1.run.app

Available Resources

The MCP server exposes several resources depending on enabled components:

  • napistu://health - Server health status and component diagnostics
  • napistu://documentation/summary - Aggregated documentation summary
  • napistu://codebase/summary - Codebase structure and API overview
  • napistu://tutorials/index - Available tutorials and notebooks
  • napistu-local://registry - Execution environment registry (local profile)
  • napistu-local://environment - Python environment information (local profile)

Client Library

For programmatic access, Napistu provides client functions in napistu.mcp.client:

from napistu.mcp.client import check_server_health, list_server_resources, read_server_resource

# Health check (live server)
health = await check_server_health("https://napistu-mcp-server-844820030839.us-west1.run.app")
print(f"Server status: {health['status']}")

# List resources
resources = await list_server_resources("http://127.0.0.1:8765")
for resource in resources:
    print(f"Available: {resource.uri}")

# Read specific resource  
content = await read_server_resource("napistu://health", "http://127.0.0.1:8765")

Transport and Protocol

The Napistu MCP server uses FastMCP's streamable-http transport, which implements the MCP protocol over HTTP with Server-Sent Events for streaming responses. The server:

  • Listens on HTTP endpoints (default: http://127.0.0.1:8765 local, production: https://napistu-mcp-server-844820030839.us-west1.run.app)
  • Uses the /mcp/ path for MCP protocol communication
  • Maintains session state for connected clients
  • Supports both JSON-RPC requests and streaming responses

This design allows multiple clients to connect simultaneously and provides compatibility with standard MCP client libraries while supporting advanced streaming capabilities for large responses.

Cloud Run Deployment

The production server runs on Google Cloud Run and is automatically deployed via CI/CD when versions are updated. See the [GitHub Actions documentation](link-to-pipeline-docs) for deployment details.

Troubleshooting

Common Issues

Connection failures: Ensure the server is running and accessible on the specified host/port. The health check command is useful for testing connectivity:

# Local server
python -m napistu.mcp health --url http://127.0.0.1:8765

# Live Cloud Run server
python -m napistu.mcp health --url https://napistu-mcp-server-844820030839.us-west1.run.app

Component initialization errors: Check server logs during startup. Component initialization happens asynchronously and errors are logged with specific component names.

Resource not found: Use the resources command to see available endpoints:

python -m napistu.mcp resources --url https://napistu-mcp-server-844820030839.us-west1.run.app

Development Workflow

For local development and debugging:

  1. Start a full server: python -m napistu.mcp server full
  2. Check health: python -m napistu.mcp health
  3. List available resources: python -m napistu.mcp resources
  4. Test specific functionality: python -m napistu.mcp read "napistu://codebase/summary"

For production deployment, the remote profile runs automatically on Cloud Run. See the [CI/CD documentation](link-to-pipeline-docs) for deployment details.