Skip to main content

phpIPAM MCP Server

Python 3.10+ License: MIT Pylint Safety Security Scan Dependency Security Check

Model Context Protocol server for phpIPAM IP address management and network infrastructure.

Installation

Prerequisites

  • Python 3.10+
  • phpIPAM instance with API access
  • App configured in phpIPAM with "SSL with App Code token" security

From PyPI (when published)

pip install phpipam-mcp-server

From Source

git clone https://github.com/InfraMCP/phpipam-mcp-server.git
cd phpipam-mcp-server
pip install -e .

Development Installation

pip install -e ".[dev]"

Usage

The server supports two transports, selected with the MCP_TRANSPORT environment variable:

Transport MCP_TRANSPORT Use case
Local (default) stdio Launched by the MCP client on the same machine
Remote streamable-http Runs as an HTTP service behind a TLS reverse proxy

Local (stdio)

The default transport. The MCP client starts the server as a subprocess, so no MCP_TRANSPORT value is required. Add to your MCP client configuration:

{
  "mcpServers": {
    "phpipam": {
      "command": "phpipam-mcp-server",
      "env": {
        "PHPIPAM_URL": "https://ipam.example.com/",
        "PHPIPAM_APP_ID": "your_app_id",
        "PHPIPAM_APP_CODE": "your_app_code_token"
      }
    }
  }
}

Remote (streaming HTTP)

Set MCP_TRANSPORT=streamable-http to run the server as a long-lived HTTP service that any streamable-http capable MCP client can reach at a URL such as https://phpipam.example.com/mcp. This mode is intended to run behind a reverse proxy that terminates TLS (see DEPLOYMENT.md for a full Docker + Caddy walkthrough).

Key differences from stdio mode:

  • The MCP endpoint is served at MCP_PATH (default /mcp).
  • A static bearer token (MCP_BEARER_TOKEN) protects the endpoint. Clients must send Authorization: Bearer <token>.
  • phpIPAM credentials can be supplied per client via X-phpIPAM-* HTTP headers, falling back to the server-wide PHPIPAM_* environment variables.
  • An unauthenticated /health endpoint is exposed for liveness probes.

Configuration (environment variables):

Variable Default Description
MCP_TRANSPORT stdio Set to streamable-http for remote mode
MCP_HOST 0.0.0.0 Bind address (HTTP mode)
MCP_PORT 8000 Bind port (HTTP mode)
MCP_PATH /mcp Path for the MCP endpoint
MCP_BEARER_TOKEN — Required token for Authorization: Bearer <token>
PHPIPAM_URL — Server-wide phpIPAM URL (fallback)
PHPIPAM_APP_ID — Server-wide phpIPAM App ID (fallback)
PHPIPAM_APP_CODE — Server-wide phpIPAM App Code (fallback)
PHPIPAM_VERIFY_SSL true Verify TLS to phpIPAM

Run it locally:

export MCP_TRANSPORT=streamable-http
export MCP_BEARER_TOKEN="$(openssl rand -hex 32)"
export PHPIPAM_URL="https://ipam.example.com/"
export PHPIPAM_APP_ID="your_app_id"
export PHPIPAM_APP_CODE="your_app_code_token"
phpipam-mcp-server

Generate a strong token with openssl rand -hex 32. Never expose the endpoint over plain HTTP — always place it behind HTTPS.

MCP client configuration (remote):

{
  "mcpServers": {
    "phpipam": {
      "type": "http",
      "url": "https://phpipam.example.com/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_BEARER_TOKEN>",
        "X-phpIPAM-URL": "https://ipam.example.com/",
        "X-phpIPAM-App-Id": "your_app_id",
        "X-phpIPAM-App-Code": "your_app_code_token"
      }
    }
  }
}

If you configure shared phpIPAM credentials on the server (via PHPIPAM_*), omit the X-phpIPAM-* headers and send only Authorization.

Quick test:

# Health check (no auth required)
curl https://phpipam.example.com/health
# -> {"status":"ok"}

# Without a token the MCP endpoint returns 401
curl -i https://phpipam.example.com/mcp

Available Tools

list_sections(include_fields="")

List all IP sections from phpIPAM.

  • include_fields: Comma-separated fields or "all" for complete data

get_section_subnets(section_id, include_usage=True, include_fields="", limit=20)

Get subnets within a specific section.

  • section_id: Section ID to query
  • include_usage: Include usage statistics (default: True)
  • include_fields: Field filtering options
  • limit: Maximum results to return (default: 20, max: 1000)

search_addresses(ip_or_hostname, limit=10)

Search for IP addresses or hostnames.

  • ip_or_hostname: IP address or hostname to search for
  • limit: Maximum results to return (default: 10, max: 1000)

search_hostname(hostname, limit=10)

Search for IP addresses by exact or partial hostname. Supports * wildcards.

  • hostname: Hostname to search for (e.g., server01 or web-*)
  • limit: Maximum results to return (default: 10, max: 50)

get_subnet_details(subnet_id, include_addresses=False, address_limit=10)

Get detailed subnet information.

  • subnet_id: Subnet ID to query
  • include_addresses: Include IP addresses in subnet (default: False)
  • address_limit: Maximum addresses to show (default: 10, max: 1000)

list_vlans(domain_id=None, limit=20)

List VLANs from phpIPAM.

  • domain_id: Optional domain ID filter
  • limit: Maximum results to return (default: 20, max: 1000)

list_vrfs(limit=20)

List VRF instances from phpIPAM.

  • limit: Maximum results to return (default: 20, max: 1000)

list_locations(limit=20)

List physical locations for network infrastructure.

  • limit: Maximum results to return (default: 20, max: 1000)

list_nameservers(limit=20)

List DNS nameservers with configuration details.

  • limit: Maximum results to return (default: 20, max: 1000)

search_subnets(query, limit=10)

Search subnets by CIDR, description, or other criteria.

  • query: Search term (CIDR, description, etc.)
  • limit: Maximum results to return (default: 10, max: 1000)

Write Operations

create_subnet(section_id, subnet, mask, *, description="", vlan_id=None)

Create a new subnet in phpIPAM.

  • section_id: Section ID where subnet will be created
  • subnet: Network address (e.g., "192.168.1.0")
  • mask: Subnet mask (e.g., "24")
  • description: Optional description for the subnet
  • vlan_id: Optional VLAN ID

reserve_ip_address(subnet_id, ip=None, hostname="", description="", owner="")

Reserve an IP address in a subnet.

  • subnet_id: Subnet ID where IP will be reserved
  • ip: Specific IP address to reserve (optional - will find first available)
  • hostname: Hostname for the IP address
  • description: Description for the IP address
  • owner: Owner of the IP address

update_ip_address(address_id, hostname=None, description=None, owner=None)

Update an existing IP address record.

  • address_id: ID of the IP address to update
  • hostname: New hostname (optional)
  • description: New description (optional)
  • owner: New owner (optional)

delete_ip_address(address_id)

Delete/release an IP address reservation.

  • address_id: ID of the IP address to delete

update_subnet(subnet_id, description=None, vlan_id=None, vrf_id=None)

Update an existing subnet.

  • subnet_id: ID of the subnet to update
  • description: New description (optional)
  • vlan_id: New VLAN ID (optional)
  • vrf_id: New VRF ID (optional)

delete_subnet(subnet_id)

Delete a subnet (WARNING: This will delete all IP addresses in the subnet).

  • subnet_id: ID of the subnet to delete

Configuration

phpIPAM Setup

  1. Create an API application in phpIPAM admin interface
  2. Set security to "SSL with App Code token"
  3. Note the App ID and App Code
  4. Set appropriate permissions for the application

Authentication

This server uses static app code token authentication:

  • No token expiration
  • Simple configuration
  • Secure over HTTPS

Development

Code Quality

# Run pylint
python -m pylint src/phpipam_mcp_server/

# Run tests (when available)
python -m pytest

# Format code
python -m black src/
python -m isort src/

Project Structure

src/phpipam_mcp_server/
├── __init__.py          # Package initialization
└── server.py            # Main MCP server implementation

API Documentation

See the docs/ directory for detailed API documentation:

  • api-overview.md - General API information
  • controllers.md - Available endpoints and data structures
  • examples.md - Request/response examples
  • mcp-design.md - MCP server design and architecture

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes with tests
  4. Run code quality checks
  5. Submit a pull request

Support

Metadata

Release files for phpipam-mcp-server 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phpipam-mcp-server 0.3.0
File Size Uploaded Provenance
phpipam_mcp_server-0.3.0.tar.gz 16.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for phpipam-mcp-server 0.3.0
File Interpreter ABI Platform
phpipam_mcp_server-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.7 kB

Release files / phpipam_mcp_server-0.3.0.tar.gz

Download URL phpipam_mcp_server-0.3.0.tar.gz
Size 16.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c1178575482b83181917afee8f33092a218366184e2d5b73e59e41367363ae87
BLAKE2b-256 checksum
How to use checksums
38435afc459481a7a04c031ec0cd839fbfb8bd0f28cc78beb32958b8ba801ec4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / phpipam_mcp_server-0.3.0-py3-none-any.whl

Download URL phpipam_mcp_server-0.3.0-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd8b7f85fa2d8127542aa3863cfd28ae855afb1f45113f79d22db707a45fc1d3
BLAKE2b-256 checksum
How to use checksums
c8ef0e4e8f5292153087bf37477305e3e4a32e0b32621346d66dadcd9f6adebf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Security for phpipam-mcp-server 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for phpipam_mcp_server-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page